<?xml version="1.0"?>
<doc>
    <assembly>
        <name>Ladaer.BackEnd</name>
    </assembly>
    <members>
        <member name="T:Ladaer.BackEnd.Controllers.Ads.AdsAccountController">
            <summary>
            Tài khoản quảng cáo đồng bộ từ nền tảng về.
            Không có endpoint tạo tay: tài khoản luôn kéo từ nền tảng để ExternalId chắc chắn đúng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsAccountController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách tài khoản quảng cáo</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsAccountController.GetById(System.Int32)">
            <summary>Chi tiết một tài khoản quảng cáo</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsAccountController.GetByConnection(System.Int32)">
            <summary>Danh sách tài khoản của một kết nối — dùng cho dropdown chọn tài khoản</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsAccountController.SyncFromPlatform(System.Int32)">
            <summary>Kéo danh sách tài khoản từ nền tảng về (upsert theo ExternalId)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsAccountController.ToggleActive(System.Int32)">
            <summary>Bật/tắt việc đưa tài khoản vào các job đồng bộ định kỳ</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Ads.AdsBulkBidController">
            <summary>
            Đổi giá thầu hàng loạt cho nhóm quảng cáo và từ khoá.
            <para>
            Cả hai endpoint đều đòi <c>Ads.Publish</c>, <b>kể cả</b> <c>preview</c>: bản xem trước gọi
            thật ra nền tảng bằng <c>validate_only</c> nên vẫn tốn quota và vẫn để lại dấu vết trên tài
            khoản quảng cáo. Quyền không gộp theo "đọc/ghi" mà theo "có chạm nền tảng hay không"
            (plan §1.2, bài học <c>set-bid-modifier</c>).
            </para>
            <para>
            Luồng bắt buộc ba bước: chọn dòng → <c>preview</c> (nền tảng chỉ kiểm tra, LADA không ghi
            gì) → gõ chữ xác nhận rồi <c>apply</c>. <c>apply</c> ghi lên nền tảng <b>trước</b>, thành
            công mới ghi giá mới vào LADA.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsBulkBidController.Preview(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel)">
            <summary>
            Xem trước lô đổi giá thầu: bảng cũ → mới từng dòng, dòng bỏ qua kèm lý do.
            Không ghi gì vào LADA, không sửa gì trên nền tảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsBulkBidController.Apply(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel)">
            <summary>
            Ghi thật lô đổi giá thầu lên nền tảng. Ghi nền tảng trước, thành công mới ghi vào LADA.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController">
            <summary>
            Chiến dịch quảng cáo: soạn nháp trong LADA và đẩy lên nền tảng.
            Quyền được tách theo mức rủi ro: <c>Ads.Search</c> để xem, <c>Ads.Create</c>/<c>Ads.Update</c>
            để soạn nháp, còn <c>Ads.Publish</c> cho mọi thao tác làm phát sinh chi phí thật trên nền tảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách chiến dịch</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.GetDetail(System.Guid,System.Nullable{System.DateOnly},System.Nullable{System.DateOnly})">
            <summary>
            Chi tiết chiến dịch kèm nhóm quảng cáo và số liệu tổng hợp.
            Không truyền khoảng ngày thì lấy 30 ngày gần nhất.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCampaignModel)">
            <summary>
            Lưu cả cây chiến dịch nháp (chiến dịch → nhóm → mẫu quảng cáo → targeting).
            Chỉ ghi vào LADA, không gọi ra nền tảng nên không phát sinh chi phí.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.Delete(System.Guid)">
            <summary>Xoá mềm chiến dịch trong LADA (chiến dịch đã lên nền tảng phải xoá bên đó trước)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.SyncCampaigns(System.Int32)">
            <summary>Kéo chiến dịch của một tài khoản từ nền tảng về</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.SyncAccount(System.Int32)">
            <summary>Kéo cả chiến dịch và nhóm quảng cáo của một tài khoản</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.SyncGroups(System.Guid,System.Int32)">
            <summary>Kéo nhóm quảng cáo của một chiến dịch</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.GetPublishPreview(System.Guid)">
            <summary>
            Thông tin cho hộp thoại xác nhận trước khi đẩy: tài khoản bị trừ tiền, ngân sách,
            thời gian chạy, ước tính chi phí tối đa, danh sách lỗi/cảnh báo.
            Chỉ đọc dữ liệu nên không cần quyền publish.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.Validate(System.Guid)">
            <summary>
            Kiểm tra trước khi đẩy (dry-run): nền tảng validate toàn bộ nhưng không tạo gì thật.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.Publish(System.Guid)">
            <summary>
            Đẩy chiến dịch lên nền tảng. Luôn tạo ở trạng thái tạm dừng — người dùng tự bật sau
            khi đã tự kiểm tra trên nền tảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.PushUpdate(System.Guid)">
            <summary>Đẩy thay đổi của chiến dịch nháp lên nền tảng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.Pause(System.Guid)">
            <summary>Tạm dừng chiến dịch trên nền tảng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.Resume(System.Guid)">
            <summary>Bật chạy chiến dịch trên nền tảng — từ đây quảng cáo bắt đầu tiêu tiền</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.BulkStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkStatusModel)">
            <summary>
            Bật / tạm dừng <b>nhiều</b> chiến dịch trong một lượt.
            <para>
            Gọi tuần tự đúng logic của bản lẻ (nguyên tắc §1.6 — không song song), trả kết quả từng
            dòng. Chiến dịch đã ở trạng thái đích hoặc chưa đẩy lên nền tảng thì bỏ qua, không tính
            là lỗi. Lô bị từ chối trước khi chạy (Id lạ, quá trần) là 400; lô đã chạy — kể cả có
            dòng thất bại — là 200 kèm bảng kết quả.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.ChangeGroupStatus(System.Guid,Lada.Framework.Data.Enums.AdsEntityStatus)">
            <summary>Đổi trạng thái một nhóm quảng cáo trên nền tảng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.ChangeAdStatus(System.Guid,Lada.Framework.Data.Enums.AdsEntityStatus)">
            <summary>Đổi trạng thái một quảng cáo trên nền tảng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCampaignController.ChangeBudget(System.Guid,Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBudgetChangeModel)">
            <summary>
            Đổi ngân sách theo ngày của chiến dịch đã có trên nền tảng.
            Đây là thao tác đổi trực tiếp số tiền tiêu mỗi ngày nên cần quyền publish.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Ads.AdsConnectionController">
            <summary>
            Cấu hình kết nối tới nền tảng quảng cáo (credentials, OAuth, kiểm tra kết nối).
            Toàn bộ endpoint đụng tới credential yêu cầu quyền <c>Ads.Connection</c> —
            đây là chỗ nắm chìa khoá tiêu tiền nên tách riêng khỏi quyền xem báo cáo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsConnectionController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách kết nối</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsConnectionController.GetById(System.Int32)">
            <summary>Chi tiết một kết nối (credential đã được che)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsConnectionController.GetCapabilities(System.Int32)">
            <summary>Năng lực của một nền tảng — UI render form credential động từ đây</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsConnectionController.GetAllCapabilities">
            <summary>Năng lực của mọi nền tảng đã khai báo adapter</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsConnectionController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsConnectionModel)">
            <summary>Tạo mới hoặc cập nhật kết nối</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsConnectionController.Delete(System.Int32)">
            <summary>Xoá mềm kết nối</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsConnectionController.GetAuthorizationUrl(System.Int32)">
            <summary>Lấy liên kết cấp quyền OAuth để người dùng bấm vào</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsConnectionController.OAuthCallback(System.String,System.String,System.String)">
            <summary>
            Callback OAuth do nền tảng gọi tới. Không yêu cầu đăng nhập vì trình duyệt
            được nền tảng chuyển hướng sang, không mang theo JWT — chống CSRF bằng tham số state đã ký.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsConnectionController.TestConnection(System.Int32)">
            <summary>Kiểm tra kết nối bằng một lệnh gọi nhẹ tới nền tảng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Ads.AdsCreativeController">
            <summary>
            Mẫu quảng cáo (creative) và cầu nối từ nội dung website sang quảng cáo.
            Toàn bộ endpoint ở đây chỉ ghi vào LADA — không có endpoint nào gọi ra nền tảng,
            nên không cần quyền <c>Ads.Publish</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCreativeController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách mẫu quảng cáo</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCreativeController.GetById(System.Guid)">
            <summary>Chi tiết một mẫu quảng cáo</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCreativeController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeModel)">
            <summary>Tạo mới hoặc cập nhật mẫu quảng cáo</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCreativeController.Delete(System.Guid)">
            <summary>Xoá mềm mẫu quảng cáo (mẫu đang được dùng thì không xoá được)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCreativeController.GetLimits(System.Int32)">
            <summary>
            Giới hạn mẫu quảng cáo của một nền tảng — form dùng để đếm ký tự realtime.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCreativeController.Validate(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeModel,Lada.Framework.Data.Enums.AdsPlatform)">
            <summary>
            Kiểm tra mẫu theo giới hạn nền tảng mà không cần lưu — dùng cho nút "Kiểm tra" trên form.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCreativeController.CreateFromMarketingContent(System.Guid,Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeFromContentModel)">
            <summary>
            Gợi ý mẫu quảng cáo từ một nội dung AI Marketing đã duyệt.
            <c>SaveAsCreative = false</c> thì chỉ trả gợi ý cho wizard, chưa lưu gì.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsCreativeController.CreateFromPost(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeFromContentModel)">
            <summary>
            Gợi ý mẫu quảng cáo từ một bài viết CMS đã xuất bản. URL bài viết thành Final URL.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Ads.AdsGroupController">
            <summary>
            Đọc nhóm quảng cáo và các quảng cáo bên trong nó.
            <para>
            Toàn bộ controller này <b>chỉ đọc</b>, nên mọi endpoint chỉ cần <c>Ads.Search</c>. Bật/tắt
            một quảng cáo hay một nhóm là thao tác tiêu tiền và đã có sẵn ở
            <c>api/ads/campaign/ad/{adId}/status</c> và <c>api/ads/campaign/group/{groupId}/status</c>
            (quyền <c>Ads.Publish</c>) — cố ý không làm lại ở đây để chỉ có một đường ghi trạng thái.
            </para>
            <para>
            Đồng bộ quảng cáo từ nền tảng về cũng chỉ đọc: nó ghi vào bảng của LADA, không thay đổi gì
            trên tài khoản quảng cáo thật.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsGroupController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách nhóm quảng cáo có phân trang, kèm số đếm quảng cáo / từ khoá.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsGroupController.GetDetail(System.Guid)">
            <summary>
            Chi tiết một nhóm: thông tin nhóm, bối cảnh chiến dịch / tài khoản, và năng lực nền tảng.
            <para>
            UI dùng các cờ năng lực để <b>ẩn hẳn</b> tab không dùng được, không hiện tab rỗng —
            tab rỗng đọc thành "chưa cấu hình gì", trong khi thật ra nền tảng không có khái niệm đó.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsGroupController.GetAds(System.Guid,System.Nullable{System.DateOnly},System.Nullable{System.DateOnly})">
            <summary>
            Danh sách quảng cáo trong nhóm kèm số liệu gộp trong khoảng ngày (mặc định 30 ngày gần nhất).
            <para>
            Quảng cáo có <c>IsManagedByLada = false</c> là quảng cáo đồng bộ về từ nền tảng — LADA
            không quản mẫu của nó nên chỉ đọc được, đó không phải bản ghi lỗi.
            </para>
            <para>
            <c>Metrics = null</c> nghĩa là <b>chưa đồng bộ số liệu cấp quảng cáo</b>, khác hẳn với
            "đã đồng bộ và mọi số bằng 0" — UI phải hiển thị hai trạng thái này khác nhau.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsGroupController.GetSummary(System.Guid,System.Nullable{System.DateOnly},System.Nullable{System.DateOnly})">
            <summary>Số liệu tổng hợp của nhóm trong khoảng ngày (mặc định 30 ngày gần nhất).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsGroupController.SyncAds(System.Guid)">
            <summary>
            Kéo quảng cáo của cả chiến dịch chứa nhóm này từ nền tảng về LADA.
            <b>Chỉ đọc</b> — không thay đổi gì trên tài khoản quảng cáo, nên quyền chỉ cần
            <c>Ads.Search</c>.
            <para>
            Đồng bộ theo <b>chiến dịch</b> chứ không theo từng nhóm: nền tảng trả quảng cáo của cả
            chiến dịch trong một lượt gọi, tách ra từng nhóm chỉ tốn quota gấp số nhóm lần mà không
            thu thêm thông tin nào.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Ads.AdsIssueController">
            <summary>
            "Việc cần xử lý" của phân hệ quảng cáo — panel gộp theo loại trên trang Chiến dịch (plan §3.4).
            <para>
            Quyền: <c>Ads.Search</c> để xem; <c>Ads.Update</c> để bỏ qua (<c>dismiss</c>) / hiện lại (<c>undismiss</c>) — bỏ qua chỉ ghi
            <c>AdsIssueDismissal</c>, không chạm dữ liệu đồng bộ. Hành động chính của từng loại (kéo lịch về,
            đồng bộ tài khoản, đồng bộ số liệu) nằm ở controller của nghiệp vụ đó với đúng bó quyền của nó.
            </para>
            <para>
            Lỗi ngoài dự kiến trả thông điệp trung tính, chi tiết vào log — không lặp nếp
            <c>BadRequest(ex.Message)</c> (sổ nợ N-22).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsIssueController.List(System.Nullable{Lada.Framework.Data.Enums.AdsPlatform},System.Nullable{System.Int32})">
            <summary>
            Danh sách việc đã gộp theo loại, mỗi loại kèm số đếm đã trừ bỏ qua và tối đa 200 mục chi tiết.
            Bỏ trống bộ lọc = toàn hệ thống.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsIssueController.Dismiss(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsIssueDismissModel)">
            <summary>
            Bỏ qua một lô mục cùng loại trong N ngày (mặc định 30). Có Id không tồn tại hoặc không còn
            thuộc loại đó là <b>400 cả lô</b>, không âm thầm bỏ phần lạ. Tối đa 500 Id.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsIssueController.Undismiss(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsIssueUndismissModel)">
            <summary>
            Hiện lại các mục đã bỏ qua của một loại. Bỏ trống <c>EntityIds</c> = hiện lại tất cả.
            POST chứ không DELETE-có-thân: thân của DELETE bị một số proxy/WAF bỏ, và repo chưa có tiền lệ nào
            chạy thật qua production với kiểu đó.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Ads.AdsKeywordController">
            <summary>
            Từ khoá và từ khoá phủ định của chiến dịch / nhóm quảng cáo.
            <para>
            Sửa từ khoá là <b>đổi cấu hình đang tiêu tiền</b>, nên luồng ghi chia ba bước tách biệt
            giống lịch chạy: (1) sửa nháp trong LADA (<c>create-or-update</c>, <c>create-bulk</c>,
            <c>DELETE</c>) — không gọi ra nền tảng, không tốn đồng nào; (2) xem trước
            (<c>preview-apply</c>) — nền tảng kiểm tra cả lô bằng <c>validate_only</c>, không ghi gì;
            (3) đẩy thật (<c>apply</c>) — ghi lên nền tảng rồi đọc lại để xác nhận.
            </para>
            <para>
            Quyền: <c>Ads.Search</c> để xem và để đồng bộ về (chỉ đọc); <c>Ads.Update</c> /
            <c>Ads.Delete</c> cho việc sửa nháp trong LADA; <c>Ads.Publish</c> cho mọi thứ gọi ra nền
            tảng — kể cả <c>preview-apply</c>, vì nó tốn quota API thật.
            </para>
            <para>
            <b>Xoá từ khoá phủ định là thao tác nguy hiểm nhất ở đây</b>: nó mở cửa cho truy vấn rác
            tiêu tiền ngay khi được đẩy lên, mà không có gì báo. UI phải bắt gõ từ khoá xác nhận trước
            khi gọi <c>apply</c> nếu lô có dòng xoá phủ định — số dòng đó nằm ở
            <c>NegativeRemoveCount</c> trong kết quả <c>preview-apply</c>.
            </para>
            <para>
            Danh sách phủ định rỗng nghĩa là <b>không loại trừ truy vấn nào</b>, không phải "chưa cấu
            hình". Ngoài ra LADA chưa đọc danh sách phủ định dùng chung (shared set) của nền tảng —
            xem <c>SharedSetNote</c> trong kết quả đọc.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsKeywordController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Danh sách từ khoá có phân trang, lọc theo chiến dịch / nhóm / nền tảng / kiểu khớp.
            <para>
            Không gửi <c>isNegative</c> = lấy cả hai loại. Gửi <c>true</c>/<c>false</c> mới lọc.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsKeywordController.GetContext(System.Guid,System.Nullable{System.Guid})">
            <summary>
            Bối cảnh của một phạm vi từ khoá — <b>không kèm danh sách</b>: năng lực nền tảng, trạng
            thái publish, có thay đổi chưa đẩy hay không, và số lượng từng loại.
            <para>
            Đây là thứ màn hình danh sách gọi, cặp với <c>search</c> phân trang. Bỏ trống
            <c>groupId</c> = phạm vi cấp chiến dịch (phủ định cấp chiến dịch).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsKeywordController.GetByCampaign(System.Guid)">
            <summary>
            Từ khoá của một chiến dịch: từ khoá phủ định cấp chiến dịch cùng từ khoá của mọi nhóm,
            kèm bối cảnh hiển thị (nền tảng có khái niệm từ khoá không, có dry-run không, giới hạn
            số từ khoá mỗi nhóm).
            <para>
            <b>Không phân trang</b> — trả về mọi dòng của chiến dịch. Màn hình danh sách phải dùng
            <c>search</c> + <c>context</c> thay cho endpoint này.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsKeywordController.GetByGroup(System.Guid)">
            <summary>
            Từ khoá của riêng một nhóm quảng cáo.
            <para>
            Từ khoá phủ định cấp chiến dịch <b>cố ý không</b> trộn vào đây: trộn vào thì người dùng
            tưởng xoá ở đây là hết ảnh hưởng, trong khi nó áp cho mọi nhóm khác của chiến dịch.
            </para>
            <para>
            <b>Không phân trang</b> — xem ghi chú ở <c>by-campaign</c>.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsKeywordController.Sync(System.Guid)">
            <summary>
            Kéo từ khoá từ nền tảng về LADA. <b>Chỉ đọc</b> — dữ liệu trên tài khoản quảng cáo thật
            không bị thay đổi, nên quyền chỉ cần <c>Ads.Search</c>.
            <para>
            Từ khoá thuộc nhóm chưa đồng bộ về LADA bị bỏ qua và <b>đếm riêng</b>
            (<c>SkippedCount</c>) — nếu số đó khác 0 thì danh sách đang xem CHƯA đủ.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsKeywordController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordModel)">
            <summary>
            Thêm / sửa một từ khoá trong LADA (bản nháp). <b>Không</b> gọi ra nền tảng, không phát
            sinh chi phí — thay đổi chỉ có hiệu lực sau khi đẩy lên.
            <para>
            Bỏ trống <c>AdsGroupId</c> = từ khoá phủ định cấp chiến dịch. Bỏ trống mà
            <c>IsNegative = false</c> sẽ bị từ chối chứ không tự đổi cấp.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsKeywordController.CreateBulk(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordBulkModel)">
            <summary>
            Thêm nhiều từ khoá một lượt bằng danh sách dán vào — mỗi dòng một từ khoá.
            <b>Không</b> gọi ra nền tảng.
            <para>
            Cả lô cùng vào hoặc cùng đứng: có lỗi thì không thêm dòng nào, để không để lại danh
            sách nửa vời. Dòng trắng, dòng trùng trong lô và dòng đã có sẵn được báo rõ số lượng
            trong thông báo, không âm thầm bỏ.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsKeywordController.Delete(System.Guid)">
            <summary>
            Xoá một từ khoá trong LADA (soft-delete). <b>Không</b> gọi ra nền tảng.
            <para>
            Từ khoá đã có trên nền tảng <b>vẫn đang chạy</b> tới khi người dùng đẩy lên — với từ
            khoá phủ định thì nghĩa là truy vấn vẫn đang bị loại trừ. Thông báo trả về nói rõ điều
            này; UI phải hiện nguyên văn, đừng rút gọn thành "đã xoá".
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsKeywordController.PreviewApply(System.Guid,System.Nullable{System.Guid})">
            <summary>
            Xem trước những gì sẽ ghi lên nền tảng: so từ khoá trong LADA với từ khoá trên nền tảng
            rồi nhờ nền tảng kiểm tra cả lô bằng <c>validate_only</c>. <b>Không ghi gì</b> lên tài
            khoản quảng cáo.
            <para>
            Bỏ trống <c>groupId</c> = lô từ khoá phủ định cấp chiến dịch. Một lần gọi chỉ xử lý
            <b>một phạm vi</b> — nhóm hoặc cấp chiến dịch, không trộn.
            </para>
            <para>
            Quyền <c>Ads.Publish</c> vì nó gọi ra nền tảng thật (tốn quota API). Nền tảng không có
            dry-run thì endpoint này <b>báo lỗi</b>, tuyệt đối không âm thầm ghi thật.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsKeywordController.Apply(System.Guid,System.Nullable{System.Guid})">
            <summary>
            Đẩy từ khoá lên nền tảng thật. <b>Việc này tiêu tiền</b>: từ khoá mới bắt đầu chạy ngay,
            và từ khoá phủ định bị xoá thì truy vấn tương ứng lập tức tiêu tiền trở lại.
            <para>
            UI phải hiện hộp xác nhận nêu rõ từng thay đổi trước khi gọi endpoint này, và bắt gõ từ
            khoá xác nhận khi lô có dòng xoá phủ định (<c>NegativeRemoveCount &gt; 0</c> ở bước xem
            trước).
            </para>
            <para>
            Sau khi ghi, service đọc lại từ khoá từ nền tảng và trả về danh sách <b>đã đọc lại</b> —
            UI hiển thị danh sách đó, không hiển thị thứ vừa gửi lên.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Ads.AdsNavController">
            <summary>
            Cờ hiển thị cho giao diện của phân hệ Quảng cáo — "tôi được thấy nút nào".
            </summary>
            <remarks>
            Endpoint này <b>cố ý không đòi role nào</b> (chỉ cần đăng nhập): người không có quyền gì
            vẫn phải hỏi được và nhận về toàn <c>false</c> để giao diện ẩn nút. Gác nó bằng một role là
            dựng lại đúng lỗi nó sinh ra để chữa (rule <c>quyen-hien-thi</c> mục 4). Luật nằm ở hàm thuần
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsNavPermissions"/>, controller chỉ hỏi role rồi chuyển tiếp.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsNavController.GetNavPermissions">
            <summary>Cờ hiển thị nút của phân hệ quảng cáo cho người đang đăng nhập</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Ads.AdsReportController">
            <summary>
            Số liệu quảng cáo và log gọi nền tảng.
            Chi phí luôn kèm mã tiền tệ của tài khoản — frontend hiển thị theo mã đó, không quy đổi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsReportController.SyncMetrics(System.Int32,System.DateOnly,System.DateOnly,Lada.Framework.Data.Enums.AdsMetricLevel)">
            <summary>Kéo số liệu theo ngày của một tài khoản trong khoảng ngày</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsReportController.GetSummary(Lada.Framework.Data.Enums.AdsMetricLevel,System.Guid,System.DateOnly,System.DateOnly)">
            <summary>Số liệu tổng hợp của một chiến dịch / nhóm / quảng cáo</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsReportController.GetAccountSummary(System.Int32,System.DateOnly,System.DateOnly)">
            <summary>Số liệu tổng hợp của cả một tài khoản quảng cáo</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsReportController.SearchSyncLogs(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Log gọi nền tảng — màn hình debug của module</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsReportController.GetOverview(System.DateOnly,System.DateOnly,System.Nullable{Lada.Framework.Data.Enums.AdsPlatform},System.Nullable{System.Int32})">
            <summary>
            Số liệu tổng quan toàn hệ thống kèm kỳ liền trước để so sánh tăng/giảm.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsReportController.GetMetricsStatus(System.Nullable{Lada.Framework.Data.Enums.AdsPlatform},System.Nullable{System.Int32})">
            <summary>
            Số liệu đã về tới ngày nào và đồng bộ lần cuối lúc nào — thanh ngữ cảnh của phân hệ
            hiện "Số liệu đến …" và tô cảnh báo khi số đã cũ. Không nhận khoảng ngày.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsReportController.GetTimeSeries(System.DateOnly,System.DateOnly,System.Nullable{Lada.Framework.Data.Enums.AdsPlatform},System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricGroupBy)">
            <summary>
            Chuỗi số liệu theo thời gian để vẽ biểu đồ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsReportController.GetByPlatform(System.DateOnly,System.DateOnly,System.Nullable{Lada.Framework.Data.Enums.AdsPlatform},System.Nullable{System.Int32})">
            <summary>
            Số liệu gộp theo từng nền tảng quảng cáo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsReportController.GetTopCampaigns(System.DateOnly,System.DateOnly,System.Nullable{Lada.Framework.Data.Enums.AdsPlatform},System.Nullable{System.Int32},System.String,System.Int32)">
            <summary>
            Xếp hạng chiến dịch theo chi phí (mặc định) hoặc chỉ số khác.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsReportController.SyncNow(System.Nullable{System.DateOnly},System.Nullable{System.DateOnly})">
            <summary>
            Đồng bộ số liệu ngay cho mọi tài khoản đang bật đồng bộ định kỳ.
            Yêu cầu quyền <c>Ads.Publish</c> vì có gọi ra nền tảng bên ngoài.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsReportController.BuildFilter(System.DateOnly,System.DateOnly,System.Nullable{Lada.Framework.Data.Enums.AdsPlatform},System.Nullable{System.Int32})">
            <summary>
            Dựng bộ lọc chung và chặn khoảng ngày không hợp lệ ngay tại cửa ngõ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Ads.AdsScheduleController">
            <summary>
            Lịch chạy quảng cáo (ad schedule) của chiến dịch.
            <para>
            Luồng sửa lịch chia làm ba bước tách biệt vì sửa lịch là đổi giá thầu — tiêu tiền thật:
            (1) sửa bản nháp trong LADA (<c>create-or-update</c>, <c>DELETE</c>, <c>set-bid-modifier</c>)
            — không gọi ra nền tảng; (2) xem trước (<c>preview-apply</c>) — nền tảng kiểm tra bằng
            <c>validate_only</c>, không ghi gì; (3) đẩy thật (<c>apply</c>).
            </para>
            <para>
            Quyền: <c>Ads.Search</c> để xem; <c>Ads.Update</c> / <c>Ads.Delete</c> cho việc sửa nháp
            trong LADA; <c>Ads.Publish</c> cho mọi thứ liên quan tới tiền và tới nền tảng — bao gồm cả
            <c>set-bid-modifier</c> (đổi giá thầu là chuyện tiền) và <c>preview-apply</c> (gọi ra nền tảng thật).
            </para>
            <para>
            Danh sách khung giờ rỗng nghĩa là chiến dịch chạy cả tuần 24/7, không phải "không chạy".
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsScheduleController.GetByCampaign(System.Guid)">
            <summary>
            Lịch của một chiến dịch kèm bối cảnh hiển thị (múi giờ tài khoản, đã publish chưa,
            nền tảng có cho sửa lịch không, chiến lược đặt giá có áp dụng % giá thầu không).
            <para>
            Danh sách rỗng nghĩa là chiến dịch chạy cả tuần 24/7, không phải "không chạy".
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsScheduleController.Sync(System.Guid)">
            <summary>
            Kéo lịch từ nền tảng về LADA. Chỉ đọc từ nền tảng — dữ liệu trên tài khoản
            quảng cáo thật không bị thay đổi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsScheduleController.SyncMany(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleBulkSyncModel)">
            <summary>
            Kéo lịch từ nền tảng về cho <b>nhiều</b> chiến dịch — chỉ đọc, không đổi gì trên tài khoản quảng
            cáo; xong mỗi chiến dịch thì dò lệch lại để cờ "lệch với nền tảng" tắt. Tuần tự, một chiến dịch
            lỗi không giết lô, kết quả từng dòng. Tối đa 500 Id; có Id không tồn tại là 400 cả lô (plan §3.9).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsScheduleController.Reconcile(System.Guid)">
            <summary>
            Dò lệch lịch của <b>một</b> chiến dịch ngay lập tức, không chờ job chạy đêm.
            <para>
            Chỉ đọc từ nền tảng rồi đánh dấu nếu lệch — không sửa lịch ở bất kỳ phía nào.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsScheduleController.ReconcileAll">
            <summary>
            Chạy tay lượt dò lệch lịch trên <b>toàn bộ</b> chiến dịch đã đẩy lên nền tảng —
            đúng việc mà job <c>ads-schedule-reconcile</c> làm mỗi đêm.
            <para>
            Gọi ra nền tảng một lần cho mỗi chiến dịch nên tốn quota API. Chỉ dùng khi cần kiểm
            tra ngay, còn lại để job tự chạy. Quyền <c>Ads.Publish</c> vì đây là thao tác nặng,
            dù nó không ghi gì lên nền tảng.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsScheduleController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleModel)">
            <summary>
            Tạo / sửa một khung giờ trong LADA (bản nháp). <b>Không</b> gọi ra nền tảng, không
            phát sinh chi phí — thay đổi chỉ có hiệu lực sau khi bấm đẩy lên.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsScheduleController.Delete(System.Guid)">
            <summary>
            Xoá một khung giờ trong LADA (soft-delete). <b>Không</b> gọi ra nền tảng: khung giờ
            đã có trên nền tảng vẫn còn chạy tới khi người dùng đẩy lịch lên.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsScheduleController.SetBidModifier(System.Guid,System.Nullable{System.Decimal})">
            <summary>
            Đặt / xoá % điều chỉnh giá thầu của một khung giờ trong LADA.
            <para>
            Quyền <c>Ads.Publish</c> dù chỉ ghi vào DB LADA: đổi giá thầu là chuyện tiền, không
            nên để quyền sửa dữ liệu thường mở được cánh cửa này.
            </para>
            </summary>
            <param name="bidModifier">
            Hệ số theo dạng nền tảng (1.2 = +20%, 0.5 = -50%). Bỏ trống / null = xoá điều chỉnh,
            khác hẳn 0. Frontend chịu trách nhiệm đổi từ "+20" mà người dùng gõ sang 1.2.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsScheduleController.PreviewApply(System.Guid)">
            <summary>
            Xem trước những gì sẽ ghi lên nền tảng: so lịch LADA với lịch nền tảng rồi nhờ nền tảng
            kiểm tra cả lô bằng <c>validate_only</c>. <b>Không ghi gì</b> lên tài khoản quảng cáo.
            <para>
            Quyền <c>Ads.Publish</c> vì nó gọi ra nền tảng thật (tốn quota API).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsScheduleController.Apply(System.Guid)">
            <summary>
            Đẩy lịch lên nền tảng thật. <b>Việc này tiêu tiền</b>: giá thầu theo khung giờ đổi ngay
            sau khi ghi. UI phải hiện hộp xác nhận nêu rõ từng thay đổi trước khi gọi endpoint này.
            <para>
            Sau khi ghi, service đọc lại lịch từ nền tảng và trả về danh sách <b>đã đọc lại</b> —
            UI hiển thị danh sách đó, không hiển thị thứ vừa gửi lên.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsScheduleController.GetTemplates">
            <summary>
            Danh sách mẫu lịch áp nhanh (giờ hành chính, cuối tuần, 24/7…) kèm giới hạn số chiến dịch
            một lô.
            <para>
            Định nghĩa mẫu nằm ở backend nên thêm/sửa mẫu không phải build lại frontend. Giới hạn lô
            trả kèm ở đây thay vì để frontend tự ghi hằng số — hai bản số lệch nhau thì UI sẽ cho chọn
            nhiều hơn mức backend nhận, người dùng chọn xong mới biết là quá.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsScheduleController.ApplyTemplate(System.Guid,System.String,System.Nullable{System.Decimal})">
            <summary>
            Áp một mẫu lịch cho một chiến dịch — <b>chỉ ghi nháp trong LADA</b>, không gọi ra nền tảng.
            <para>
            <b>Thay toàn bộ lịch hiện tại.</b> Quyền <c>Ads.Publish</c> (không phải <c>Ads.Update</c>)
            vì mẫu mang theo % giá thầu — cùng lý do với <c>set-bid-modifier</c>: đổi giá thầu là
            chuyện tiền.
            </para>
            </summary>
            <param name="bidModifier">
            % chung theo dạng hệ số Google (1.2 = +20%). Bỏ trống để dùng % của mẫu.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ads.AdsScheduleController.ApplyTemplateToMany(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleBulkTemplateModel)">
            <summary>
            Áp một mẫu lịch cho <b>nhiều</b> chiến dịch một lượt.
            <para>
            Một chiến dịch lỗi không làm chết cả lô — kết quả trả về nói rõ từng chiến dịch
            thành công / thất bại / bỏ qua kèm lý do. Chiến dịch chưa publish và tài khoản MCC
            được tính là <b>bỏ qua</b>, không phải thất bại.
            </para>
            <para>
            Luồng nên dùng trên UI: gọi với <c>validateOnly = true</c> để dry-run cả lô, người dùng
            đọc bảng kết quả, rồi mới gọi lại với <c>validateOnly = false</c>. Áp sai lịch cho hàng
            chục chiến dịch cùng lúc là sự cố tốn tiền.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Analytics.AnalyticsController">
            <summary>REST quản trị của miền MCP số liệu (docs/plan-mcp-tra-cuu-so-lieu.md) — tool số liệu nằm ở endpoint MCP /analytics, không ở đây.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Analytics.AnalyticsController.DeployCheck(System.Threading.CancellationToken)">
            <summary>
            Ảnh chụp trạng thái triển khai MCP số liệu: phiên bản schema, cấu hình (cờ, không khoá), login chỉ đọc (đọc được analytics,
            bị lỗi 229 ở dbo), số dòng bảng analytics, lượt nạp từng chủ đề + mốc phủ, role Analytics.Read, client OAuth, số đo Việc 0.
            </summary>
            <remarks>
            Gác <c>Founder</c> như <c>api/ContentStore/DeployCheck</c> — thay cho mọi câu SQL tay trên production (ràng buộc 2026-08-27).
            Chỉ đọc, không tham số. Luật nằm ở <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsDeployCheckService"/>; controller trả thẳng kết quả.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Cms.CategoryController">
            <summary>
            Controller xử lý các hoạt động liên quan đến danh mục.  
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.CategoryController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Cms.ICategoryService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Cms.CategoryController"/>.
            </summary>
            <param name="categoryService">Dịch vụ xử lý danh mục.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.CategoryController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các danh mục dựa trên các tham số được cung cấp.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.CategoryController.GetTree(System.String,Lada.Framework.Data.Enums.ContentType)">
            <summary>
            Lấy danh sách danh mục dưới dạng cây.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <returns>Danh sách danh mục dưới dạng cây.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.CategoryController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.CategoryModel)">
            <summary>
            Tạo hoặc cập nhật thông tin danh mục.
            </summary>
            <param name="categoryModel">Model chứa thông tin danh mục.</param>
            <returns>Kết quả của hoạt động tạo hoặc cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.CategoryController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của một danh mục dựa trên ID.
            </summary>
            <param name="id">ID của danh mục.</param>
            <returns>Thông tin chi tiết của danh mục.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.CategoryController.Delete(System.Int32)">
            <summary>
            Xóa một danh mục dựa trên ID.
            </summary>
            <param name="id">ID của danh mục.</param>
            <returns>Kết quả của hoạt động xóa.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Cms.GoodsCategoryConfigController">
            <summary>
            Controller cấu hình tính giá cho danh mục hàng hóa động
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.GoodsCategoryConfigController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm cấu hình danh mục hàng hóa
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.GoodsCategoryConfigController.GetById(System.Int32)">
            <summary>
            Lấy cấu hình theo Id (kèm thuộc tính và lựa chọn)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.GoodsCategoryConfigController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryConfigModel)">
            <summary>
            Tạo mới hoặc cập nhật cấu hình (kèm thuộc tính và lựa chọn)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.GoodsCategoryConfigController.Delete(System.Int32)">
            <summary>
            Xóa cấu hình (xóa mềm kèm thuộc tính và lựa chọn)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.GoodsCategoryConfigController.GetByCategoryId(System.Int32)">
            <summary>
            Lấy cấu hình theo danh mục hàng hóa (nhân viên lên đơn cần đọc)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.GoodsCategoryConfigController.GetAllActive">
            <summary>
            Lấy toàn bộ cấu hình đang bật
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Cms.PostController">
            <summary>
            Controller xử lý các hoạt động liên quan đến bài viết.  
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.PostController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Cms.IPostService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Cms.PostController"/>.
            </summary>
            <param name="postService">Dịch vụ xử lý bài viết.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.PostController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các bài viết dựa trên các tham số được cung cấp.  
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.PostController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostModel)">
            <summary>
            Tạo hoặc cập nhật bài viết.  
            </summary>
            <param name="postModel">Model chứa thông tin bài viết.</param>
            <returns>Kết quả của hoạt động tạo hoặc cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.PostController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của bài viết dựa trên ID.  
            </summary>
            <param name="id">ID của bài viết.</param>
            <returns>Thông tin chi tiết của bài viết.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.PostController.AgencyOptions">
            <summary>
            Nguồn cho ô "Bưu cục liên quan" của form Bài viết: chi nhánh LADA/nhượng quyền chưa xoá, kèm tên hiển thị và trạng
            thái công bố của hồ sơ bưu cục nếu có.
            </summary>
            <remarks>
            Gác đúng bó role của form Bài viết (<c>Post.GetById</c> để mở form sửa, <c>Post.CreateOrUpdate</c> để lưu) chứ không
            mượn nguồn bưu cục sẵn có: <c>AgencyProfile/Lookups</c> đòi <c>AgencyProfile.*</c>, <c>Agency/GetTree</c> đòi
            <c>Agency.GetTree</c> — người viết bài không có các role đó, ô chọn sẽ 403 và interceptor đá cả trang (rule
            quyen-hien-thi). Tập dòng trùng đúng tập mà bước lưu bài chấp nhận.
            </remarks>
            <returns>Danh sách <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.PostAgencyOption"/> sắp theo tên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.PostController.Delete(System.Int32)">
            <summary>
            Xóa một bài viết dựa trên ID.  
            </summary>
            <param name="id">ID của bài viết.</param>
            <returns>Kết quả của hoạt động xóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.PostController.Publish(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostStatusModel)">
            <summary>
            Đăng bài viết.  
            </summary>
            <param name="model">Model chứa thông tin trạng thái bài viết.</param>
            <returns>Kết quả của hoạt động đăng bài viết.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.PostController.Reject(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostStatusModel)">
            <summary>
            Từ chối bài viết.  
            </summary>
            <param name="model">Model chứa thông tin trạng thái bài viết.</param>
            <returns>Kết quả của hoạt động từ chối bài viết.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.PostController.SendToPublish(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostStatusModel)">
            <summary>
            Gửi bài viết chờ duyệt.  
            </summary>  
            <param name="model">Model chứa thông tin trạng thái bài viết.</param>
            <returns>Kết quả của hoạt động gửi bài viết chờ duyệt.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.ProductController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Cms.IProductService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Cms.ProductController"/>.
            </summary>
            <param name="ProductService">Dịch vụ xử lý sản phẩm.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.ProductController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các sản phẩm dựa trên các tham số được cung cấp.  
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.ProductController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của sản phẩm dựa trên ID.  
            </summary>
            <param name="id">ID của sản phẩm.</param>
            <returns>Thông tin chi tiết của sản phẩm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.ProductController.BlockProfile">
            <summary>
            Bộ khối của trang dịch vụ — editor FE lấy loại khối được thêm và bộ icon cố định từ đây (không chép danh
            sách). Quyền như mở form dịch vụ.
            </summary>
            <returns><see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.BlockProfileItem"/>.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.ProductController.RouteCityOptions(System.String)">
            <summary>
            Nguồn cho hai ô "Tỉnh đi / Tỉnh đến" của form Dịch vụ: tỉnh bộ 2 cấp + gợi ý đoán từ tên trang.
            </summary>
            <remarks>
            Gác đúng bó role của form Dịch vụ (<c>Product.GetById</c> để mở form sửa, <c>Product.CreateOrUpdate</c> để lưu)
            chứ không mượn nguồn tỉnh sẵn có: <c>LoSug</c> đòi <c>Location.LocationSuggestion</c>, <c>AgencyProfile/Lookups</c>
            đòi <c>AgencyProfile.*</c> — người soạn trang dịch vụ không có các role đó, ô chọn sẽ 403 và interceptor đá cả
            trang (rule quyen-hien-thi). Ai mở được form thì nạp được ô chọn, không hơn.
            </remarks>
            <param name="name">Tên trang đang soạn; rỗng thì chỉ trả danh sách tỉnh, không đoán.</param>
            <returns><see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductRouteCityOptions"/>.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.ProductController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel)">
            <summary>
            Tạo hoặc cập nhật sản phẩm.
            </summary>
            <param name="ProductModel">Model chứa thông tin sản phẩm.</param>
            <returns>Kết quả của hoạt động tạo hoặc cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.ProductController.Delete(System.Int32)">
            <summary>
            Xóa một sản phẩm dựa trên ID.  
            </summary>
            <param name="id">ID của sản phẩm.</param>
            <returns>Kết quả của hoạt động xóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.ScriptConfigController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm cấu hình script
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.ScriptConfigController.GetById(System.Int32)">
            <summary>
            Lấy thông tin cấu hình script theo Id
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.ScriptConfigController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ScriptConfigModel)">
            <summary>
            Thêm hoặc cập nhật cấu hình script
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.ScriptConfigController.Delete(System.Int32)">
            <summary>
            Xóa cấu hình script
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.TagController.Autocomplete(System.String)">
            <summary>
            Tự động hoàn thành từ khóa tìm kiếm thẻ.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <returns>Danh sách các thẻ gợi ý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.TagController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các thẻ dựa trên tham số SmartTableParam.
            </summary>
            <param name="param">Tham số tìm kiếm.</param>
            <returns>Danh sách các thẻ phù hợp.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Cms.TopicController">
            <remarks>
            Topic là nội dung một mục Cổng nhượng quyền (<c>FranchisePortal.&lt;Code&gt;</c>, hoặc đang được một mục trỏ tới)
            KHÔNG đi qua controller này với bất kỳ ai, kể cả Founder và người có role cổng: <c>Search</c> không liệt kê, đọc /
            lưu / xuất bản / xem trước trả như topic không tồn tại, xoá bị từ chối — cửa nằm trong <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Cms.ITopicService"/>.
            Nội dung cổng sửa ở <c>FranchisePortalSectionController</c> (role <c>FranchisePortal.Content</c> / <c>Manage</c>,
            đóng nợ CNQ-12 ở GĐ E).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.TopicController.NavPermissions">
            <summary>
            Cờ hiển thị của màn sửa topic: <c>CanSave</c> (nút "Lưu lại"), <c>CanUploadPicture</c> (nút tải ảnh của khối),
            <c>CanPublish</c> (nút "Xuất bản"), <c>CanPreview</c> (nút "Xem trước"); và của danh sách topic: <c>CanCreate</c>
            (nút "Tạo topic"), <c>CanDelete</c> (mục "Xóa").
            KHÔNG đòi role (rule quyen-hien-thi) — người không có quyền nhận cờ false.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.TopicController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các chủ đề dựa trên các tham số được cung cấp.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.TopicController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của chủ đề dựa trên ID.
            </summary>
            <param name="id">ID của chủ đề.</param>
            <returns>Thông tin chi tiết của chủ đề.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.TopicController.IdBySystemName(System.String)">
            <summary>
            Id của topic theo tên hệ thống — menu tắt "Nội dung trang nhượng quyền" mở thẳng topic <c>FranchiseLanding</c>
            mà không ghi cứng Id (khác nhau giữa các DB). Không có → 0. Quyền như đọc topic.
            </summary>
            <param name="systemName">Tên hệ thống, vd. <c>FranchiseLanding</c>.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.TopicController.BlockProfile(System.String)">
            <summary>
            Bộ khối của topic theo tên hệ thống — editor FE biết có hiện tab "Khối nội dung" không, được thêm loại khối
            nào, luật số lượng và bộ icon cố định (FE không chép danh sách). Không có bộ khối → <c>Enabled = false</c>.
            Quyền như đọc topic.
            </summary>
            <param name="systemName">Tên hệ thống của topic, vd. <c>FranchiseLanding</c>.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.TopicController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel)">
            <summary>
            Tạo hoặc cập nhật chủ đề.
            </summary>
            <param name="TopicModel">Model chứa thông tin chủ đề.</param>
            <returns>Kết quả của hoạt động tạo hoặc cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.TopicController.PublishBlocks(System.Int32,System.String)">
            <summary>
            Xuất bản khối nội dung đang sửa của topic: kiểm lại toàn bộ rồi chụp thành bản website in ra. Lưu topic
            (<c>CreateOrUpdate</c>) không đổi trang công khai — chỉ thao tác này mới đổi (plan nhượng quyền website §6.3).
            </summary>
            <param name="id">Id của topic.</param>
            <param name="version">
            Dấu <c>DraftVersion</c> của bản đang sửa người bấm đã thấy (từ <c>GetById</c>) — bắt buộc. Có người lưu khối
            sau đó thì không xuất bản (<c>DraftChanged = true</c>).
            </param>
            <returns><c>TopicPublishResult</c>; <c>Failed</c> kèm câu lỗi khi bản đang sửa chưa đạt luật xuất bản.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.TopicController.PreviewToken(System.Int32)">
            <summary>
            Cấp link xem trước bản ĐANG SỬA của topic trên website (hạn 30 phút; link cấp trước vẫn sống). Role như đọc topic: link
            chỉ cho xem đúng bản đang sửa mà người gọi đã đọc được qua <c>GetById</c>, để gửi người duyệt/chủ trang xem
            mà không cần tài khoản (plan nhượng quyền website §6.3).
            </summary>
            <param name="id">Id của topic.</param>
            <returns><c>TopicPreviewResult</c> — <c>Path</c> trên website kèm token, <c>ExpiresAt</c>.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.TopicController.Delete(System.Int32)">
            <summary>
            Xóa một chủ đề dựa trên ID.
            </summary>
            <param name="id">ID của chủ đề.</param>
            <returns>Kết quả của hoạt động xóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.UrlRecordController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của UrlRecord dựa trên ID.
            </summary>
            <param name="id">ID của UrlRecord.</param>
            <returns>Thông tin chi tiết của UrlRecord.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.UrlRecordController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các UrlRecord dựa trên tham số SmartTableParam.
            </summary>
            <param name="param">Tham số tìm kiếm.</param>
            <returns>Danh sách các UrlRecord phù hợp.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.UrlRecordController.UpdateInfo(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordUpdateModel)">
            <summary>
            Cập nhật thông tin cơ bản của UrlRecord.
            </summary>
            <param name="model">Model chứa thông tin cập nhật.</param>
            <returns>Kết quả cập nhật.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Cms.UrlRedirectController">
             <summary>
             Màn hình "Chuyển hướng URL": khai luật 301/302 cho website công khai mà không phải deploy.
            
             <para>
             <b>Quyền tách làm hai mức theo hậu quả, không theo động từ HTTP.</b>
             <c>UrlRedirect.View</c> cho hai lời gọi chỉ đọc — kể cả <c>POST search</c>, vốn là POST chỉ vì
             <c>SmartTable</c> gửi bộ lọc trong thân request. <c>UrlRedirect.Manage</c> cho hai lời gọi ghi:
             chúng đổi <b>điều hướng của trang công khai</b> trong vòng 5 phút (thời hạn cache của middleware
             bên website), không qua bước duyệt nào.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.UrlRedirectController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách luật chuyển hướng, có lọc và phân trang</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.UrlRedirectController.GetById(System.Int32)">
            <summary>Một luật để mở form sửa</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.UrlRedirectController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRedirectModel)">
            <summary>
            Thêm hoặc sửa một luật chuyển hướng.
            </summary>
            <remarks>
            <b>Danh tính người thực hiện lấy từ token, không lấy từ thân request.</b> Hai trường
            <c>UpdatedBy</c>/<c>UpdatedByUserName</c> của model bị ghi đè ngay đầu hàm: chúng có trong
            model vì tầng service dùng chung khuôn với các màn CRUD khác, nhưng nhận giá trị do client
            gửi lên là để bất kỳ ai cũng ký tên người khác vào một thay đổi điều hướng công khai.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.UrlRedirectController.Delete(System.Int32)">
            <summary>Xoá mềm một luật chuyển hướng</summary>
            <remarks>
            Xoá luật <b>không</b> bật lại cờ <c>IncludeInSiteMap</c> của bản ghi <c>UrlRecord</c> tương
            ứng — lý do đầy đủ nằm ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRedirectService.Delete(System.Int32,System.Int32,System.String)"/>.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Cms.UrlRedirectNavController">
            <summary>
            Cờ hiển thị cho màn hình "Chuyển hướng URL" — "tôi được thấy nút nào".
            </summary>
            <remarks>
            Endpoint này <b>cố ý không đòi role nào</b> (chỉ cần đăng nhập): người không có quyền gì vẫn
            phải hỏi được và nhận về toàn <c>false</c> để giao diện ẩn nút. Gác nó bằng một role là dựng lại
            đúng lỗi nó sinh ra để chữa — trang sẽ hiện nút cho người không bấm được, hoặc gãy vì lời gọi
            hỏi quyền lại bị 403. Luật nằm ở hàm thuần <see cref="T:Ladaer.BackEnd.Controllers.Cms.UrlRedirectNavPermissions"/>, controller
            chỉ hỏi role rồi chuyển tiếp (mẫu: <c>SearchConsoleNavController</c>).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.UrlRedirectNavController.GetNavPermissions">
            <summary>Cờ hiển thị nút của màn hình chuyển hướng URL cho người đang đăng nhập</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Cms.UrlRedirectNavPermissions">
            <summary>
            Luật "ai thấy gì" của màn hình Chuyển hướng URL.
            </summary>
            <remarks>
            <para>
            <b>Hàm thuần</b> — không chạm database, không đọc <c>HttpContext</c>: nhận danh sách role đã
            phân giải qua <c>IUserRoleResolver</c>, trả các cờ. Controller thì không test được sạch vì
            <c>User.GetCurrentUser()</c> nuốt mọi ngoại lệ rồi trả <c>UserId = 0</c>.
            </para>
            <para>
            <b><c>CanManage</c> không kéo theo <c>CanView</c>.</b> Hàng rào thật là các thuộc tính
            <c>[Authorize(Roles = …)]</c> trên <c>UrlRedirectController</c>: hai lời gọi đọc đòi đúng
            <c>UrlRedirect.View</c>. Một người chỉ được cấp <c>UrlRedirect.Manage</c> mà thấy trang mở ra
            sẽ ăn 403 ngay ở lời gọi nạp bảng, nên cờ phải soi đúng bó quyền nó gác chứ không mượn bó khác.
            Ở miền này khả năng lệch còn cao hơn miền đồng bộ tìm kiếm: hai quyền cố ý <b>không</b> được
            nối vào nhóm <c>Permission</c> nào (chủ dự án chốt 2026-09-15 "chỉ Founder"), nên mọi lần cấp
            về sau đều là gán tay — và gán tay thì lệch được.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.Cms.UrlRedirectNavPermissions.Founder">
            <summary>Vai bỏ qua mọi kiểm tra role của hệ thống — ẩn nút của Founder là dựng hàng rào không có thật.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.Cms.UrlRedirectNavPermissions.View">
            <summary>Role của hai lời gọi chỉ đọc: <c>search</c>, <c>get-by-id</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.Cms.UrlRedirectNavPermissions.Manage">
            <summary>Role của hai lời gọi đổi điều hướng công khai: <c>create-or-update</c>, <c>delete</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.UrlRedirectNavPermissions.Resolve(System.Collections.Generic.IEnumerable{System.String})">
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c>; <c>null</c> hoặc rỗng = không có role nào</param>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Cms.UrlRedirectNavFlags">
            <summary>Cờ hiển thị của màn hình Chuyển hướng URL — mỗi cờ gác đúng một bó quyền (xem <see cref="T:Ladaer.BackEnd.Controllers.Cms.UrlRedirectNavPermissions"/>)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Cms.UrlRedirectNavFlags.#ctor(System.Boolean,System.Boolean)">
            <summary>Cờ hiển thị của màn hình Chuyển hướng URL — mỗi cờ gác đúng một bó quyền (xem <see cref="T:Ladaer.BackEnd.Controllers.Cms.UrlRedirectNavPermissions"/>)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Connect.ConnectController">
            <summary>
            Trang đăng nhập + đồng ý của authorization server OAuth 2.1 cho MCP (plan §3.4, §7.2): người dùng đăng nhập bằng
            tài khoản LADA, xem client nào xin quyền gì, bấm đồng ý → OpenIddict cấp mã uỷ quyền. Endpoint token / revocation /
            metadata do OpenIddict tự phục vụ (không passthrough). Không nằm dưới /api nên không qua FrontendOriginMiddleware.
            </summary>
            <remarks>
            <para>
            Hai luật không có đường vòng: tài khoản <b>Founder</b> không được cấp quyền cho trợ lý AI (plan §7.4d) và tài khoản
            phải có role MCP — lúc đăng nhập: ≥ 1 role <c>ContentStore.*</c> hoặc <c>Analytics.*</c>; lúc đồng ý: role của
            ĐÚNG mặt MCP mà <c>resource</c> xin (<see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpConsentPolicy"/>). Một issuer phục vụ hai mặt (<c>/mcp</c> kho
            nội dung, <c>/analytics</c> số liệu), nên token chỉ mang scope thuộc resource đã xin — scope không lọt chéo.
            </para>
            <para>
            <see cref="F:Ladaer.BackEnd.Controllers.Connect.ConnectController.ScopeLabels"/> là <b>nửa dành cho người</b> của hợp đồng MCP: nó nói bằng tiếng Việt thứ mà token sắp
            cấp cho phép làm. Nửa dành cho máy là <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract"/> + mô tả từng tool. Mở rộng quyền của một
            scope thì sửa nhãn ở đây trong cùng commit, không thì người bấm "Đồng ý" đang đồng ý với một câu đã cũ.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.Connect.ConnectController.ConsentFormParameters">
            <summary>
            Tham số OAuth được chép lại thành input ẩn của form đồng ý — danh sách cố định, để tham số lạ trong URL
            (ví dụ kẻ xấu chèn <c>decision=accept</c> vào link authorize gửi nạn nhân) không lọt vào form.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Connect.ConnectController.DeniedPage(System.String)">
            <summary>Trang từ chối theo MÃ lý do (không phản chiếu chuỗi tự do từ URL lên trang mang thương hiệu LADA).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Connect.ConnectController.OnActionExecuting(Microsoft.AspNetCore.Mvc.Filters.ActionExecutingContext)">
            <summary>Mọi trang /connect không được nhúng trong khung (chống clickjacking trang đồng ý).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Connect.ConnectController.SafeReturnUrl(System.String)">
            <summary>Chỉ nhận đường dẫn cục bộ trỏ về /connect/authorize; còn lại về trang từ chối.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Connect.ConnectController.DenialReasonAsync(Lada.Framework.Data.Domains.Identity.User)">
            <summary>
            Lý do không cho ĐĂNG NHẬP trang OAuth; null nếu được. Lúc này chưa đọc resource của yêu cầu nên chỉ đòi "có role
            MCP nào đó" — role đúng mặt kiểm ở bước đồng ý (<see cref="M:Ladaer.BackEnd.Controllers.Connect.ConnectController.ConsentDecisionAsync(Lada.Framework.Data.Domains.Identity.User,OpenIddict.Abstractions.OpenIddictRequest)"/>).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Connect.ConnectController.ConsentDecisionAsync(Lada.Framework.Data.Domains.Identity.User,OpenIddict.Abstractions.OpenIddictRequest)">
            <summary>Resource + scope sẽ cấp cho yêu cầu này, hoặc lý do từ chối (<see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpConsentPolicy"/>).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Connect.McpRegistrationController">
            <summary>
            Đăng ký client động (RFC 7591) <c>POST /connect/register</c> — Claude.ai / Cowork / ChatGPT gọi khi người dùng thêm
            connector. Ẩn danh theo RFC nhưng bị giới hạn 10 lần/phút/IP và redirect URI phải thuộc allowlist.
            </summary>
            <remarks>
            Endpoint này chỉ cấp danh tính cho client, không mang một luật nội dung nào. Thứ trợ lý AI đọc để biết viết bài
            thế nào là <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract"/> + mô tả từng tool, trả ở <c>initialize</c> và
            <c>tools/list</c> sau khi đã có token.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.ContentStore.ContentAccessTokenController">
            <summary>
            Quản lý token truy cập cá nhân (PAT) cho MCP — quản trị tạo hộ user, thu hồi, xem danh sách. Chuỗi token chỉ trả
            về một lần ở <c>Create</c>. Toàn bộ cần role <c>ContentStore.ManageToken</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentAccessTokenController.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenCreateModel)">
            <summary>Tạo token cho một user — 201 kèm <c>Data.PlainToken</c> (chỉ lần này); 400 khi user là Founder / thiếu role / scope sai.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentAccessTokenController.List(System.Nullable{System.Int32},System.Boolean)">
            <summary>Danh sách token (không có chuỗi/hash); mặc định ẩn token đã thu hồi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentAccessTokenController.Revoke(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenRevokeModel)">
            <summary>Thu hồi token — 200 (gọi lại token đã thu hồi cũng 200 kèm cảnh báo); 404 khi không có.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController">
            <summary>
            Bài viết trong kho nội dung AI (GĐ A: tạo nháp, đọc, tìm, render).
            Body trả về luôn là <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreResult`1"/> nguyên vẹn — kể cả khi thành công —
            để client luôn có Warnings; HTTP status suy từ mã lỗi qua <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.ToHttpStatus(System.String)"/>.
            </summary>
            <remarks>
            <b>Số liệu trong bài</b> (hợp đồng 0.2, từ 2026-09-12): thân bài viết trọn, không còn ô chờ
            <c>[[CẦN …]]</c>; khoản nào chưa có số thì nằm ở <c>Brief.DataNeeded</c>, còn cả bài chờ số thì để trạng
            thái <c>needs_data</c> kèm lý do. Bài cũ còn sót chuỗi đó vẫn lưu và vẫn đăng được, chỉ kèm cảnh báo
            <c>LEGACY_PLACEHOLDER</c> và bị dọn khỏi bản gửi sang CMS. Câu chữ mà trợ lý AI đọc nằm ở
            <c>Infrastructures/Mcp/McpServerContract.cs</c> — sửa hành vi thì sửa cả hai trong một commit.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleModel)">
            <summary>Tạo bản nháp bài 4 phần — 201 khi thành công; 400/404/409/413/422 theo mã lỗi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController.GetById(System.Int32)">
            <summary>Bài đầy đủ theo Id — 404 nếu không có.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController.GetByTopicCode(System.String)">
            <summary>Bài đầy đủ theo mã đề — 404 nếu đề chưa có bài.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách bài rút gọn theo SmartTableParam.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController.Render(System.Int32,System.String)">
            <summary>Render thân bài + FAQ: <c>format</c> = html (mặc định) | markdown.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleUpdateModel)">
            <summary>
            Sửa nội dung bài — 200 khi thành công; 409 <c>VERSION_CONFLICT</c> kèm bản hiện tại trong
            <c>Extra.Current</c> khi <c>ExpectedVersion</c> lệch; 400/404/413/422 theo mã lỗi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController.SetStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleStatusModel)">
            <summary>Đổi trạng thái bài — 422 <c>INVALID_TRANSITION</c> kèm danh sách đích hợp lệ trong <c>Extra.AllowedTargets</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController.Approve(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleApproveModel)">
            <summary>
            Duyệt đăng — chạy đủ 8 điều kiện §3.3d rồi mới chuyển <c>Approved</c>.
            Thiếu điều kiện → 422 <c>PUBLISH_PRECONDITION_FAILED</c> kèm <c>Extra.Missing</c> / <c>Extra.Checks</c>
            và <b>không ghi gì</b>. Gác riêng bằng <c>ContentStore.Approve</c>, không dùng chung
            <c>ContentStore.Edit</c> của <c>SetStatus</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController.RevokeApproval(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleRevokeApprovalModel)">
            <summary>Rút lại bài đã duyệt (Approved → Chờ duyệt), lý do bắt buộc — cùng quyền với duyệt.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController.SetPeople(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticlePeopleModel)">
            <summary>Gán tác giả / người kiểm tra cho bài; trả lại bài đầy đủ sau khi gán.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController.CheckSlug(System.String)">
            <summary>Slug còn trống không (nhìn cả <c>UrlRecord</c> đã xoá mềm của CMS), kèm gợi ý thay thế.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController.Versions(System.Int32)">
            <summary>Lịch sử phiên bản của bài, mới nhất trước — 404 nếu không có bài.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController.SetImageStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageStatusModel)">
            <summary>
            Ghi kết quả một dòng ảnh sau khi nộp file (<c>set_image_status</c>): URL ảnh, URL bản OG,
            trạng thái, ghi chú kiểm. Không đụng thông số ảnh — thứ đó sửa qua <c>Update</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController.DeleteImage(System.Int32)">
            <summary>Bỏ một ảnh khỏi bộ ảnh của bài (xoá mềm) — dùng khi bài không cần tấm đó.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentArticleController.PublishCheck(System.Int32)">
            <summary>
            Tám điều kiện đăng §3.3d ở chế độ <b>chỉ đọc</b> — màn duyệt hiện danh sách còn thiếu.
            Không đổi gì; chuyển sang <c>Approved</c> là việc của GĐ E. 404 nếu không có bài.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.ContentStore.ContentAuthorController">
            <summary>
            Tác giả / người kiểm tra của kho nội dung AI (<c>list_people</c> đặc tả §5.3 + CRUD cho màn quản trị).
            Đọc thì chỉ cần quyền tìm kiếm; ghi thì cần <c>ContentStore.ManageAuthor</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentAuthorController.List(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAuthorListRequest)">
            <summary>Danh sách gọn cho trợ lý AI và ô chọn tác giả: <c>?RoleTitle=&amp;IsActive=true&amp;Limit=50</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentAuthorController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAuthorModel)">
            <summary>Tạo mới (Id = 0) hoặc sửa — 201 khi tạo, 200 khi sửa.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentAuthorController.Delete(System.Int32)">
            <summary>Xoá mềm — từ chối nếu người này còn đứng tên bài nào.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.ContentStore.ContentImageKitController">
            <summary>
            Bộ công cụ ảnh: khối STYLE BASE/DO NOT, từ điển khuôn ảnh, ảnh tham chiếu thương hiệu.
            </summary>
            <remarks>
            Đọc gác bằng <c>ContentStore.GetById</c> — người tạo ảnh cần xem khuôn và ảnh tham chiếu ngay
            trên màn chi tiết bài. Ghi gác bằng <c>ContentStore.ManageAssets</c>, role RIÊNG cho cấu hình
            thương hiệu: không mượn role của dữ liệu bài viết, vì cấu hình thương hiệu là miền khác hẳn.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentImageKitController.GetKit">
            <summary>Toàn bộ bộ công cụ cho màn cấu hình (kể cả bản đã tắt).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentImageKitController.GetSnapshot">
            <summary>Bản dùng cho màn chi tiết bài: khuôn + ảnh tham chiếu đang bật.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.ContentStore.ContentImportController">
            <summary>
            Nhập bài từ file Markdown 4 phần — đường vào cho trợ lý không có MCP (ChatGPT, Gemini) và cho
            các file nháp viết trước khi kho nội dung tồn tại.
            <para>
            File <b>không lưu xuống đĩa</b>: đọc thẳng từ luồng vào bộ nhớ, xử lý xong là hết. Đây là chủ ý —
            một thư mục upload trên máy chủ là bề mặt tấn công mới mà nghiệp vụ này không cần tới.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentImportController.Upload(System.Collections.Generic.List{Microsoft.AspNetCore.Http.IFormFile},System.Boolean)">
            <summary>
            Nộp một hoặc nhiều file <c>.md</c> (multipart). <c>dryRun=true</c> chỉ soát và báo cáo, không ghi gì.
            200 kèm bảng kết quả từng file — file hỏng không chặn file lành.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentImportController.Folder(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImportFolderModel)">
            <summary>
            Nhập cả một thư mục trên máy chạy API — đường dẫn truyền qua payload, không hard-code trong code.
            Dùng cho lượt nhập đầu tiên (30 file nháp) khi file nằm sẵn trên máy chủ nội bộ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.ContentStore.ContentPublishController">
            <summary>
            Xuất bản bài từ kho nội dung sang CMS <c>Post</c> — đường duy nhất dữ liệu kho nội dung ra được website.
            </summary>
            <remarks>
            <para>
            <b>Hai action, cùng một hàm service.</b> <c>Preview</c> và <c>Publish</c> gọi đúng
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentPublishService.Publish(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)"/>, chỉ khác cờ <c>DryRun</c> — và <c>Preview</c> <b>ép</b>
            cờ đó về <c>true</c> ở đây, không tin giá trị người gọi gửi lên. Hai đường code song song cho
            "xem trước" và "làm thật" là cách chắc chắn để một hôm nào đó chúng lệch nhau, và chỗ lệch sẽ nằm
            đúng trên đường ghi ra trang công khai.
            </para>
            <para>
            <b>Cả hai gác <c>ContentStore.Publish</c>.</b> Xem trước cũng là quyền: nó trả nguyên HTML sẽ đăng.
            Riêng chế độ "Đăng ngay" đòi thêm role <c>Post.Publish</c>, kiểm <b>ở tầng service</b> chứ không phải
            ở đây (§7.11) — MCP và PAT cũng đi qua đúng hàm đó.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentPublishController.Preview(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishModel)">
            <summary>
            Soát thử: trả HTML, mục lục, số H2 / ảnh / FAQ và danh sách việc sẽ ghi. <b>Không ghi một dòng nào</b>,
            và chạy được cả khi công tắc <c>ContentStore.PublishEnabled</c> đang tắt — đây chính là cách kiểm bài
            trước khi xin bật công tắc.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentPublishController.Publish(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishModel)">
            <summary>
            Xuất bản thật. Đòi công tắc <c>ContentStore.PublishEnabled = true</c> (503 <c>PUBLISH_DISABLED</c>
            nếu tắt), bài đang <c>Approved</c>, và <b>đủ 8 điều kiện đăng kiểm lại tại thời điểm này</b>
            (422 <c>PUBLISH_PRECONDITION_FAILED</c>) — <c>Approved</c> là kết luận của thời điểm duyệt, không
            phải giấy phép vĩnh viễn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentPublishController.PreviewResyncImages(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResyncModel)">
            <summary>
            Soát thử đồng bộ lại ảnh sang bài viết CMS của một bài <b>đã xuất bản</b>: cho biết ảnh đại diện
            và thân bài sẽ đổi những gì. <b>Không ghi một dòng nào</b>, và chạy được cả khi công tắc đang tắt.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentPublishController.ResyncImages(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResyncModel)">
            <summary>
            Ghi thật ảnh của bài sang <c>Post</c> đã đăng — ảnh đại diện / OG, và thân bài nếu nó còn đúng bản
            do kho dựng ra. Đòi công tắc <c>ContentStore.PublishEnabled = true</c> như đường xuất bản.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentPublishController.Categories">
            <summary>
            Danh mục CMS chọn được, kèm cờ danh mục mặc định. Mảng thẳng, không bọc <c>ContentStoreResult</c>
            (đúng bảng vỏ trả về của miền). Gác <c>ContentStore.Publish</c> chứ không phải <c>Category.GetTree</c>
            — màn đăng phải chạy được với đúng bó quyền của chính nó.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentPublishController.SyncPublishedStatus">
            <summary>
            Chạy tay job đồng bộ trạng thái đăng — thứ Hangfire vẫn chạy mỗi 15 phút. Có ở đây để người vận hành
            không phải chờ một chu kỳ khi vừa bấm đăng trong CMS cũ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.ContentStore.ContentRunLogController">
            <summary>
            Nhật ký lượt chạy nháp bài (<c>append_run_log</c> đặc tả §5.1) và danh sách trang dịch vụ
            (<c>list_service_pages</c> đặc tả §5.3) — hai tra cứu nhỏ của cùng một nhóm người dùng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentRunLogController.Append(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentRunLogModel)">
            <summary>Ghi một lượt chạy — 201 kèm dòng vừa ghi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentRunLogController.Recent(System.Int32)">
            <summary>Các lượt gần nhất, mới trước (mặc định 20, tối đa 100).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentRunLogController.ServicePages">
            <summary>
            Toàn bộ trang dịch vụ đang chạy trên website, để trợ lý AI đặt link nội bộ theo URL thật
            thay vì bịa đường dẫn.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.ContentStore.ContentStoreController">
            <summary>Những thứ chung của cả miền kho nội dung AI, không thuộc riêng bài / đề / tác giả / token.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentStoreController.NavPermissions">
            <summary>
            Cờ ẩn/hiện cho giao diện: người này bấm được nút nào trong kho nội dung.
            </summary>
            <remarks>
            <b>Cố ý KHÔNG gác bằng role nào.</b> Câu hỏi "tôi được thấy gì" phải trả lời được cho cả người không
            có quyền nào — họ nhận đủ cờ <c>false</c>. Gác nó bằng một role là dựng lại đúng cái lỗi nó sinh ra
            để chữa (rule <c>quyen-hien-thi</c> §4).
            <para>
            Luật nằm ở hàm thuần <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreNavPermissions"/>, không nằm ở đây — controller chỉ hỏi
            role rồi chuyển tiếp.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentStoreController.DeployCheck(System.Threading.CancellationToken)">
            <summary>
            Ảnh chụp trạng thái triển khai: phiên bản schema, số dòng từng bảng <c>Content*</c>, role đã seed và
            số người có, ba công tắc, cấu hình MCP đang chạy, và thứ API nhìn thấy về chính request này.
            </summary>
            <remarks>
            <para>
            <b>Đây là thứ thay cho việc mở SQL client vào production</b> (quyết định Q7, plan §7.12). Trình tự
            deploy §4.4 bước 1 đòi xác nhận migration và seed bằng query; ràng buộc 2026-08-27 cấm chạy SQL tay
            vào <c>Ladaer2</c> production. Endpoint chỉ đọc, không tham số, và dùng lại được ở mọi lần deploy sau.
            </para>
            <para>
            <b>Vì sao gác <c>Founder</c> chứ không phải một role <c>ContentStore.*</c>.</b> Việc của nó là chứng
            minh <b>seed role đã chạy</b> — gác nó bằng chính role mà seed tạo ra là vòng tròn: seed hỏng thì
            endpoint báo 403 và không ai biết vì sao. <c>Founder</c> có sẵn từ trước mọi migration của đợt này.
            </para>
            <para>
            Luật nằm ở <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentDeployCheckService"/>; controller <b>trả thẳng</b> kết quả, không chép
            tay từng trường — đúng bài học <c>NavPermissions</c> 2026-09-07.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.ContentStore.ContentStoreControllerBase">
            <summary>
            Phần dùng chung của các controller kho nội dung AI: dựng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor"/> từ người dùng hiện tại
            và đổi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreResult`1"/> thành HTTP response. Không đặt [Authorize] ở đây —
            từng controller tự khai để role hiện rõ ngay tại chỗ.
            </summary>
            <remarks>
            <b>REST và MCP là hai lớp vận chuyển của cùng một luật</b> — luật nằm ở tầng service, còn thứ trợ lý AI đọc
            để biết phải viết bài thế nào nằm ở <c>Infrastructures/Mcp/McpServerContract.cs</c> cùng mô tả từng tool.
            Đổi hành vi ở đây mà không sửa hợp đồng bên đó là dựng lại đúng cái lệch pha 2026-09-12: code bỏ ô chờ
            <c>[[CẦN …]]</c> nhưng chỉ dẫn MCP vẫn dạy trợ lý để ô lại, nên nó vừa làm theo vừa bị cảnh báo.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentStoreControllerBase.Actor">
            <summary>Người thực hiện thao tác: UserId/UserName từ JWT, RequestId là TraceIdentifier; Client giữ mặc định "admin".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentStoreControllerBase.FromResult``1(Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreResult{``0},System.Int32)">
            <summary>
            Trả nguyên <paramref name="r"/> làm body (kể cả khi thành công, để client luôn có Warnings);
            status = <paramref name="okStatus"/> khi Success, ngược lại suy từ mã lỗi qua <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.ToHttpStatus(System.String)"/>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.ContentStore.ContentTopicController">
            <summary>Hàng đợi đề bài của kho nội dung AI (list_topics / create_topics, đặc tả §5.1).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentTopicController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách đề cho màn quản trị theo SmartTableParam.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentTopicController.List(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicListRequest)">
            <summary>Danh sách đề cho trợ lý AI: <c>?Status=&amp;WeekNo=&amp;ExcludeL2=F2&amp;Limit=20</c>, theo SortOrder tăng dần.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentTopicController.Create(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicModel})">
            <summary>Tạo nhiều đề một lần — 201 kèm Created/Rejected từng dòng; 400 khi payload rỗng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.ContentStore.ContentTopicController.UpdateStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicStatusModel)">
            <summary>Đổi trạng thái một đề — 404 nếu không có mã đề; 400 khi "Đã nháp" mà thiếu ArticleId.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Crm.CallLogController">
            <summary>
            CallLog Controller - Quản lý cuộc gọi tổng đài
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CallLogController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm call log
            </summary>
            <param name="param">Các tham số tìm kiếm</param>
            <returns>Kết quả tìm kiếm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CallLogController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết call log theo ID
            </summary>
            <param name="id">ID của call log</param>
            <returns>Thông tin chi tiết call log</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CallLogController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel)">
            <summary>
            Tạo hoặc cập nhật call log
            </summary>
            <param name="model">Model chứa thông tin call log cần tạo/cập nhật</param>
            <returns>Kết quả của hoạt động tạo/cập nhật call log</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CallLogController.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel)">
            <summary>
            Tạo call log mới
            </summary>
            <param name="model">Model chứa thông tin call log cần tạo</param>
            <returns>Kết quả của hoạt động tạo call log</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CallLogController.Delete(System.Int32)">
            <summary>
            Xóa call log
            </summary>
            <param name="id">ID của call log cần xóa</param>
            <returns>Kết quả của hoạt động xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CallLogController.UpdateLeadStatus(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel)">
            <summary>
            Cập nhật trạng thái Lead cho call log
            </summary>
            <param name="id">ID của call log</param>
            <param name="model">Model chứa thông tin trạng thái mới</param>
            <returns>Kết quả của hoạt động cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CallLogController.GetByPhoneNumber(System.String)">
            <summary>
            Lấy danh sách call log theo số điện thoại
            </summary>
            <param name="phoneNumber">Số điện thoại</param>
            <returns>Danh sách call log</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CallLogController.GetStatistics(System.Nullable{System.DateTime},System.Nullable{System.DateTime})">
            <summary>
            Thống kê call log theo khoảng thời gian
            </summary>
            <param name="startDate">Ngày bắt đầu</param>
            <param name="endDate">Ngày kết thúc</param>
            <returns>Thống kê call log</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Crm.CustomerAddressController">
            <summary>
            Controller xử lý các hoạt động liên quan đến địa chỉ khách hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerAddressController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerAddressService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Crm.CustomerAddressController"/>.
            </summary>
            <param name="customerAddressService">Dịch vụ xử lý địa chỉ khách hàng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerAddressController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các địa chỉ khách hàng dựa trên các tham số được cung cấp.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerAddressController.SearchSource(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các địa chỉ nguồn dựa trên các tham số được cung cấp.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerAddressController.SearchDest(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các địa chỉ đích dựa trên các tham số được cung cấp.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerAddressController.CreateDestAddress(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel)">
            <summary>
            Tạo địa chỉ đích cho khách hàng.
            </summary>
            <param name="customerAddressModel">Model chứa thông tin địa chỉ khách hàng.</param>
            <returns>Kết quả của hoạt động tạo địa chỉ đích.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerAddressController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel)">
            <summary>
            Tạo hoặc cập nhật địa chỉ khách hàng.
            </summary>
            <param name="customerAddressModel">Model chứa thông tin địa chỉ khách hàng.</param>
            <returns>Kết quả của hoạt động tạo hoặc cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerAddressController.UpdateCoord(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.UpdateCustomerAddressCoordModel)">
            <summary>
            Cập nhật riêng định vị (Lat/Long) của một địa chỉ khách hàng.
            Gửi Lat = Long = null để xoá định vị đang có.
            </summary>
            <param name="model">Toạ độ cần ghi.</param>
            <returns>Kết quả của hoạt động cập nhật.</returns>
            <remarks>
            Dùng chung role với CreateOrUpdate: ghim toạ độ bản chất là sửa địa chỉ, nên ai
            sửa được địa chỉ thì ghim được. Đặt role mới sẽ khiến toàn bộ nhân viên đang
            dùng bị 403 cho tới khi role đó được thêm vào DB.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerAddressController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của một địa chỉ khách hàng dựa trên ID.
            </summary>
            <param name="id">ID của địa chỉ khách hàng.</param>
            <returns>Thông tin chi tiết của địa chỉ khách hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerAddressController.Delete(System.Int32)">
            <summary>
            Xóa một địa chỉ khách hàng dựa trên ID.
            </summary>
            <param name="id">ID của địa chỉ khách hàng.</param>
            <returns>Kết quả của hoạt động xóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerAddressController.Suggest(System.String,System.Int32,System.Int32)">
            <summary>
            Gợi ý địa chỉ khách hàng dựa trên từ khóa, ID khách hàng và loại địa chỉ.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="customerId">ID của khách hàng.</param>
            <param name="type">Loại địa chỉ.</param>
            <returns>Danh sách địa chỉ phù hợp.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Crm.CustomerBankAccountController">
            <summary>
            Controller quản lý tài khoản ngân hàng khách hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerBankAccountController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerBankAccountService)">
            <summary>
            Khởi tạo controller
            </summary>
            <param name="customerBankAccountService">Service quản lý tài khoản ngân hàng</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerBankAccountController.GetByCustomerId(System.Int32)">
            <summary>
            Lấy danh sách tài khoản ngân hàng của khách hàng
            </summary>
            <param name="customerId">ID khách hàng</param>
            <returns>Danh sách tài khoản ngân hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerBankAccountController.GetDefaultByCustomerId(System.Int32)">
            <summary>
            Lấy tài khoản ngân hàng mặc định của khách hàng
            </summary>
            <param name="customerId">ID khách hàng</param>
            <returns>Tài khoản ngân hàng mặc định</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerBankAccountController.GetById(System.Int32)">
            <summary>
            Lấy thông tin tài khoản ngân hàng theo ID
            </summary>
            <param name="id">ID tài khoản</param>
            <returns>Thông tin tài khoản ngân hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerBankAccountController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel)">
            <summary>
            Tạo hoặc cập nhật tài khoản ngân hàng
            </summary>
            <param name="model">Thông tin tài khoản ngân hàng</param>
            <returns>Kết quả thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerBankAccountController.Delete(System.Int32)">
            <summary>
            Xóa tài khoản ngân hàng
            </summary>
            <param name="id">ID tài khoản</param>
            <returns>Kết quả thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerBankAccountController.SetDefault(System.Int32)">
            <summary>
            Đặt tài khoản làm mặc định
            </summary>
            <param name="id">ID tài khoản</param>
            <returns>Kết quả thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerBankAccountController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm tài khoản ngân hàng
            </summary>
            <param name="keyword">Từ khóa tìm kiếm (số TK, tên chủ TK, tên ngân hàng)</param>
            <param name="customerId">ID khách hàng (tùy chọn)</param>
            <param name="bankCode">Mã ngân hàng (tùy chọn)</param>
            <returns>Danh sách tài khoản ngân hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerBankAccountController.Suggest(System.Int32,System.String)">
            <summary>
            Gợi ý tài khoản ngân hàng cho khách hàng
            </summary>
            <param name="customerId">ID khách hàng</param>
            <param name="keyword">Từ khóa tìm kiếm</param>
            <returns>Danh sách gợi ý</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Crm.CustomerComplaintController">
            <summary>
            Controller xử lý ticket khiếu nại của khách hàng phía nhân viên
            (khiếu nại do khách tạo từ app qua Lada.AppBackEnd, khách xem phản hồi qua api/complaints).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerComplaintController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerComplaintManagementService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Crm.CustomerComplaintController"/>.
            </summary>
            <param name="complaintService">Dịch vụ xử lý ticket khiếu nại.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerComplaintController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm khiếu nại của khách hàng.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerComplaintController.GetById(System.Int32)">
            <summary>
            Lấy chi tiết khiếu nại kèm ảnh đính kèm.
            </summary>
            <param name="id">Id khiếu nại.</param>
            <returns>Chi tiết khiếu nại.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerComplaintController.StartProcessing(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.ComplaintProcessModel)">
            <summary>
            Tiếp nhận khiếu nại (chuyển sang trạng thái đang xử lý).
            </summary>
            <param name="model">Thông tin thao tác.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerComplaintController.Respond(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.ComplaintProcessModel)">
            <summary>
            Phản hồi khiếu nại cho khách.
            </summary>
            <param name="model">Thông tin phản hồi.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerComplaintController.Resolve(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.ComplaintProcessModel)">
            <summary>
            Đóng khiếu nại (chuyển sang trạng thái đã giải quyết).
            </summary>
            <param name="model">Thông tin thao tác.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Crm.CustomerController">
            <summary>
            Controller dịch vụ xử lý các hoạt động liên quan đến khách hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Crm.CustomerController"/>.
            </summary>
            <param name="customerService">Dịch vụ xử lý khách hàng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các khách hàng dựa trên các tham số được cung cấp.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.Suggest(System.String)">
            <summary>
            Gọi đến khách hàng dựa trên từ khóa.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <returns>Danh sách khách hàng phù hợp.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.SugManagers(System.String)">
            <summary>
            Gợi ý danh sách sale quản lý dùng cho bộ lọc danh sách khách hàng.
            Founder thấy toàn bộ nhân viên; người dùng thường chỉ thấy bản thân và cấp dưới trực tiếp.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <returns>Danh sách nhân viên phù hợp.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerModel)">
            <summary>
            Tạo hoặc cập nhật thông tin khách hàng.
            </summary>
            <param name="customerModel">Model chứa thông tin khách hàng.</param>
            <returns>Kết quả của hoạt động tạo hoặc cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.UpdateProp(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerPropModel)">
            <summary>
            Cập nhật thông tin thuộc tính của khách hàng.
            </summary>
            <param name="customerModel">Model chứa thông tin thuộc tính của khách hàng.</param>
            <returns>Kết quả của hoạt động cập nhật thuộc tính.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.GetProp(System.Int32,Lada.Framework.Data.Enums.PropType)">
            <summary>
            Lấy thông tin thuộc tính của khách hàng dựa trên ID và loại thuộc tính.
            </summary>
            <param name="customerId">ID của khách hàng.</param>
            <param name="propType">Loại thuộc tính.</param>
            <returns>Thông tin thuộc tính của khách hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của một khách hàng dựa trên ID.
            </summary>
            <param name="id">ID của khách hàng.</param>
            <returns>Thông tin chi tiết của khách hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.Delete(System.Int32)">
            <summary>
            Xóa một khách hàng dựa trên ID.
            </summary>
            <param name="id">ID của khách hàng.</param>
            <returns>Kết quả của hoạt động xóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.Lock(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerStatusModel)">
            <summary>
            Khóa một khách hàng.
            </summary>
            <param name="model">Model chứa thông tin khách hàng cần khóa.</param>
            <returns>Kết quả của hoạt động khóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.UnLock(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerStatusModel)">
            <summary>
            Mở khóa một khách hàng.
            </summary>
            <param name="model">Model chứa thông tin khách hàng cần mở khóa.</param>
            <returns>Kết quả của hoạt động mở khóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.SetPassword(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerSetPasswordModel)">
            <summary>
            Đặt lại mật khẩu cho tài khoản đăng nhập của một khách hàng.
            </summary>
            <param name="model">Model chứa Id khách hàng và mật khẩu mới.</param>
            <returns>Kết quả của hoạt động đặt lại mật khẩu.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.RegisterCustomerAccount(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.RegisterCustomerAccountModel)">
            <summary>
            Tạo tài khoản đăng nhập cho một khách hàng đã có hồ sơ.
            </summary>
            <param name="model">Model chứa Id khách hàng, tên đăng nhập và mật khẩu.</param>
            <returns>Kết quả của hoạt động tạo tài khoản.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.GetManagerById(System.Int32)">
            <summary>
            Lấy thông tin người quản lý của một khách hàng dựa trên ID.
            </summary>
            <param name="id">ID của khách hàng.</param>
            <returns>Thông tin người quản lý của khách hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.AssignManager(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.AssignManagerModel)">
            <summary>
            Gán người quản lý cho một khách hàng.
            </summary>
            <param name="model">Model chứa thông tin người quản lý cần gán.</param>
            <returns>Kết quả của hoạt động gán người quản lý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.BulkAssignManager(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.BulkAssignManagerModel)">
            <summary>
            Gán người quản lý hàng loạt cho nhiều khách hàng.
            </summary>
            <param name="model">Model chứa danh sách khách hàng và người quản lý.</param>
            <returns>Kết quả của hoạt động gán hàng loạt.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.ExportExcel(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Xuất danh sách khách hàng ra file Excel.
            </summary>
            <param name="param">Tham số tìm kiếm (dùng chung filter với Search).</param>
            <returns>Kết quả xuất Excel (chứa URL download trong Message).</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.GetCoManagers(System.Int32)">
            <summary>
            Lấy danh sách đồng quản lý của khách hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.CustomerController.RemoveCoManager(System.Int32)">
            <summary>
            Xóa đồng quản lý khỏi khách hàng.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.Crm.LeadController.ManagerRoles">
            <summary>
            Các role được xem toàn bộ lead (không bị giới hạn theo người phụ trách).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.LeadController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm lead
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.LeadController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.LeadModel)">
            <summary>
            Tạo hoặc cập nhật lead
            </summary>
            <param name="model">Model chứa thông tin lead cần tạo/cập nhật.</param>
            <returns>Kết quả của hoạt động tạo/cập nhật lead.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.LeadController.AssignManager(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.LeadStatusModel)">
            <summary>
            Gán người quản lý cho một lead.
            </summary>
            <param name="model">Model chứa thông tin người quản lý cần gán.</param>
            <returns>Kết quả của hoạt động gán người quản lý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.LeadController.GetReviewModel(System.Int32)">
            <summary>
            Lấy thông tin định giá của một lead dựa trên ID.
            </summary>
            <param name="id">ID của lead.</param>
            <returns>Thông tin định giá của lead.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.LeadController.UpdateReview(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.LeadStatusModel)">
            <summary>
            Cập nhật thông tin định giá của một lead.
            </summary>
            <param name="model">Model chứa thông tin định giá của lead.</param>
            <returns>Kết quả của hoạt động cập nhật định giá.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Crm.ManagerChangeRequestController">
            <summary>
            Controller duyệt/từ chối yêu cầu đổi nhân viên phụ trách do khách gửi từ app.
            Duyệt sẽ cập nhật Customer.ManagerId qua luồng AssignManager sẵn có.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.ManagerChangeRequestController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerComplaintManagementService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Crm.ManagerChangeRequestController"/>.
            </summary>
            <param name="complaintService">Dịch vụ xử lý ticket khiếu nại và yêu cầu đổi nhân viên.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.ManagerChangeRequestController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm yêu cầu đổi nhân viên phụ trách.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.ManagerChangeRequestController.Approve(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.ManagerChangeRequestProcessModel)">
            <summary>
            Duyệt yêu cầu: gán nhân viên phụ trách mới cho khách hàng.
            </summary>
            <param name="model">Thông tin duyệt (NewManagerId bắt buộc).</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.ManagerChangeRequestController.Reject(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.ManagerChangeRequestProcessModel)">
            <summary>
            Từ chối yêu cầu đổi nhân viên phụ trách.
            </summary>
            <param name="model">Thông tin từ chối (ProcessedNote bắt buộc).</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Crm.VatInfoController">
            <summary>
            Controller quản lý thông tin xuất hóa đơn VAT của khách hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.VatInfoController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy danh sách thông tin xuất hóa đơn VAT
            </summary>
            <param name="searchModel">Model tìm kiếm</param>
            <returns>Danh sách thông tin xuất hóa đơn VAT</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.VatInfoController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết xuất hóa đơn VAT theo ID
            </summary>
            <param name="id">ID thông tin xuất hóa đơn VAT</param>
            <returns>Thông tin chi tiết xuất hóa đơn VAT</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.VatInfoController.GetDefaultByCustomerId(System.Int32)">
            <summary>
            Lấy thông tin xuất hóa đơn VAT mặc định của khách hàng
            </summary>
            <param name="customerId">ID khách hàng</param>
            <returns>Thông tin xuất hóa đơn VAT mặc định</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.VatInfoController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.VatInfoModel)">
            <summary>
            Tạo mới hoặc cập nhật thông tin xuất hóa đơn VAT
            </summary>
            <param name="model">Model tạo mới hoặc cập nhật</param>
            <returns>Kết quả tạo mới hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.VatInfoController.Delete(System.Int32)">
            <summary>
            Xóa thông tin xuất hóa đơn VAT
            </summary>
            <param name="id">ID thông tin xuất hóa đơn VAT</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Crm.VatInfoController.SetAsDefault(System.Int32)">
            <summary>
            Đặt thông tin xuất hóa đơn VAT làm mặc định
            </summary>
            <param name="id">ID thông tin xuất hóa đơn VAT</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Dashboards.DashboardController">
            <summary>
            Dashboard cá nhân theo vai trò — mọi endpoint chỉ cần đăng nhập:
            dashboard là bề mặt cá nhân, phân quyền thật nằm ở mapping widget ↔ nhóm quyền
            và được DashboardService kiểm tra server-side ở từng thao tác.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Dashboards.WidgetAdminController">
            <summary>
            Quản trị danh mục widget dashboard: bật/tắt, gán nhóm quyền, sửa cấu hình mặc định,
            khoá tuỳ chọn (UserEditable trong SettingsSchema)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DriverAppController.GetDashboard">
            <summary>
            Lấy thông tin dashboard cho ứng dụng tài xế
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DriverAppController.GetFinancialInfo">
            <summary>
            Lấy thông tin tài chính của lái xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DriverAppController.SearchFinancialOrders(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh sách đơn hàng tài chính của lái xe có phân trang
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DriverAppController.SearchOrders(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh sách đơn hàng của lái xe có phân trang
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DriverAppController.GetOrder(System.Int32)">
            <summary>
            Lấy thông tin chi tiết đơn hàng theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DriverAppController.GetOrderByQuery(System.Int32)">
            <summary>
            Lấy chi tiết đơn hàng, id truyền qua query (<c>GetOrder?id=</c>) — dạng app tài xế gửi cho khoá
            CallPath <c>ORDER_GETBYID</c> (order_service.dart fetchOrderById). Tách action riêng vì
            <c>[ApiController]</c> suy ra <c>id</c> là <c>[FromRoute]</c> khi mọi route của action có <c>{id}</c>:
            chỉ chồng thêm <c>[HttpGet("GetOrder")]</c> lên action trên thì <c>?id=</c> bị bỏ qua, id = 0 và app
            nhận đơn rỗng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DriverAppController.Pickup(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppPickupModel)">
            <summary>
            Cập nhật trạng thái lấy hàng thành công
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DriverAppController.PickupFail(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailModel)">
            <summary>
            Cập nhật trạng thái lấy hàng thất bại
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DriverAppController.Delivery(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppDeliveryModel)">
            <summary>
            Cập nhật trạng thái giao hàng thành công
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DriverAppController.DeliveryFail(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailModel)">
            <summary>
            Cập nhật trạng thái giao hàng thất bại
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Ops.DeployController">
            <summary>
            Controller quản lý các hoạt động liên quan đến triển khai đơn hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService,Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService,Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Ops.DeployController"/>.
            </summary>
            <param name="deployService">Dịch vụ xử lý triển khai đơn hàng.</param>
            <param name="userService">Dịch vụ quản lý người dùng.</param>
            <param name="agencyService">Dịch vụ quản lý chi nhánh.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.GetDeployLocations">
            <summary>
            Lấy danh sách các địa điểm triển khai.
            </summary>
            <returns>Danh sách các địa điểm triển khai.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.GetDeliveryLocations">
            <summary>
            Lấy danh sách các địa điểm giao hàng.
            </summary>
            <returns>Danh sách các địa điểm giao hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.GetDeliveryOrders(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy danh sách các đơn hàng cần nhận hàng dựa trên các tham số tìm kiếm.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Danh sách các đơn hàng cần nhận hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.AssignDelivery(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel)">
            <summary>
            Gán giao hàng
            </summary>
            <param name="model">Model gán</param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.GetPickupLocations">
            <summary>
            Lấy danh sách các địa điểm nhận hàng.
            </summary>
            <returns>Danh sách các địa điểm nhận hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.GetPickupOrders(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy danh sách các đơn hàng cần nhận hàng dựa trên các tham số tìm kiếm.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Danh sách các đơn hàng cần nhận hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.AssignPickup(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel)">
            <summary>
            Gán nhiệm vụ nhận hàng cho người dùng.
            </summary>
            <param name="model">Model chứa thông tin gán nhiệm vụ.</param>
            <returns>Kết quả của hoạt động gán nhiệm vụ.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.UnAssignPickup(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel)">
            <summary>
            Hủy gán nhiệm vụ nhận hàng cho người dùng.
            </summary>
            <param name="model">Model chứa thông tin hủy gán nhiệm vụ.</param>
            <returns>Kết quả của hoạt động hủy gán nhiệm vụ.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.GetTransitLocations">
            <summary>
            Lấy danh sách các địa điểm trung chuyển.
            </summary>
            <returns>Danh sách các địa điểm trung chuyển.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.GetTransitOrders(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy danh sách các đơn hàng cần trung chuyển dựa trên các tham số tìm kiếm.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Danh sách các đơn hàng cần trung chuyển.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.AssignTransit(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel)">
            <summary>
            Gán trung chuyển
            </summary>
            <param name="model">Model gán</param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.GetDeployMonitor(System.Int32,System.Int32)">
            <summary>
            Lấy thông tin giám sát đơn hàng.
            </summary>
            <param name="pageNumber">Số trang.</param>
            <param name="pageSize">Kích thước trang.</param>
            <returns>Thông tin giám sát đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.GetDeployDetail(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy chi tiết đơn hàng dựa trên các tham số tìm kiếm.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Chi tiết đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.GeocodeOrderAddresses(System.Collections.Generic.List{System.Int32})">
            <summary>
            Lấy toạ độ cho các địa chỉ đơn hàng chưa được ghim, bằng cách gọi Google Geocoding
            rồi lưu lại vào CSDL. Bản đồ triển khai gọi endpoint này sau khi đã hiện các điểm
            gần đúng, nên độ trễ của Google không chặn việc hiển thị.
            </summary>
            <param name="addressIds">Danh sách Id của OrderAddress</param>
            <returns>Danh sách toạ độ lấy được (bỏ qua địa chỉ geocode thất bại)</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.ReorderOrders(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.ReorderModel)">
            <summary>
            Sắp xếp thứ tự hiển thị đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.GetLocations(Lada.Framework.Data.Enums.DeployType)">
            <summary>
            Lấy danh sách vị trí triển khai theo loại triển khai
            </summary>
            <param name="deployType">Loại triển khai: 1=Pickup, 2=Delivery, 3=Transit, 4=Return</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.GetOrders(Lada.Framework.Data.Enums.DeployType,Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy danh sách đơn hàng triển khai theo loại triển khai
            </summary>
            <param name="deployType">Loại triển khai: 1=Pickup, 2=Delivery, 3=Transit, 4=Return</param>
            <param name="param">Tham số bảng thông minh</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.Assign(Lada.Framework.Data.Enums.DeployType,Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel)">
            <summary>
            Gán đơn hàng cho nhân viên theo loại triển khai
            </summary>
            <param name="deployType">Loại triển khai: 1=Pickup, 2=Delivery, 3=Transit, 4=Return</param>
            <param name="model">Mô hình gán đơn hàng</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.SetOrderReturn(System.Collections.Generic.List{System.Int32},System.Nullable{System.Int32})">
            <summary>
            Cập nhật đơn hàng sang chiều trả về
            </summary>
            <param name="orderIds">Danh sách ID đơn hàng</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.DeployController.GetReturnAgencies">
            <summary>
            Lựa chọn "Bên phát hoàn" của hộp Trả về: chi nhánh LADA đang hoạt động (cùng role với Trả về — điều phối không có role màn chi nhánh).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Ops.OperationController">
            <summary>
            Controller để xử lý các hoạt động liên quan tới quy trình kinh doanh
            Các chức năng Pickup, Delivery đã được di chuyển sang DriverAppController
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.OperationController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Business.IOperationService,Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Ops.OperationController"/>.
            </summary>
            <param name="operationService">Dịch vụ xử lý các hoạt động.</param>
            <param name="userService">Dịch vụ xử lý người dùng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.OperationController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các hoạt động dựa trên các tham số được cung cấp.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.OperationController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của một hoạt động dựa trên ID.
            </summary>
            <param name="id">ID của hoạt động.</param>
            <returns>Thông tin chi tiết của hoạt động.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.OperationController.Pickup(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Operations.PickupModel)">
            <summary>
            Xử lý yêu cầu nhận hàng cho một hoạt động.
            </summary>
            <param name="model">Model chứa thông tin chi tiết của yêu cầu nhận hàng.</param>
            <returns>Kết quả của hoạt động nhận hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.OperationController.Delivery(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Operations.DeliveryModel)">
            <summary>
            Xử lý yêu cầu nhận hàng cho một hoạt động.
            </summary>
            <param name="model">Model chứa thông tin chi tiết của yêu cầu nhận hàng.</param>
            <returns>Kết quả của hoạt động nhận hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.RouteController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            T�m ki?m c�c tuy?n d?a tr�n tham s? SmartTableParam
            </summary>
            <param name="param">Tham s? t�m ki?m</param>
            <returns>Danh s�ch c�c tuy?n ph� h?p</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.RouteController.GetById(System.Int32)">
            <summary>
            L?y th�ng tin tuy?n theo ID
            </summary>
            <param name="id">ID c?a tuy?n</param>
            <returns>Th�ng tin c?a tuy?n</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.RouteController.Delete(System.Int32)">
            <summary>
            X�a tuy?n theo ID
            </summary>
            <param name="id">ID c?a tuy?n</param>
            <returns>K?t qu? x�a</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.RouteController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.RouteModel)">
            <summary>
            T?o ho?c c?p nh?t th�ng tin tuy?n
            </summary>
            <param name="routeModel">Th�ng tin c?a tuy?n</param>
            <returns>K?t qu? t?o ho?c c?p nh?t</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.GetCurrentAgencyHierarchyAsync">
            <summary>
            Lấy danh sách agencyIds thuộc chi nhánh hiện tại và con cháu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.GetAvailableTrucks">
            <summary>
            Lấy danh sách xe có thể nhận (chưa có người phụ trách)
            </summary>
            <returns>Danh sách xe có thể nhận</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.CheckInTruck(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckCheckInOutModel)">
            <summary>
            Nhận xe (Check-in) với upload hình ảnh
            </summary>
            <param name="model">Thông tin nhận xe</param>
            <returns>Kết quả nhận xe</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.CheckOutTruck(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckCheckInOutModel)">
            <summary>
            Trả xe (Check-out) với upload hình ảnh
            </summary>
            <param name="model">Thông tin trả xe</param>
            <returns>Kết quả trả xe</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel)">
            <summary>
            Tạo hoặc cập nhật thông tin xe tải
            </summary>
            <param name="model">Thông tin xe tải</param>
            <returns>Kết quả tạo hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.GetTruckByIds(Ladaer.BackEnd.Infrastructures.DTO.Models.KeyModels{System.Int32})">
            <summary>
            Lấy thông tin xe tải theo danh sách ID
            </summary>
            <param name="ids">Danh sách ID xe tải</param>
            <returns>Danh sách thông tin xe tải</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của một xe tải dựa trên ID.
            </summary>
            <param name="id">ID của xe tải.</param>
            <returns>Thông tin chi tiết của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.GetTruckMedia(System.Int32)">
            <summary>
            Lấy danh sách media (ảnh đăng ký, đăng kiểm) của xe tải
            </summary>
            <param name="truckId">ID xe tải</param>
            <returns>Danh sách media items</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.GetTruckByAgencyId(System.Int32)">
            <summary>
            Lấy thông tin xe tải theo ID đơn vị
            </summary>
            <param name="id">ID đơn vị</param>
            <returns>Danh sách thông tin xe tải</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm xe tải dựa trên tham số SmartTableParam
            </summary>
            <param name="model">Tham số tìm kiếm</param>
            <returns>Danh sách xe tải phù hợp</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckDelete(System.Int32)">
            <summary>
            Xóa xe tải
            </summary>
            <param name="id">ID xe tải cần xóa</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.GetTruckActivityHistory(System.Int32)">
            <summary>
            Lấy lịch sử giao nhận xe tải theo ID xe
            </summary>
            <param name="truckId">ID xe tải</param>
            <returns>Danh sách lịch sử giao nhận xe với thông tin ODO, ghi chú và ảnh</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckSpecGetAll(System.Int32)">
            <summary>
            Lấy tất cả thông số kỹ thuật của xe tải
            </summary>
            <param name="truckId">ID xe tải</param>
            <returns>Danh sách thông số kỹ thuật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckSpecCreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecificationModel)">
            <summary>
            Tạo hoặc cập nhật thông số kỹ thuật của xe tải
            </summary>
            <param name="model">Thông tin thông số kỹ thuật</param>
            <returns>Kết quả tạo hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckSpecDelete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecificationModel)">
            <summary>
            Xóa thông số kỹ thuật của xe tải
            </summary>
            <param name="model">Thông tin thông số kỹ thuật</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckSpecAttrSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm thuộc tính thông số kỹ thuật của xe tải
            </summary>
            <param name="model">Tham số tìm kiếm</param>
            <returns>Danh sách thuộc tính thông số kỹ thuật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckSpecAttrGetAll">
            <summary>
            Lấy tất cả thuộc tính thông số kỹ thuật của xe tải
            </summary>
            <returns>Danh sách thuộc tính thông số kỹ thuật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckSpecAttrCreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecAttributeModel)">
            <summary>
            Tạo hoặc cập nhật thuộc tính thông số kỹ thuật của xe tải
            </summary>
            <param name="model">Thông tin thuộc tính thông số kỹ thuật</param>
            <returns>Kết quả tạo hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckSpecAttrDelete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecAttributeModel)">
            <summary>
            Xóa thuộc tính thông số kỹ thuật của xe tải
            </summary>
            <param name="model">Thông tin thuộc tính thông số kỹ thuật</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckMaintAttrSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm thuộc tính bảo trì của xe tải
            </summary>
            <param name="model">Tham số tìm kiếm</param>
            <returns>Danh sách thuộc tính bảo trì</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckMaintAttrGetAll">
            <summary>
            Lấy tất cả thuộc tính bảo trì của xe tải
            </summary>
            <returns>Danh sách thuộc tính bảo trì</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckMaintAttrCreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintAttributeModel)">
            <summary>
            Tạo hoặc cập nhật thuộc tính bảo trì của xe tải
            </summary>
            <param name="model">Thông tin thuộc tính bảo trì</param>
            <returns>Kết quả tạo hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckMaintAttrDelete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintAttributeModel)">
            <summary>
            Xóa thuộc tính bảo trì của xe tải
            </summary>
            <param name="model">Thông tin thuộc tính bảo trì</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckMaintLinkGetAll(System.Int32)">
            <summary>
            Lấy tất cả liên kết bảo trì của xe tải
            </summary>
            <param name="truckMaintId">ID bảo trì xe tải</param>
            <returns>Danh sách liên kết bảo trì</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckMaintSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm bảo trì xe tải
            </summary>
            <param name="model">Tham số tìm kiếm</param>
            <returns>Danh sách bảo trì xe tải</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckMaintByIds(Ladaer.BackEnd.Infrastructures.DTO.Models.KeyModels{System.Int32})">
            <summary>
            Lấy thông tin bảo trì xe tải theo danh sách ID
            </summary>
            <param name="model">Danh sách ID bảo trì xe tải</param>
            <returns>Danh sách thông tin bảo trì xe tải</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckMaintCreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel)">
            <summary>
            Tạo hoặc cập nhật thông tin bảo trì xe tải
            </summary>
            <param name="model">Thông tin bảo trì xe tải</param>
            <returns>Kết quả tạo hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.TruckMaintDelete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintDeleteModel)">
            <summary>
            Xóa thông tin bảo trì xe tải
            </summary>
            <param name="model">Id của lần bảo dưỡng cần xoá</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.GetTrucksByAgency">
            <summary>
            Lấy danh sách tất cả xe tải thuộc chi nhánh của người dùng hiện tại
            </summary>
            <returns>Danh sách tất cả xe tải thuộc chi nhánh</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.FuelRefillTruck(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckFuelRefillModel)">
            <summary>
            Nạp dầu cho xe với upload hình ảnh và thông tin ODO
            </summary>
            <param name="model">Thông tin nạp dầu</param>
            <returns>Kết quả nạp dầu</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.GetTruckActivityByIds(Ladaer.BackEnd.Infrastructures.DTO.Models.KeyModels{System.Int32})">
            <summary>
            Lấy hoạt động xe tải theo danh sách ID
            </summary>
            <param name="ids">Danh sách ID hoạt động xe tải</param>
            <returns>Thông tin hoạt động xe tải</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.UpdateLastRefillOdo(System.Int32,System.Int32)">
            <summary>
            Cập nhật giá trị ODO đổ dầu gần nhất của xe tải
            </summary>
            <param name="truckId">ID xe tải</param>
            <param name="odoValue">Giá trị ODO</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckController.GetLastRefillOdo(System.Int32)">
            <summary>
            Lấy giá trị ODO đổ dầu gần nhất của xe tải
            </summary>
            <param name="truckId">ID xe tải</param>
            <returns>Giá trị ODO đổ dầu gần nhất</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController">
             <summary>
             API phân hệ bảo dưỡng xe tải: danh mục garage, danh mục loại bộ phận, bộ phận lắp trên xe.
            
             <para><b>Vì sao là controller riêng chứ không thêm vào <c>TruckController</c></b>: file đó đã 620 dòng
             và ôm cả xe, hoạt động, thông số kỹ thuật, bảo trì, đổ dầu. Phân hệ này còn thêm engine cảnh báo
             và API tình trạng đội xe ở GĐ B nên tách từ đầu.</para>
            
             <para><b>Tên role cố ý giữ tiền tố <c>Truck.*</c></b> thay vì <c>TruckMaintenance.*</c> theo tên controller:
             plan §3.4 đã chốt danh sách role và migration đã seed đúng danh sách đó. Role gom theo nhóm việc
             (<c>ComponentTypeManage</c>, <c>ComponentManage</c>) chứ không một-role-một-action, vì đây là danh mục
             quản trị dùng chung — ai sửa được thì cũng xem được.</para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Trucks.IGarageService,Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentTypeService,Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentService,Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckOdoService,Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceAgencyScopeResolver,Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckConditionService,Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentAlertService,Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckMaintenanceMediaService,Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceInvoiceReaderService,Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceSlipReaderService,Ladaer.BackEnd.Infrastructures.Services.Trucks.IComponentTypeAliasService,Ladaer.BackEnd.Infrastructures.Services.Identity.IUserRoleResolver)">
            <summary>
            Khởi tạo controller bảo dưỡng xe tải.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.GetCurrentScopeAsync">
            <summary>
            Dựng phạm vi chi nhánh của người dùng hiện tại.
            </summary>
            <remarks>
            Luật nằm trong <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceAgencyScopeResolver"/> vì <c>TruckController</c>
            cũng cần đúng luật này cho luồng lưu/xoá bảo dưỡng — hai bản sao của một luật phân quyền
            là hai chỗ để quên sửa một chỗ.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.GarageSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm garage.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.GarageGetAll(System.Boolean)">
            <summary>
            Lấy danh sách garage đang hoạt động (đổ vào ô chọn).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.GarageGetById(System.Int32)">
            <summary>
            Lấy chi tiết một garage.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.GarageCreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.GarageModel)">
            <summary>
            Tạo mới hoặc cập nhật garage.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.GarageDelete(System.Int32)">
            <summary>
            Xoá garage.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.ComponentTypeSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm loại bộ phận xe.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.ComponentTypeGetAll(System.Boolean)">
            <summary>
            Lấy danh sách loại bộ phận (đổ vào ô chọn).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.ComponentTypeGetById(System.Int32)">
            <summary>
            Lấy chi tiết một loại bộ phận.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.ComponentTypeCreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel)">
            <summary>
            Tạo mới hoặc cập nhật loại bộ phận.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.ComponentTypeDelete(System.Int32)">
            <summary>
            Xoá loại bộ phận.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.ComponentSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm bộ phận trên xe, trong phạm vi chi nhánh của người dùng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.ComponentGetByTruck(System.Int32,System.Boolean)">
            <summary>
            Lấy toàn bộ bộ phận của một xe.
            </summary>
            <remarks>
            Mở thêm cho người ghi bảo dưỡng vì form bảo dưỡng gọi nó khi chọn xe để gắn dòng phụ tùng vào bộ phận
            (QĐ3-11) — chỉ nới ĐỌC, gắn/sửa/xoá bộ phận vẫn chỉ <c>Truck.ComponentManage</c>; phạm vi chi nhánh giữ nguyên.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.ComponentGetById(System.Int32)">
            <summary>
            Lấy chi tiết một bộ phận.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.ComponentCreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentModel)">
            <summary>
            Gắn mới hoặc sửa bộ phận trên xe.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.ComponentInitForTruck(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentInitModel)">
            <summary>
            Khởi tạo bộ bộ phận hàng loạt cho một xe từ danh mục đang bật.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.ComponentDelete(System.Int32)">
            <summary>
            Xoá bộ phận trên xe.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.GetCurrentOdo(System.Int32)">
            <summary>
            Lấy chỉ số ODO hiện tại của một xe kèm thời điểm ghi nhận và nguồn dữ liệu.
            Chỉ trả về khi xe nằm trong phạm vi chi nhánh của người dùng.
            </summary>
            <remarks>
            Mở thêm cho người ghi bảo dưỡng vì form bảo dưỡng gọi nó khi chọn xe để điền sẵn ODO (QĐ3-11).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.FleetConditionSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Danh sách xe kèm ODO hiện tại và số bộ phận sắp/đã đến hạn — màn tình trạng đội xe.
            </summary>
            <remarks>
            Số cảnh báo tính trực tiếp bằng engine tại thời điểm gọi, không đọc bảng
            <c>TruckComponentAlert</c>: bảng đó do job nền ghi nên trước lượt quét đầu tiên còn rỗng,
            mà màn tình trạng phải đúng ngay khi vừa gắn bộ phận xong.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.TruckProfile(System.Int32)">
            <summary>
            Hồ sơ tình trạng một xe: ODO, lưới bộ phận kèm tỷ lệ tiêu hao và mức cảnh báo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.ComponentHistory(System.Int32)">
            <summary>
            Lịch sử các lần bảo dưỡng đã chạm tới một bộ phận: thay ở đâu, giá bao nhiêu, có hoá đơn không.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.AlertSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tra cứu cảnh báo do job nền sinh, lọc theo phạm vi chi nhánh của người dùng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.MaintenanceMedias(System.Int32)">
            <summary>
            Danh sách tệp đính kèm của một lần bảo dưỡng.
            </summary>
            <remarks>
            Role dùng lại nhóm <c>Truck.TruckMaint*</c> có sẵn của luồng bảo dưỡng vì tệp là một phần của
            bản ghi bảo dưỡng — ai xem/sửa được bản ghi thì xem/sửa được tệp. Phạm vi chi nhánh vẫn
            ép server-side theo xe đang gắn với bản ghi.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.MaintenanceMediaUpload(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceMediaUploadModel)">
            <summary>
            Tải tệp (multipart) lên và gắn vào lần bảo dưỡng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.MaintenanceMediaDelete(System.Int32)">
            <summary>
            Gỡ một tệp đính kèm khỏi lần bảo dưỡng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.MaintenanceInvoiceRead(System.Int32)">
            <summary>
            Đọc một hoá đơn đã đính kèm (PDF hoặc ảnh) và trả <b>gợi ý</b> số tiền / ngày / biển số cho form.
            </summary>
            <remarks>
            <para>Người dùng chủ động bấm "Đọc từ hoá đơn"; kết quả chỉ là gợi ý "máy đọc — kiểm lại", không tự
            điền, không ghi gì vào DB. Tệp đọc lại từ đĩa theo bản ghi đính kèm — không nhận tệp tải lên ở đây,
            nên không có endpoint "OCR chung" cho file tuỳ ý (plan trích-xuất-văn-bản §3.5).</para>
            <para>Role: người sửa được bản ghi bảo dưỡng mới cần gợi ý để điền form. Phạm vi chi nhánh ép server-side
            theo xe gắn với bản ghi. POST vì là thao tác tốn CPU (OCR 1–2,5 giây), không để proxy/trình duyệt cache.</para>
            </remarks>
            <param name="mediaLinkId">Id dòng đính kèm (<c>TruckMaintenanceMediaItem.Id</c>), loại hoá đơn.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.AiNavPermissions">
            <summary>
            Cờ hiển thị phần "Đọc phiếu bằng AI" của form bảo dưỡng (rule <c>quyen-hien-thi</c>).
            </summary>
            <remarks>
            KHÔNG đòi role: câu "tôi được thấy gì" phải trả lời được cho cả người không có quyền nào (họ nhận toàn
            <c>false</c>). Mỗi cờ đọc đúng bó role trên <c>[Authorize]</c> của endpoint nó gác — test reflection khoá.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.SlipRead(System.Int32)">
            <summary>
            Đọc một hoá đơn / phiếu đã đính kèm bằng AI và trả <b>gợi ý</b> tiêu đề + từng dòng khớp danh mục.
            </summary>
            <remarks>
            Gợi ý, không ghi gì ngoài nhật ký đọc. Phạm vi chi nhánh theo xe của bản ghi; ngoài phạm vi trả cùng câu
            "không tìm thấy". AI lỗi thì máy chủ tự chuyển sang OCR cũ (<c>Mode = Offline</c>).
            </remarks>
            <param name="mediaLinkId">Id dòng đính kèm loại hoá đơn.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.SlipReadUpload(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.MaintenanceSlipUploadModel)">
            <summary>
            Đọc tệp phiếu tải thẳng lúc TẠO MỚI bản ghi (QĐ3-3). Tệp chỉ được đọc rồi bỏ — lưu bản ghi xong giao diện
            mới tải nó lên làm media và gọi <c>SlipReading/{id}/Attach</c>.
            </summary>
            <remarks>Trần 15 MB kiểm TRƯỚC khi đọc vào bộ nhớ (§3.11); xe phải thuộc phạm vi chi nhánh của người gọi.</remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.SlipReadingRematch(System.Int32)">
            <summary>Chạy lại so khớp (không gửi lại ảnh) sau khi danh mục / alias vừa đổi. Có trần số lần.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.SlipReadingGet(System.Int32)">
            <summary>Mở lại gợi ý của một lượt đọc trong phạm vi chi nhánh.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.SlipReadingAttach(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.MaintenanceSlipAttachModel)">
            <summary>Gắn lượt đọc lúc tạo mới vào bản ghi vừa lưu (và dòng media vừa tải lên).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.ComponentTypeAliasGetAll(System.Nullable{System.Int32})">
            <summary>Danh sách tên gọi khác của loại bộ phận K200.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.ComponentTypeAliasCreate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeAliasModel)">
            <summary>Ghi nhớ "tên trên phiếu = loại bộ phận" — danh mục dùng chung nên đòi role quản lý danh mục.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Ops.TruckMaintenanceController.ComponentTypeAliasDelete(System.Int32)">
            <summary>Gỡ một tên gọi khác.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.DriverApp.DriverAttendanceController">
            <summary>
            API chấm công dành cho ứng dụng lái xe (DriverApp).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverAttendanceController.SearchMyAttendance(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tra cứu lịch sử chấm công của chính lái xe đang đăng nhập (có phân trang).
            UserId được lấy từ token và ép ở tầng service, không đọc từ client.
            </summary>
            <param name="param">Tham số SmartTableParam (Pagination bắt buộc; lọc khoảng ngày qua Search.PredicateObject.CheckInStart/CheckInEnd).</param>
            <returns>Danh sách ca chấm công của lái xe hiện tại.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverDashboardController.GetDashboard">
            <summary>
            Lấy thông tin dashboard cho ứng dụng tài xế
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverFinanceController.GetFinancialInfo">
            <summary>
            Lấy thông tin tài chính của lái xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverFinanceController.SearchFinancialOrders(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh sách đơn hàng tài chính của lái xe có phân trang
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverFinanceController.CreateTransferSlip(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateDriverTransferSlipModel)">
            <summary>
            Lái xe tạo phiếu chuyển tiền (upload ảnh chuyển khoản)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverFinanceController.MyPendingSlip">
            <summary>
            Lái xe xem phiếu đang chờ duyệt
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverFinanceController.CancelSlip(System.Int32)">
            <summary>
            Lái xe hủy phiếu chuyển tiền
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverFinanceController.GetDepositBankAccount(System.Nullable{System.Decimal},System.String)">
            <summary>
            Lấy thông tin tài khoản ngân hàng để nộp tiền (QR code VietQR)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverOrderController.SearchOrders(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh sách đơn hàng của lái xe có phân trang
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverOrderController.SearchActiveOrders(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm đơn hàng đang hoạt động (đang lấy, lấy thất bại, đang giao, giao thất bại)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverOrderController.GetOrder(System.Int32)">
            <summary>
            Lấy thông tin chi tiết đơn hàng theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverOrderController.ReorderOrders(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.ReorderModel)">
            <summary>
            Sắp xếp thứ tự hiển thị đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverOrderOpsController.Pickup(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppPickupModel)">
            <summary>
            Cập nhật trạng thái lấy hàng thành công
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverOrderOpsController.PickupFail(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailModel)">
            <summary>
            Cập nhật trạng thái lấy hàng thất bại
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverOrderOpsController.Delivery(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppDeliveryModel)">
            <summary>
            Cập nhật trạng thái giao hàng thành công
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverOrderOpsController.DeliveryFail(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailModel)">
            <summary>
            Cập nhật trạng thái giao hàng thất bại
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverOrderOpsController.Return(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppReturnModel)">
            <summary>
            Cập nhật trạng thái trả hàng thành công
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverOrderOpsController.ReturnFail(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailModel)">
            <summary>
            Cập nhật trạng thái trả hàng thất bại
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverOrderOpsController.GetFailReasons(System.Int32)">
            <summary>
            Lấy danh sách lý do thất bại theo loại (Pickup/Delivery)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverProfileController.Login(Ladaer.BackEnd.Infrastructures.DTO.Models.Accounts.LoginModel)">
            <summary>
            Đăng nhập dành cho tài xế
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverProfileController.ChangePassword(Ladaer.BackEnd.Infrastructures.DTO.Models.Users.ChangePasswordModel)">
            <summary>
            Đổi mật khẩu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverProfileController.RefreshToken(Ladaer.BackEnd.Infrastructures.DTO.Models.Accounts.RefreshTokenModel)">
            <summary>
            Gia hạn đăng nhập (Refresh Token)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverProfileController.UpdateProfile(Ladaer.BackEnd.Infrastructures.DTO.Models.Users.StaffModel)">
            <summary>
            Cập nhật thông tin profile
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverProfileController.Attendance(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CheckInOutModel)">
            <summary>
            Chấm công (Check-in/Check-out)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverProfileController.GetPayroll(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy bảng lương (Dựa trên báo cáo năng suất)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverTruckController.GetTrucksByAgency">
            <summary>
            Lấy danh sách tất cả xe tải thuộc chi nhánh của người dùng hiện tại
            </summary>
            <returns>Danh sách tất cả xe tải thuộc chi nhánh</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverTruckController.GetAvailableTrucks">
            <summary>
            Lấy danh sách xe tải có thể nhận (chưa có người phụ trách) thuộc chi nhánh
            </summary>
            <returns>Danh sách xe tải có thể nhận</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverTruckController.CheckInTruck(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckCheckInOutModel)">
            <summary>
            Nhận xe (Check-in) với upload hình ảnh
            </summary>
            <param name="model">Thông tin nhận xe</param>
            <returns>Kết quả nhận xe</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverTruckController.CheckOutTruck(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckCheckInOutModel)">
            <summary>
            Trả xe (Check-out) với upload hình ảnh
            </summary>
            <param name="model">Thông tin trả xe</param>
            <returns>Kết quả trả xe</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverTruckController.DriverFuelRefill(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel)">
            <summary>
            Đổ dầu cho lái xe trên app mobile.
            Lái xe là người đang đăng nhập, xe là xe đang phụ trách (tự động xác định).
            Có thể chọn thẻ dầu hoặc đổ bằng tiền mặt, không cần chọn giao dịch.
            </summary>
            <param name="model">Thông tin đổ dầu</param>
            <returns>Kết quả đổ dầu</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverTruckController.ResubmitFuelRefill(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel)">
            <summary>
            Lái xe chỉnh sửa và gửi lại phiếu đổ dầu bị từ chối
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverTruckController.DeleteFuelRefill(System.Int32)">
            <summary>
            Lái xe xóa phiếu đổ dầu (chỉ khi Pending hoặc Rejected)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverTruckController.SearchRefillHistory(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lịch sử đổ dầu của lái xe (phân trang, lọc theo ngày và từ khóa)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverTruckController.GetMyCurrentTruck">
            <summary>
            Kiểm tra xe hiện tại của người dùng
            </summary>
            <returns>Thông tin xe hiện tại</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverTruckController.GetMyFuelCard">
            <summary>
            Lấy thẻ xăng dầu mà lái xe đang được gán (bao gồm PendingAccept và Received)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverTruckController.GetCardByQrCode(System.String)">
            <summary>
            Lấy thông tin thẻ xăng dầu theo QR Code
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverTruckController.ConfirmReceiveFuelCard(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.ConfirmReceiveFuelCardModel)">
            <summary>
            Lái xe xác nhận nhận thẻ xăng dầu (kèm ảnh minh chứng)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverTruckController.ReturnFuelCard(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.ReturnFuelCardModel)">
            <summary>
            Lái xe trả thẻ xăng dầu (kèm ảnh minh chứng)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.DriverTruckController.MyTruckCondition">
            <summary>
            Tình trạng bảo dưỡng của xe lái xe đang nhận: ODO hiện tại và danh sách bộ phận kèm tỷ lệ
            tiêu hao, cái nào sắp đến hạn.
            </summary>
            <remarks>
            <b>Không nhận <c>truckId</c> từ client.</b> Xe xác định từ token qua
            <c>Truck.CurrentDriverId</c> — cho phép truyền id là cho tài xế xem xe của người khác.
            Chưa nhận xe thì trả 404 kèm thông báo, không trả rỗng lặng lẽ.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.DriverApp.TtsController">
            <summary>
            Giọng đọc dẫn đường cho app lái xe (đợt dẫn đường DriverApp, GĐ D2 — plan §3.5.6, §3.11; đợt tự host
            2026-09-28 — memory <c>project-tts-tu-host</c>).
            </summary>
            <remarks>
            Gác bằng role SẴN CÓ <c>DriverApp.SearchActiveOrders</c> (danh sách đơn đang trên đường của app
            lái xe): mọi lối vào màn dẫn đường đều đi qua danh sách đó, nên ai tới được nút loa đều có role
            này — không cần cờ ẩn nút (rule <c>quyen-hien-thi</c>). Role riêng <c>Tts.Batch</c> cần migration
            seed cho nhóm lái xe — ngoài phạm vi D2 (DD-42). Chỉ <c>[Authorize]</c> trơn thì bất kỳ tài khoản
            nhân viên nào (kể cả bị lộ) cũng tiêu được trần ký tự toàn server (/code-review D2). Chặn tiếp
            bằng trần ký tự câu mới theo người + toàn server trong <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsCacheService"/>.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.DriverApp.TtsController.DriverRole">
            <summary>Role gác endpoint — mượn của danh sách đơn đang trên đường (xem remarks).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.DriverApp.TtsController.OperatorRole">
            <summary>Role gác endpoint trạng thái — người vận hành cấu hình hệ thống (cùng role với ReloadCache của AppConfig).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.TtsController.Batch(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchModel,System.Threading.CancellationToken)">
            <summary>
            Bảo đảm các câu chỉ dẫn có âm thanh; trả bytes (base64) của câu app chưa có.
            </summary>
            <remarks>
            400 khi số câu ngoài 1…60 (<c>ErrorCode = "Invalid"</c>; câu sai LẺ chỉ hỏng dòng của nó);
            503 khi máy chủ chưa có khoá nguồn giọng (<c>"NotConfigured"</c>); còn lại 200 — kể cả khi
            nguồn lỗi hay hết token: lúc đó <c>Result = Failed</c> kèm <c>ErrorCode</c>, những câu đã có vẫn
            trả về dùng được. Câu chưa có ở nguồn tự host mang <c>"Pending"</c> riêng dòng, lượt vẫn Success.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.DriverApp.TtsController.Status(System.Threading.CancellationToken)">
            <summary>
            Trạng thái gateway cho người vận hành: nguồn đang chọn, năm khoá AppConfig đã nạp (khoá che),
            thăm dò sidecar, và một lượt tổng hợp thử qua đúng đường app đi.
            </summary>
            <remarks>
            Có vì backend production chỉ ghi log ra console (IIS không giữ): "app không tải được giọng" mà
            không có cách nào biết hỏng ở AppConfig, khoá, mạng tới sidecar hay nguồn. Lượt thử tính vào trần
            ký tự của người gọi (50 ký tự) — gọi tay vài lần không đáng kể.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Email.EmailAccountController">
            <summary>
            Controller quản lý tài khoản gửi email (SMTP/SES) — cấu hình động, có mã hóa secret.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Email.EmailAccountController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Lấy danh sách tài khoản gửi email.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Email.EmailAccountController.GetById(System.Int32)">
            <summary>Lấy chi tiết tài khoản gửi email theo ID (không trả secret thật).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Email.EmailAccountController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Email.EmailAccountModel)">
            <summary>Tạo mới hoặc cập nhật tài khoản gửi email.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Email.EmailAccountController.Delete(System.Int32)">
            <summary>Xóa (mềm) tài khoản gửi email.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Email.EmailAccountController.SetAsDefault(System.Int32)">
            <summary>Đặt tài khoản gửi làm mặc định (chỉ 1 mặc định toàn hệ thống).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Email.EmailAccountController.TestSend(Ladaer.BackEnd.Infrastructures.DTO.Models.Email.EmailTestSendModel)">
            <summary>Gửi email thử để kiểm tra cấu hình tài khoản.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Email.EmailLogController">
            <summary>
            Controller nhật ký + báo cáo gửi email (chỉ đọc).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Email.EmailLogController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách nhật ký gửi email (lọc theo trạng thái/người nhận/khoảng ngày).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Email.EmailLogController.GetById(System.Guid)">
            <summary>Chi tiết 1 dòng nhật ký gửi email.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Email.EmailLogController.GetSummary(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Báo cáo tổng hợp gửi email (tổng/thành công/thất bại) theo khoảng ngày.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.BankAccountController">
            <summary>
            Controller quản lý tài khoản ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankAccountController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm tài khoản ngân hàng
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Danh sách tài khoản ngân hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankAccountController.GetById(System.Int32)">
            <summary>
            Lấy chi tiết tài khoản ngân hàng
            </summary>
            <param name="id">ID tài khoản ngân hàng</param>
            <returns>Chi tiết tài khoản ngân hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankAccountController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountModel)">
            <summary>
            Tạo hoặc cập nhật tài khoản ngân hàng
            </summary>
            <param name="model">Thông tin tài khoản ngân hàng</param>
            <returns>Kết quả thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankAccountController.Delete(System.Int32)">
            <summary>
            Xóa tài khoản ngân hàng
            </summary>
            <param name="id">ID tài khoản ngân hàng</param>
            <returns>Kết quả thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankAccountController.ImportStatement(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportModel)">
            <summary>
            Import sao kê ngân hàng từ file Excel
            </summary>
            <param name="model">Thông tin import</param>
            <returns>Kết quả import</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankAccountController.SearchTransactions(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm giao dịch ngân hàng
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Danh sách giao dịch</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankAccountController.GetActiveAccounts">
            <summary>
            Lấy danh sách tài khoản ngân hàng đang hoạt động
            </summary>
            <returns>Danh sách tài khoản đang hoạt động</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankAccountController.SearchImportHistory(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm lịch sử import sao kê
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Danh sách lịch sử import</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankAccountController.UpdateBalance(Ladaer.BackEnd.Controllers.Finance.UpdateBalanceModel)">
            <summary>
            Cập nhật số dư tài khoản
            </summary>
            <param name="accountId">ID tài khoản</param>
            <param name="newBalance">Số dư mới</param>
            <returns>Kết quả thao tác</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.UpdateBalanceModel">
            <summary>
            Model cập nhật số dư
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Finance.UpdateBalanceModel.AccountId">
            <summary>
            ID tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Finance.UpdateBalanceModel.NewBalance">
            <summary>
            Số dư mới
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.BankController">
            <summary>
            Controller quản lý thông tin ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm ngân hàng với phân trang
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankController.GetAll">
            <summary>
            Lấy danh sách tất cả ngân hàng đang hoạt động
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankController.InitializeBankData">
            <summary>
            Khởi tạo dữ liệu ngân hàng mẫu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankController.GetById(System.Int32)">
            <summary>
            Lấy thông tin ngân hàng theo ID (trả về model để edit)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.BankModel)">
            <summary>
            Tạo hoặc cập nhật thông tin ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankController.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.BankModel)">
            <summary>
            Tạo ngân hàng mới
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankController.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.BankModel)">
            <summary>
            Cập nhật thông tin ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankController.Delete(System.Int32)">
            <summary>
            Xóa ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.BankController.SugBank(System.String,System.Int32)">
            <summary>
            Gợi ý ngân hàng theo từ khóa (cho select option)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.CashierController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm quỹ 
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.CashierController.CollectCashier(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CollectCashierModel)">
            <summary>
            Thu tiền
            </summary>
            <param name="model">Model chứa thông tin thu tiền.</param>
            <returns>Kết quả của hoạt động thu tiền.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.CashierController.GetOrders(System.Int32)">
            <summary>
            Lấy danh sách hóa đơn
            </summary>
            <param name="userId">ID của người dùng.</param>
            <returns>Danh sách hóa đơn.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ChartOfAccountController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm tài khoản
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ChartOfAccountController.GetById(System.Int32)">
            <summary>
            Lấy tài khoản theo ID
            </summary>
            <param name="id">ID của tài khoản.</param>
            <returns>Thông tin tài khoản.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ChartOfAccountController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ChartOfAccountModel)">
            <summary>
            Tạo hoặc cập nhật tài khoản
            </summary>
            <param name="model">Model chứa thông tin tài khoản cần tạo/cập nhật.</param>
            <returns>Kết quả của hoạt động tạo/cập nhật tài khoản.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ChartOfAccountController.Delete(System.Int32)">
            <summary>
            Xóa tài khoản
            </summary>
            <param name="id">ID của tài khoản cần xóa.</param>
            <returns>Kết quả của hoạt động xóa tài khoản.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ChartOfAccountController.SeedData">
            <summary>
            Seed dữ liệu tài khoản
            </summary>
            <returns>Kết quả của hoạt động seed dữ liệu tài khoản.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.CustomerReconciliationSlipController.GetCustomersOverview(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy danh sách khách hàng cần đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.CustomerReconciliationSlipController.GetReconciliableOrders(System.Int32)">
            <summary>
            Lấy danh sách đơn hàng có thể đối soát của khách hàng
            </summary>
        </member>
        <!-- Badly formed XML comment ignored for member "M:Ladaer.BackEnd.Controllers.Finance.CustomerReconciliationSlipController.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateCustomerReconciliationSlipModel)" -->
        <member name="M:Ladaer.BackEnd.Controllers.Finance.CustomerReconciliationSlipController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.CustomerReconciliationSlipController.GetById(System.Int32)">
            <summary>
            Lấy chi tiết phiếu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.CustomerReconciliationSlipController.Approve(System.Int32)">
            <summary>
            Duyệt phiếu (Kế toán)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.CustomerReconciliationSlipController.Reject(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.RejectCustomerReconciliationSlipModel)">
            <summary>
            Từ chối phiếu (Kế toán)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.CustomerReconciliationSlipController.Complete(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CompleteCustomerReconciliationSlipModel)">
            <summary>
            Hoàn thành phiếu (Xác nhận thanh toán)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.CustomerReconciliationSlipController.GetLogs(System.Int32)">
            <summary>
            Lấy lịch sử thao tác
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.CustomerReconciliationSlipController.UploadProofImages(System.Int32,System.Collections.Generic.List{Microsoft.AspNetCore.Http.IFormFile})">
            <summary>
            Upload ảnh chứng từ cho phiếu đối soát
            </summary>
            <param name="id">ID phiếu đối soát</param>
            <param name="files">Danh sách ảnh chứng từ (1-3 ảnh)</param>
            <returns>Kết quả upload</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.CustomerReconciliationSlipController.ExportExcel(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel)">
            <summary>
            Xuất Excel danh sách phiếu đối soát khách hàng
            </summary>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.CustomerReconciliationSlipController.ExportExcelDetail(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel)">
            <summary>
            Xuất Excel chi tiết phiếu đối soát khách hàng
            </summary>
            <param name="slipId">ID phiếu đối soát</param>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.CustomerReconciliationSlipController.ExportReconciliableOrders(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel)">
            <summary>
            Xuất Excel danh sách đơn hàng cần đối soát của khách hàng
            </summary>
            <param name="customerId">ID khách hàng</param>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.DriverTransferSlipController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm phiếu chuyển tiền lái xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.DriverTransferSlipController.GetById(System.Int32)">
            <summary>
            Chi tiết phiếu chuyển tiền
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.DriverTransferSlipController.Approve(System.Int32)">
            <summary>
            Duyệt phiếu chuyển tiền
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.DriverTransferSlipController.Reject(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.RejectDriverTransferSlipModel)">
            <summary>
            Từ chối phiếu chuyển tiền
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.ExpenseCategoryController">
            <summary>
            Controller quản lý danh mục chi phí
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseCategoryController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh mục chi phí với phân trang
            </summary>
            <param name="param">Tham số tìm kiếm và phân trang</param>
            <returns>Danh sách danh mục chi phí</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseCategoryController.GetById(System.Int32)">
            <summary>
            Lấy danh mục chi phí theo ID
            </summary>
            <param name="id">ID danh mục chi phí</param>
            <returns>Thông tin danh mục chi phí</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseCategoryController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExpenseCategoryModel)">
            <summary>
            Tạo hoặc cập nhật danh mục chi phí
            </summary>
            <param name="model">Thông tin danh mục chi phí</param>
            <returns>Kết quả tạo hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseCategoryController.Delete(System.Int32)">
            <summary>
            Xóa danh mục chi phí
            </summary>
            <param name="id">ID danh mục chi phí</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseCategoryController.GetAll">
            <summary>
            Lấy danh sách tất cả danh mục chi phí (cho dropdown)
            </summary>
            <returns>Danh sách danh mục chi phí</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseCategoryController.CheckNameExists(System.String,System.Int32)">
            <summary>
            Kiểm tra tên danh mục có trùng không
            </summary>
            <param name="name">Tên danh mục</param>
            <param name="excludeId">ID loại trừ (khi update)</param>
            <returns>True nếu tên đã tồn tại</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseCategoryController.GetHierarchy">
            <summary>
            Lấy danh sách danh mục chi phí theo cây phân cấp
            </summary>
            <returns>Danh sách danh mục chi phí theo cây phân cấp</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseCategoryController.GetRootCategories">
            <summary>
            Lấy danh sách danh mục gốc (không có ParentId)
            </summary>
            <returns>Danh sách danh mục gốc</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseCategoryController.GetChildren(System.Int32)">
            <summary>
            Lấy danh sách danh mục con theo ParentId
            </summary>
            <param name="parentId">ID danh mục cha</param>
            <returns>Danh sách danh mục con</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseCategoryController.CanDelete(System.Int32)">
            <summary>
            Kiểm tra có thể xóa danh mục không (không có danh mục con)
            </summary>
            <param name="id">ID danh mục</param>
            <returns>True nếu có thể xóa</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.ExpenseController">
            <summary>
            Controller quản lý chi phí
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm chi phí với phân trang
            </summary>
            <param name="param">Tham số tìm kiếm và phân trang</param>
            <returns>Danh sách chi phí</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseController.GetById(System.Guid)">
            <summary>
            Lấy chi phí theo ID
            </summary>
            <param name="id">ID chi phí</param>
            <returns>Thông tin chi phí</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseModel)">
            <summary>
            Tạo hoặc cập nhật chi phí
            </summary>
            <param name="model">Thông tin chi phí</param>
            <returns>Kết quả tạo hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseController.Approve(System.Guid)">
            <summary>
            Duyệt chi phí
            </summary>
            <param name="id">ID chi phí</param>
            <returns>Kết quả duyệt</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseController.Unapprove(System.Guid)">
            <summary>
            Bỏ duyệt chi phí (chuyển về trạng thái chờ duyệt)
            </summary>
            <param name="id">ID chi phí</param>
            <returns>Kết quả bỏ duyệt</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseController.Reject(System.Guid,Ladaer.BackEnd.Controllers.Finance.RejectExpenseRequest)">
            <summary>
            Từ chối chi phí
            </summary>
            <param name="id">ID chi phí</param>
            <param name="request">Thông tin từ chối</param>
            <returns>Kết quả từ chối</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseController.MarkAsPaid(System.Guid,Ladaer.BackEnd.Controllers.Finance.MarkAsPaidExpenseRequest)">
            <summary>
            Đánh dấu chi phí đã chuyển tiền
            </summary>
            <param name="id">ID chi phí</param>
            <param name="request">Thông tin chuyển tiền</param>
            <returns>Kết quả đánh dấu chuyển tiền</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseController.Delete(System.Guid)">
            <summary>
            Xóa chi phí
            </summary>
            <param name="id">ID chi phí</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExpenseController.BatchApprove(Ladaer.BackEnd.Controllers.Finance.BatchApproveExpenseRequest)">
            <summary>
            Duyệt hàng loạt chi phí (chỉ dành cho Founder)
            </summary>
            <param name="request">Danh sách ID chi phí cần duyệt</param>
            <returns>Kết quả duyệt hàng loạt</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.RejectExpenseRequest">
            <summary>
            Request model cho việc từ chối chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Finance.RejectExpenseRequest.RejectReason">
            <summary>
            Lý do từ chối (bắt buộc)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.MarkAsPaidExpenseRequest">
            <summary>
            Request model cho việc đánh dấu chi phí đã chuyển tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Finance.MarkAsPaidExpenseRequest.Note">
            <summary>
            Ghi chú cho giao dịch chuyển tiền
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.BatchApproveExpenseRequest">
            <summary>
            Request model cho việc duyệt hàng loạt chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Finance.BatchApproveExpenseRequest.Ids">
            <summary>
            Danh sách ID chi phí cần duyệt
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.ExportOrderController">
            <summary>
            Controller cho việc xuất Excel thông tin đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExportOrderController.ExportOrders(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExportOrderModel)">
            <summary>
            Xuất Excel thông tin đơn hàng theo danh sách OrderId hoặc OrderCode
            </summary>
            <param name="model">Thông tin đầu vào</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExportOrderController.ExportOrdersByIds(System.Collections.Generic.List{System.Int32})">
            <summary>
            Xuất Excel thông tin đơn hàng theo danh sách OrderId
            </summary>
            <param name="orderIds">Danh sách ID đơn hàng</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExportOrderController.ExportOrdersByCodes(System.Collections.Generic.List{System.String})">
            <summary>
            Xuất Excel thông tin đơn hàng theo danh sách OrderCode
            </summary>
            <param name="orderCodes">Danh sách mã đơn hàng</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExportOrderController.DownloadFile(System.String)">
            <summary>
            Download file Excel đã xuất
            </summary>
            <param name="fileName">Tên file</param>
            <returns>File Excel</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ExportOrderController.GetExportedFiles">
            <summary>
            Lấy danh sách file Excel đã xuất
            </summary>
            <returns>Danh sách file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FinanceDashboardController.GetSummary">
            <summary>
            Lấy dữ liệu tổng quan tài chính
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FinanceDashboardController.GetFinancialHealthOverview">
            <summary>
            Tổng quan tình hình tài chính — Financial Health Overview
            Tổng hợp 12 KPIs: Profitability (5) + Liquidity (5) + Franchise (2)
            Bám theo Section 4 - LADA_Franchise_Finance_Plan.md
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FinanceDashboardController.GetCashFlowForecast">
            <summary>
            Dự báo dòng tiền 13 tuần tới
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.FinanceExcelExportController">
            <summary>
            Controller tổng hợp cho việc xuất Excel các phiếu tài chính
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FinanceExcelExportController.ExportReconciliations(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel)">
            <summary>
            Xuất Excel danh sách phiếu đối soát
            </summary>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FinanceExcelExportController.ExportReconciliationDetail(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel)">
            <summary>
            Xuất Excel chi tiết phiếu đối soát
            </summary>
            <param name="reconciliationId">ID phiếu đối soát</param>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FinanceExcelExportController.ExportTransferPaymentBills(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel)">
            <summary>
            Xuất Excel danh sách phiếu chuyển khoản
            </summary>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FinanceExcelExportController.ExportTransferPaymentBillDetail(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel)">
            <summary>
            Xuất Excel chi tiết phiếu chuyển khoản
            </summary>
            <param name="transferPaymentBillId">ID phiếu chuyển khoản</param>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FinanceExcelExportController.ExportCustomerTransferableOrdersExcel(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersExcelExportModel)">
            <summary>
            Xuất Excel danh sách đơn hàng nợ cước của khách hàng
            </summary>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FinanceExcelExportController.DownloadFile(System.String)">
            <summary>
            Download file Excel đã xuất
            </summary>
            <param name="fileName">Tên file</param>
            <returns>File Excel</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FinanceExcelExportController.GetExportedFiles">
            <summary>
            Lấy danh sách file Excel đã xuất
            </summary>
            <returns>Danh sách file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FinanceExcelExportController.DeleteFile(System.String)">
            <summary>
            Xóa file Excel đã xuất
            </summary>
            <param name="fileName">Tên file</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FinanceExcelExportController.GetFileType(System.String)">
            <summary>
            Xác định loại file dựa trên thư mục
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.FuelCardController">
            <summary>
            Controller quản lý thẻ xăng dầu (thẻ tín dụng), đổ dầu và thanh toán tiền dầu khoán
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm thẻ xăng dầu với phân trang
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.GetById(System.Int32)">
            <summary>
            Lấy thông tin thẻ xăng dầu theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.GetHistory(System.Int32)">
            <summary>
            Lấy lịch sử thẻ xăng dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardModel)">
            <summary>
            Tạo hoặc cập nhật thẻ xăng dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.Delete(System.Int32)">
            <summary>
            Xóa thẻ xăng dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.SugFuelCard(System.String)">
            <summary>
            Lấy danh sách thẻ đang hoạt động
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.GetTotalDebt">
            <summary>
            Lấy tổng nợ thẻ tín dụng (cho báo cáo)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.ImportStatement(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionImportModel)">
            <summary>
            Import sao kê thẻ tín dụng từ Excel
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.ImportTransactionHistory(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionHistoryImportModel)">
            <summary>
            Import lịch sử giao dịch thẻ xăng dầu từ file Excel.
            File Excel phải có cột "Tài khoản thẻ/ Số thẻ" để hệ thống ánh xạ với thẻ tương ứng.
            Hệ thống sẽ tự động tìm thẻ dựa vào số thẻ trong file và tạo giao dịch tương ứng.
            </summary>
            <remarks>
            Các cột được hỗ trợ trong file Excel:
            - Tài khoản thẻ / Số thẻ (bắt buộc): Số thẻ tín dụng để mapping
            - Ngày giao dịch: Định dạng dd/MM/yyyy hoặc dd/MM/yyyy HH:mm
            - Số tiền: Số tiền giao dịch (hỗ trợ định dạng 1.234.567 hoặc 1,234,567)
            - Loại tiền: VND, USD...
            - Loại giao dịch: Retail, Refund...
            - Địa điểm: Nơi giao dịch
            - Tình trạng: Thành công, Chờ xử lý...
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.SearchTransactions(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Nullable{System.Int32})">
            <summary>
            Tìm kiếm giao dịch thẻ
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.GetTransactionById(System.Guid)">
            <summary>
            Lấy chi tiết giao dịch thẻ
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.ReconcileTransaction(System.Guid,System.Int32)">
            <summary>
            Đối soát giao dịch thẻ với lần đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.MarkTransactionPaid(System.Guid)">
            <summary>
            Đánh dấu giao dịch đã thanh toán cho ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.GetUnreconciledTransactions(System.Int32,System.DateTimeOffset)">
            <summary>
            Lấy danh sách giao dịch chưa đối soát theo thẻ và ngày
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.BulkDeleteTransactions(System.Collections.Generic.List{System.Guid})">
            <summary>
            Xóa nhiều giao dịch thẻ cùng lúc
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.CreateOrUpdateRefill(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel)">
            <summary>
            Tạo hoặc cập nhật thông tin đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.SearchRefills(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm lịch sử đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.GetRefillById(System.Int32)">
            <summary>
            Lấy chi tiết lần đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.GetRefillsByTruck(System.Int32)">
            <summary>
            Lấy lịch sử đổ dầu theo xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.GetRefillsByDriver(System.Int32)">
            <summary>
            Lấy lịch sử đổ dầu theo lái xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.DeleteRefill(System.Int32)">
            <summary>
            Xóa bản ghi đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.ApproveRefill(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillApproveModel)">
            <summary>
            Duyệt phiếu đổ dầu (nếu đổ bằng thẻ, bắt buộc chọn giao dịch thẻ xăng)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.RejectRefill(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillRejectModel)">
            <summary>
            Từ chối phiếu đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.UnapproveRefill(System.Int32)">
            <summary>
            Bỏ duyệt phiếu đổ dầu đã duyệt (chưa chốt lương): đưa về chờ duyệt, gỡ đối soát giao dịch thẻ
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.RefillNavPermissions">
            <summary>
            Cờ hiển thị nút Duyệt / Từ chối / Bỏ duyệt / Cập nhật / Xóa / Xuất Excel của màn Lịch sử đổ dầu cho người đang đăng nhập
            </summary>
            <remarks>
            Cố ý không đòi role nào (chỉ cần đăng nhập): người không có quyền vẫn phải hỏi được và nhận toàn
            <c>false</c> để giao diện ẩn nút. Luật nằm ở hàm thuần <see cref="T:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillNavPermissions"/>.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.FuelCardController.ExportRefillsExcel(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Xuất Excel lịch sử đổ dầu
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.IncomeCategoryController">
            <summary>
            Controller quản lý danh mục doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeCategoryController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh mục doanh thu với phân trang
            </summary>
            <param name="param">Tham số tìm kiếm và phân trang</param>
            <returns>Danh sách danh mục doanh thu</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeCategoryController.GetById(System.Int32)">
            <summary>
            Lấy danh mục doanh thu theo ID
            </summary>
            <param name="id">ID danh mục doanh thu</param>
            <returns>Thông tin danh mục doanh thu</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeCategoryController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeCategoryModel)">
            <summary>
            Tạo hoặc cập nhật danh mục doanh thu
            </summary>
            <param name="model">Thông tin danh mục doanh thu</param>
            <returns>Kết quả tạo hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeCategoryController.Delete(System.Int32)">
            <summary>
            Xóa danh mục doanh thu
            </summary>
            <param name="id">ID danh mục doanh thu</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeCategoryController.GetAll">
            <summary>
            Lấy danh sách tất cả danh mục doanh thu (cho dropdown)
            </summary>
            <returns>Danh sách danh mục doanh thu</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeCategoryController.CheckNameExists(System.String,System.Int32)">
            <summary>
            Kiểm tra tên danh mục có trùng không
            </summary>
            <param name="name">Tên danh mục</param>
            <param name="excludeId">ID loại trừ (khi update)</param>
            <returns>True nếu tên đã tồn tại</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeCategoryController.GetHierarchy">
            <summary>
            Lấy danh sách danh mục doanh thu theo cây phân cấp
            </summary>
            <returns>Danh sách danh mục doanh thu theo cây phân cấp</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeCategoryController.GetRootCategories">
            <summary>
            Lấy danh sách danh mục gốc (không có ParentId)
            </summary>
            <returns>Danh sách danh mục gốc</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeCategoryController.GetChildren(System.Int32)">
            <summary>
            Lấy danh sách danh mục con theo ParentId
            </summary>
            <param name="parentId">ID danh mục cha</param>
            <returns>Danh sách danh mục con</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeCategoryController.CanDelete(System.Int32)">
            <summary>
            Kiểm tra có thể xóa danh mục không (không có danh mục con)
            </summary>
            <param name="id">ID danh mục</param>
            <returns>True nếu có thể xóa</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.IncomeController">
            <summary>
            Controller quản lý doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm doanh thu với phân trang
            </summary>
            <param name="param">Tham số tìm kiếm và phân trang</param>
            <returns>Danh sách doanh thu</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeController.GetById(System.Guid)">
            <summary>
            Lấy doanh thu theo ID
            </summary>
            <param name="id">ID doanh thu</param>
            <returns>Thông tin doanh thu</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.IncomeModel)">
            <summary>
            Tạo hoặc cập nhật doanh thu
            </summary>
            <param name="model">Thông tin doanh thu</param>
            <returns>Kết quả tạo hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeController.Approve(System.Guid)">
            <summary>
            Duyệt doanh thu
            </summary>
            <param name="id">ID doanh thu</param>
            <returns>Kết quả duyệt</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeController.Reject(System.Guid,Ladaer.BackEnd.Controllers.Finance.RejectIncomeRequest)">
            <summary>
            Từ chối doanh thu
            </summary>
            <param name="id">ID doanh thu</param>
            <param name="request">Thông tin từ chối</param>
            <returns>Kết quả từ chối</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeController.MarkAsReceived(System.Guid,Ladaer.BackEnd.Controllers.Finance.MarkAsReceivedIncomeRequest)">
            <summary>
            Đánh dấu doanh thu đã nhận tiền
            </summary>
            <param name="id">ID doanh thu</param>
            <param name="request">Thông tin nhận tiền</param>
            <returns>Kết quả đánh dấu nhận tiền</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeController.Delete(System.Guid)">
            <summary>
            Xóa doanh thu
            </summary>
            <param name="id">ID doanh thu</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeController.SubmitDeposit(Ladaer.BackEnd.Controllers.Finance.SubmitDepositRequest)">
            <summary>
            Nộp cọc trách nhiệm — tạo giao dịch thu nhập cọc lái xe
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.RejectIncomeRequest">
            <summary>
            Request model cho việc từ chối doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Finance.RejectIncomeRequest.RejectReason">
            <summary>
            Lý do từ chối (bắt buộc)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.MarkAsReceivedIncomeRequest">
            <summary>
            Request model cho việc đánh dấu doanh thu đã nhận tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Finance.MarkAsReceivedIncomeRequest.Note">
            <summary>
            Ghi chú cho giao dịch nhận tiền
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.SubmitDepositRequest">
            <summary>
            Request model cho việc nộp cọc trách nhiệm
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Finance.SubmitDepositRequest.UserId">
            <summary>
            ID lái xe nộp cọc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Finance.SubmitDepositRequest.Amount">
            <summary>
            Số tiền cọc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Finance.SubmitDepositRequest.TransferDate">
            <summary>
            Ngày chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Finance.SubmitDepositRequest.ProofImage">
            <summary>
            Ảnh chuyển khoản (tùy chọn)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Finance.SubmitDepositRequest.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.IncomeExpenseReportController">
            <summary>
            Controller cho báo cáo thu chi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeExpenseReportController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IIncomeExpenseReportService)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Controllers.Finance.IncomeExpenseReportController"/>.
            </summary>
            <param name="service">Service báo cáo thu chi.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.IncomeExpenseReportController.GetReport(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeExpenseReportRequest)">
            <summary>
            Lấy báo cáo thu chi theo khoảng thời gian
            </summary>
            <param name="request">Thông tin khoảng thời gian báo cáo</param>
            <returns>Báo cáo thu chi theo ngày</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.MyBankAccountController">
            <summary>
            Controller quản lý tài khoản ngân hàng cá nhân của người dùng đang đăng nhập
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.MyBankAccountController.GetAll">
            <summary>
            Lấy danh sách tài khoản ngân hàng của tôi
            </summary>
            <returns>Danh sách tài khoản ngân hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.MyBankAccountController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm tài khoản ngân hàng của tôi với phân trang
            </summary>
            <param name="param">Tham số tìm kiếm và phân trang</param>
            <returns>Danh sách tài khoản ngân hàng với phân trang</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.MyBankAccountController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết tài khoản ngân hàng của tôi theo ID
            </summary>
            <param name="id">ID tài khoản ngân hàng</param>
            <returns>Thông tin chi tiết tài khoản ngân hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.MyBankAccountController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UserBankAccountModel)">
            <summary>
            Tạo mới hoặc cập nhật tài khoản ngân hàng của tôi
            </summary>
            <param name="model">Thông tin tài khoản ngân hàng</param>
            <returns>Kết quả tạo hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.MyBankAccountController.Delete(System.Int32)">
            <summary>
            Xóa tài khoản ngân hàng của tôi
            </summary>
            <param name="id">ID tài khoản ngân hàng</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.PriceController">
            <summary>
            Controller xử lý các hoạt động liên quan đến giá cước.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.#ctor(Microsoft.Extensions.Options.IOptions{Ladaer.BackEnd.Infrastructures.AppSettings.AppSetting},Ladaer.BackEnd.Infrastructures.Services.Finances.IPriceService,Ladaer.BackEnd.Infrastructures.Services.Finances.IGoodsCategoryPriceService,Lada.Framework.Infrastructures.Services.Fees.IFeeQuoteEngine,Lada.Framework.Infrastructures.Services.Fees.IFeeConfigProvider,Microsoft.AspNetCore.Hosting.IWebHostEnvironment,Microsoft.AspNetCore.Http.IHttpContextAccessor)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Finance.PriceController"/>.
            </summary>
            <param name="options">Tùy chọn cấu hình ứng dụng.</param>
            <param name="priceService">Dịch vụ xử lý giá cước.</param>
            <param name="goodsCategoryPriceService">Dịch vụ quản trị ma trận giá theo loại hàng.</param>
            <param name="feeQuoteEngine">Engine báo giá theo dòng phí.</param>
            <param name="hostEnvironment">Môi trường lưu trữ web.</param>
            <param name="httpContextAccessor">Truy cập ngữ cảnh HTTP.</param>
            <remarks>
            GĐ 2 — bỏ <c>IBackFeeService</c> và <c>IGoodsCategoryPricingService</c> khỏi controller: cả hai
            nay nằm bên trong engine. <c>IBackFeeService</c> mất nơi gọi cuối cùng và đã được xoá.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.GetDefaultGoodsCategoryId">
            <summary>
            Id loại hàng mặc định của hệ thống (QĐ-1).
            </summary>
            <returns><c>GoodsCategoryId</c>, bằng <c>0</c> khi chưa cấu hình.</returns>
            <remarks>
            <para>
            Form lên đơn cần biết loại mặc định <b>ngay khi mở</b> để đặt sẵn dòng hàng đầu tiên, tức trước
            khi có đủ hai đầu địa chỉ để gọi <c>CheckFee</c>. Không có endpoint này thì frontend buộc phải
            hardcode Id "Hàng đóng kiện" — đúng thứ mà <c>GoodsCategoryResolver</c> đã cố tránh bằng cách
            đưa Id vào cấu hình.
            </para>
            <para>
            Chỉ trả Id, không trả tên: danh mục loại hàng frontend đã tải sẵn để đổ dropdown, tra tên ở đó.
            Dùng chung quyền với <c>CheckFee</c> vì cùng phục vụ một màn hình.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.GetDefaultPriceList(Lada.Framework.Data.Enums.PriceType)">
            <summary>
            Lấy danh sách giá mặc định.
            </summary>
            <param name="priceType">Loại giá.</param>
            <returns>Danh sách giá mặc định.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.UpdateDefaultPriceList(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceListModel)">
            <summary>
            Cập nhật danh sách giá mặc định.
            </summary>
            <param name="model">Model chứa thông tin danh sách giá.</param>
            <returns>Kết quả của hoạt động cập nhật danh sách giá.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.GetPriceList(System.Int32,Lada.Framework.Data.Enums.PriceType,System.Nullable{System.Int32})">
            <summary>
            Đọc bảng giá của MỘT PHẠM VI bất kỳ — bộ ba (khách, loại hàng, loại giá).
            </summary>
            <param name="customerId">Khách sở hữu bảng giá. <c>0</c> = khách mặc định.</param>
            <param name="priceType">Loại giá.</param>
            <param name="goodsCategoryId">Loại hàng. Bỏ trống = bảng giá CHUNG theo khoảng trọng lượng.</param>
            <returns>Bảng giá của phạm vi được hỏi.</returns>
            <remarks>
            <para>
            Đây là dạng tổng quát của <see cref="M:Ladaer.BackEnd.Controllers.Finance.PriceController.GetDefaultPriceList(Lada.Framework.Data.Enums.PriceType)"/> — endpoint cũ nay chỉ là lời gọi
            endpoint này với phạm vi (khách mặc định, bảng chung). Giữ endpoint cũ để client hiện tại không
            phải đổi.
            </para>
            <para>
            Dùng lại quyền <c>Price.GetDefaultPriceList</c>: cùng một việc "xem bảng giá", chỉ khác phạm vi.
            Đẻ quyền mới nghĩa là mọi vai trò đang xem bảng giá phải được gán lại tay.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.UpdatePriceList(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceListModel)">
            <summary>
            Cập nhật bảng giá của một phạm vi bất kỳ.
            </summary>
            <param name="model">Bảng giá kèm phạm vi <c>(CustomerId, GoodsCategoryId, PriceType)</c>.</param>
            <returns>Kết quả cập nhật.</returns>
            <remarks>
            ⚠️ Đường lưu này suy ra "dòng cần xoá" bằng <c>đang có trong phạm vi</c> − <c>có trong payload</c>.
            Gửi sai phạm vi là <b>xoá mềm dữ liệu của phạm vi khác</b> — đúng hình dạng của nợ PSVC. Payload
            phải chứa đủ mọi dòng người dùng đang nhìn thấy của ĐÚNG phạm vi đó.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.GetPriceScopes(System.Int32)">
            <summary>
            Liệt kê các PHẠM VI bảng giá của một khách hàng.
            </summary>
            <param name="customerId">Khách cần xem. <c>0</c> = khách mặc định.</param>
            <returns>Danh sách phạm vi kèm số dòng và cờ đang đi mượn bảng mặc định.</returns>
            <remarks>
            Danh sách cố tình gồm cả phạm vi khách <b>chưa khai dòng nào</b> và đang ăn theo bảng mặc định
            (cờ <c>IsInherited</c>). Người quản trị cần thấy "khách này đang tính tiền bằng bảng của ai" ngay
            trên màn hình, thay vì phải suy ra bằng cách không thấy dòng nào.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.CopyPriceList(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CopyPriceListModel)">
            <summary>
            Sao chép bảng giá từ phạm vi nguồn sang phạm vi đích.
            </summary>
            <param name="model">Nguồn, đích, loại giá và các tuỳ chọn copy.</param>
            <returns>Số ô đã tạo, bỏ qua, đè — và cảnh báo nếu có.</returns>
            <remarks>
            ⚠️ Mặc định <c>OverwriteExisting = false</c> — không đè ô đã tồn tại ở đích. UI phải hiện đủ
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.CopyPriceListResult.CreatedCount"/>, <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.CopyPriceListResult.SkippedCount"/>,
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.CopyPriceListResult.OverwrittenCount"/> cho người dùng biết.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.ExportDefaultPriceList(Lada.Framework.Data.Enums.PriceType)">
            <summary>
            Xuất danh sách giá mặc định.
            </summary>
            <param name="priceType">Loại giá của bảng đang mở — cùng tham số với GetDefaultPriceList.</param>
            <returns>Kết quả của hoạt động xuất danh sách giá.</returns>
            <remarks>
            <paramref name="priceType"/> là tham số THÊM VÀO khi vá nợ N4. Không có nó, service phải tự đoán
            phạm vi nên nạp mọi dòng giá của khách mặc định: file Excel trộn cả ba loại giá và kéo theo cả ô
            giá theo loại hàng, tức là <b>không khớp với bảng người dùng đang nhìn</b> lúc bấm Xuất.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.CheckFee(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeModel)">
            <summary>
            Kiểm tra phí.
            </summary>
            <param name="model">Model chứa thông tin kiểm tra phí.</param>
            <returns>Kết quả của hoạt động kiểm tra phí.</returns>
            <remarks>
            <para>
            GĐ 2 — đường này nay chạy bằng <see cref="T:Lada.Framework.Infrastructures.Services.Fees.IFeeQuoteEngine"/>, cùng khung dòng phí với đường tạo
            đơn. Trước đó khung dòng phí <b>không có nơi gọi nào trên đường tiền</b>: viết xong, có test, mà
            không ai chạy qua nó.
            </para>
            <para>
            <b>Không đổi một đồng nào — và đây là các lý do từng ô ra đúng số cũ:</b>
            </para>
            <list type="number">
            <item>
            <c>ResolveAreaSurcharge = true</c> để engine TỰ tra phụ phí khu vực từ hai phường, đúng việc
            <c>BackFeeService</c> làm trước đây. Đường tạo đơn để <c>false</c> — xem
            <see cref="P:Lada.Framework.DTO.OrderFeeCalculationRequest.ResolveAreaSurcharge"/>, bật nhầm ở đó là cộng thêm một
            khoản chưa từng có vào mọi đơn mới.
            </item>
            <item>
            Bốn khoản <c>CollectAmount</c> / <c>InsuranceFee</c> / <c>ReturnFee</c> / <c>Discount</c> để
            nguyên 0 vì <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeModel"/> không có chúng. Bộ tính tương ứng trả <c>null</c> ⇒
            không sinh dòng ⇒ không cộng đồng nào. Ngày nào form báo giá nhận thêm mấy số đó thì chỉ cần
            gán vào request, engine tự lo.
            </item>
            <item>
            Giá cố định theo loại hàng: <c>RouteFeeCalculator</c> sinh dòng cước tuyến <c>IsSkipped</c> với
            <c>Amount = 0</c>, nên <c>Fee</c> tự về 0 — thay cho câu <c>if (pricing.IsFixedPrice) Fee = 0</c>
            viết tay trước đây.
            </item>
            </list>
            <para>
            <b>Số lời gọi <c>IGoodsCategoryPricingService.ResolveAsync</c> giữ NGUYÊN, không tăng.</b> Bản cũ
            gọi hai lần: một lần trong <c>FeeService</c> (chỉ khi danh mục có bảng giá riêng) và một lần
            ngay tại controller (mọi lần tra cước thành công). Bản mới cũng hai: lần trong
            <c>FeeService</c> giữ nguyên, còn lần của controller dời vào
            <c>RouteFeeCalculator</c>. Điều kiện chạy khác nhau về hình thức (<c>GoodsCategoryId.HasValue</c>
            thay vì "tra cước thành công") nhưng ra cùng kết quả: bộ tính chỉ chạy tới đó khi tra cước đã
            thành công, và <c>ResolveAsync</c> không có danh mục thì trả kết quả rỗng.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.BuildGoodsLines(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeGoodsLineModel})">
            <summary>
            Dựng danh sách dòng hàng cho engine: quy đổi Kg → gram rồi <b>gộp</b> các món giống nhau về giá.
            </summary>
            <param name="lines">Dòng hàng form gửi, trọng lượng tính cước theo Kg.</param>
            <returns><c>null</c> khi form không khai theo món — engine đi nhánh một loại hàng.</returns>
            <remarks>
            <para>
            ⚠️ <b>Bước gộp là thứ giữ cho báo giá bằng đúng số tiền đơn được lưu.</b> Form lên đơn gửi
            <b>mỗi kiện một dòng</b> (<c>packageEditor.getFeeModel</c>), còn đường ghi đơn
            <c>OrderService.Create</c> <b>gộp</b> kiện cùng loại + cùng thuộc tính trước khi tra
            (<see cref="T:Lada.Framework.Infrastructures.Services.GoodsLineGrouper"/>). Bảng giá theo cân là bậc thang, nên tra ba dòng 10kg rồi cộng
            lại ra số khác với tra thẳng 30kg: trước bản vá này, đơn 3 kiện × 10kg cùng loại
            <b>báo 360.000 nhưng lưu 220.000</b> — người lên đơn báo khách một giá, hệ thống thu một giá khác.
            </para>
            <para>
            Gộp <b>sau</b> khi đã đổi kg → gram, đúng thứ tự của <c>OrderService.Create</c> (gộp trên
            <c>SubTotalWeight</c> đã là gram) và của <c>FeeRules.BuildGoodsLines</c> bên Lada.AppBackEnd.
            </para>
            <para>
            ⚠️ Đừng chuyển phép gộp xuống <c>RouteFeeCalculator</c>: engine cố ý để việc gộp cho nơi gọi, và
            <c>OrderService</c> / <c>OrderFinService</c> đã gộp trước khi gọi — gộp thêm lần nữa trong engine
            không sai số nhưng biến một quyết định tường minh thành hành vi ẩn ở hai tầng.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.GetGoodsCategoryPriceMatrix(System.Int32,Lada.Framework.Data.Enums.PriceType,System.Int32)">
            <summary>
            Đọc ma trận giá của một danh mục hàng hóa: tuyến (hàng) × lựa chọn thuộc tính trục (cột).
            </summary>
            <param name="goodsCategoryId">Danh mục hàng hóa.</param>
            <param name="priceType">Loại giá của các ô. Ô ma trận bình thường là <c>FixPrice</c>.</param>
            <param name="customerId">Khách sở hữu bảng giá. <c>0</c> = khách mặc định.</param>
            <returns>Lưới ĐẦY ĐỦ, phân biệt được ô đã khai giá và ô trống.</returns>
            <remarks>
            <para>
            Trả lưới đầy đủ chứ không phải danh sách dòng giá đang có: ô trống là thứ người quản trị
            <b>phải nhìn thấy</b> — đơn đi tuyến đó với lựa chọn đó sẽ báo "chưa có giá". Trả dòng thô thì ô
            trống đơn giản là không xuất hiện, và một tuyến bị bỏ quên trông y hệt một tuyến không tồn tại.
            </para>
            <para>
            Dùng lại quyền <c>Price.GetDefaultPriceList</c>: cùng một việc "xem bảng giá", chỉ khác hình dạng
            bảng. Đẻ thêm quyền mới nghĩa là mọi vai trò đang xem bảng giá phải được gán lại tay.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.GetCategoriesWithPriceTable(System.Int32)">
            <summary>
            Liệt kê các danh mục hàng hóa ĐÃ có bảng giá riêng.
            </summary>
            <param name="customerId">
            Lọc theo khách sở hữu ô giá. <c>0</c> = <b>mọi khách</b>, không phải khách mặc định.
            </param>
            <returns>Danh sách danh mục kèm số ô giá và số tuyến đã khai.</returns>
            <remarks>
            Danh sách này trả lời theo <b>dữ liệu</b> (có ô giá hay không), đúng câu hỏi mà engine đặt ra khi
            chọn trục. Một danh mục khai <c>PricingMode = RoutePriceList</c> mà chưa có ô nào <b>không</b> nằm
            trong danh sách này — và đơn của nó vẫn tính theo trọng lượng.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.UpdateGoodsCategoryPriceMatrix(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceListModel)">
            <summary>
            Ghi một lô ô giá của ma trận (tạo / sửa / xoá mềm).
            </summary>
            <param name="model">Lô ô giá cần lưu.</param>
            <returns>Kết quả lưu. <c>Message</c> mang cảnh báo khi lần lưu này xoá ô cuối cùng.</returns>
            <remarks>
            <para>
            ⚠️ Ô <b>vắng mặt</b> trong payload là ô KHÔNG ĐỤNG TỚI, không phải ô bị xoá. Muốn xoá thì phải
            gửi kèm cờ <c>Xoa = true</c>. Đường bảng giá chung suy ra "dòng cần xoá" bằng phép trừ và đó
            chính là cơ chế đã xoá oan 13 ô giá mỗi lần bấm Lưu (nợ PSVC) — không lặp lại ở đây.
            </para>
            <para>
            ⚠️ Lô rỗng là "không có gì để lưu", KHÔNG phải "xoá sạch bảng giá". Xoá cả bảng đi qua
            <see cref="M:Ladaer.BackEnd.Controllers.Finance.PriceController.DeleteGoodsCategoryPriceMatrix(System.Int32,System.Int32)"/> để hậu quả nhìn thấy được trên URL.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.InitGoodsCategoryPriceMatrix(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.InitGoodsCategoryPriceMatrixModel)">
            <summary>
            Khởi tạo ma trận giá cho một danh mục: sinh đủ ô theo tuyến × lựa chọn của thuộc tính trục.
            </summary>
            <param name="model">Danh mục, giá gốc và hệ số theo từng lựa chọn.</param>
            <returns>Kết quả khởi tạo kèm số ô đã sinh.</returns>
            <remarks>
            <para>
            ⚠️ Đây là thao tác <b>đổi cách tính tiền của cả danh mục</b>: ô giá đầu tiên xuất hiện là danh
            mục chuyển ngay từ nhánh trọng lượng sang nhánh bảng giá riêng, mọi đơn sau đó tra bảng mới.
            UI phải hỏi lại trước khi bấm.
            </para>
            <para>
            Không phải "sao chép bảng mặc định": bảng chung là tuyến × khoảng trọng lượng, bảng riêng là
            tuyến × lựa chọn trục — khác hình dạng, không nhân bản được. Ô đã có giá <b>không</b> bị đè.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.DeleteGoodsCategoryPriceMatrix(System.Int32,System.Int32)">
            <summary>
            Xoá bảng giá riêng của một danh mục ⇒ danh mục quay về tính cước theo TRỌNG LƯỢNG.
            </summary>
            <param name="goodsCategoryId">Danh mục cần xoá bảng giá riêng.</param>
            <param name="customerId">
            Khách sở hữu bảng giá cần xoá. <c>0</c> = <b>mọi khách</b>, không phải khách mặc định.
            </param>
            <returns>Kết quả xoá kèm số ô đã xoá.</returns>
            <remarks>
            ⚠️ Sau thao tác này đơn của danh mục <b>vẫn ra tiền</b>, chỉ là tính theo trọng lượng thay vì tra
            bảng riêng — không lỗi nào bay lên. Đây là đường lùi hợp lệ về nghiệp vụ, nhưng người bấm phải
            biết hậu quả tiền, nên nó là một endpoint riêng chứ không phải hệ quả phụ của một lần lưu.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.InitFilePath">
            <summary>
            Khởi tạo đường dẫn tệp.
            </summary>
            <returns>Đường dẫn tệp.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.PriceController.ConvertToUrl(System.String)">
            <summary>
            Chuyển đổi đường dẫn cục bộ thành URL.
            </summary>
            <param name="localUrl">Đường dẫn cục bộ.</param>
            <returns>URL.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.ReconciliationController">
            <summary>
            Controller quản lý đối soát đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ReconciliationController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Finances.IReconciliationService)">
            <summary>
            Khởi tạo controller
            </summary>
            <param name="reconciliationService">Service quản lý đối soát</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ReconciliationController.SearchCustomersForReconciliation(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm khách hàng cần đối soát với phân trang
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Kết quả tìm kiếm khách hàng cần đối soát</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ReconciliationController.SearchReconciliableOrders(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Nullable{Lada.Framework.Data.Domains.Finance.ReconciliationType})">
            <summary>
            Tìm kiếm đơn hàng có thể đối soát với phân trang
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <param name="reconciliationType">Loại đối soát (tùy chọn)</param>
            <returns>Kết quả tìm kiếm đơn hàng có thể đối soát</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ReconciliationController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm đối soát
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Kết quả tìm kiếm đối soát</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ReconciliationController.GetById(System.Int32)">
            <summary>
            Lấy chi tiết đối soát
            </summary>
            <param name="id">ID đối soát</param>
            <returns>Chi tiết đối soát</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ReconciliationController.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel)">
            <summary>
            Tạo đối soát mới
            </summary>
            <param name="model">Thông tin đối soát</param>
            <returns>Kết quả thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ReconciliationController.Confirm(System.Int32)">
            <summary>
            Xác nhận đối soát
            </summary>
            <param name="id">ID đối soát</param>
            <returns>Kết quả thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ReconciliationController.UpdateTransferred(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferReconciliationModel)">
            <summary>
            Cập nhật đã chuyển khoản
            </summary>
            <param name="model">Thông tin chuyển khoản</param>
            <returns>Kết quả thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ReconciliationController.Cancel(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CancelReconciliationModel)">
            <summary>
            Hủy đối soát với thông tin chi tiết
            </summary>
            <param name="model">Thông tin hủy đối soát</param>
            <returns>Kết quả thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ReconciliationController.Cancel(System.Int32)">
            <summary>
            Hủy đối soát (phương thức cũ - deprecated)
            </summary>
            <param name="id">ID đối soát</param>
            <returns>Kết quả thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ReconciliationController.UploadTransferProof(System.Int32,System.Collections.Generic.List{Microsoft.AspNetCore.Http.IFormFile})">
            <summary>
            Upload ảnh chứng từ chuyển khoản
            </summary>
            <param name="reconciliationId">ID đối soát</param>
            <param name="files">Danh sách file ảnh</param>
            <returns>Kết quả upload</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ReconciliationController.GetTransferProof(System.Int32)">
            <summary>
            Lấy danh sách ảnh chứng từ chuyển khoản
            </summary>
            <param name="reconciliationId">ID đối soát</param>
            <returns>Danh sách ảnh chứng từ</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ReconciliationController.ExportExcel(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel)">
            <summary>
            Xuất Excel danh sách phiếu đối soát
            </summary>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.ReconciliationController.ExportExcelDetail(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel)">
            <summary>
            Xuất Excel chi tiết phiếu đối soát
            </summary>
            <param name="reconciliationId">ID phiếu đối soát</param>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TaxInvoiceController.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateTaxInvoiceModel)">
            <summary>
            Tạo hóa đơn thuế mới
            </summary>
            <param name="model">Thông tin tạo hóa đơn (CustomerReconciliationSlipId, VatInfoId, Note)</param>
            <returns>Kết quả tạo hóa đơn</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TaxInvoiceController.UpdateStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UpdateTaxInvoiceStatusModel)">
            <summary>
            Cập nhật trạng thái hóa đơn thuế (Draft hoặc Issued)
            </summary>
            <param name="model">Thông tin cập nhật (TaxInvoiceId, Status, InvoiceNumber, InvoiceDate, Files)</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TaxInvoiceController.GetById(System.Int32)">
            <summary>
            Lấy thông tin hóa đơn thuế theo ID
            </summary>
            <param name="id">ID hóa đơn thuế</param>
            <returns>Thông tin hóa đơn thuế</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TaxInvoiceController.GetBySlipId(System.Int32)">
            <summary>
            Lấy thông tin hóa đơn thuế theo ID phiếu đối soát
            </summary>
            <param name="slipId">ID phiếu đối soát</param>
            <returns>Thông tin hóa đơn thuế</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TaxInvoiceController.Delete(System.Int32)">
            <summary>
            Xóa hóa đơn thuế (chỉ cho phép xóa khi ở trạng thái NotIssued)
            </summary>
            <param name="id">ID hóa đơn thuế</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TransactionController.SearchWalletTransactions(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm giao dịch của ví.
            Service sẽ tự động kiểm tra quyền: chỉ Founder và Accountant mới xem tất cả, user khác chỉ xem ví của mình.
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Danh sách giao dịch với tổng thu và tổng chi</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TransactionController.GetDetail(System.Guid)">
            <summary>
            Lấy chi tiết giao dịch (chỉ cho TransactionType = 4)
            </summary>
            <param name="id">ID của giao dịch</param>
            <returns>Chi tiết giao dịch</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TransactionController.GetStatistics(System.Int32,System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset})">
            <summary>
            Lấy thống kê giao dịch theo loại
            </summary>
            <param name="walletId">ID ví</param>
            <param name="startDate">Ngày bắt đầu (optional)</param>
            <param name="endDate">Ngày kết thúc (optional)</param>
            <returns>Thống kê giao dịch</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TransactionController.GetBalanceHistory(System.Int32,System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset})">
            <summary>
            Lấy lịch sử số dư ví
            </summary>
            <param name="walletId">ID ví</param>
            <param name="startDate">Ngày bắt đầu (optional)</param>
            <param name="endDate">Ngày kết thúc (optional)</param>
            <returns>Lịch sử số dư ví</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.TransferPaymentBillController">
            <summary>
            Controller quản lý hóa đơn thanh toán chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TransferPaymentBillController.SearchCustomersForTransferPayment(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm khách hàng có đơn hàng cần tạo hóa đơn thanh toán chuyển khoản
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Danh sách khách hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TransferPaymentBillController.GetTransferableOrdersByCustomer(System.Int32)">
            <summary>
            Lấy danh sách đơn hàng có thể tạo hóa đơn thanh toán của khách hàng
            </summary>
            <param name="customerId">ID khách hàng</param>
            <returns>Danh sách đơn hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TransferPaymentBillController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh sách hóa đơn thanh toán chuyển khoản
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Danh sách hóa đơn</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TransferPaymentBillController.GetById(System.Int32)">
            <summary>
            Lấy chi tiết hóa đơn thanh toán theo ID
            </summary>
            <param name="id">ID hóa đơn</param>
            <returns>Chi tiết hóa đơn</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TransferPaymentBillController.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateTransferPaymentBillModel)">
            <summary>
            Tạo hóa đơn thanh toán chuyển khoản
            </summary>
            <param name="model">Thông tin hóa đơn</param>
            <returns>Kết quả tạo hóa đơn</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TransferPaymentBillController.Cancel(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CancelTransferPaymentBillModel)">
            <summary>
            Hủy hóa đơn thanh toán chuyển khoản với thông tin chi tiết
            </summary>
            <param name="model">Thông tin hủy hóa đơn</param>
            <returns>Kết quả hủy hóa đơn</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TransferPaymentBillController.Cancel(System.Int32)">
            <summary>
            Hủy hóa đơn thanh toán chuyển khoản (phương thức cũ - deprecated)
            </summary>
            <param name="id">ID hóa đơn</param>
            <returns>Kết quả hủy hóa đơn</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TransferPaymentBillController.Approve(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ApproveTransferPaymentBillModel)">
            <summary>
            Duyệt hóa đơn thanh toán chuyển khoản
            </summary>
            <param name="model">Thông tin duyệt hóa đơn</param>
            <returns>Kết quả duyệt hóa đơn</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TransferPaymentBillController.ExportExcel(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel)">
            <summary>
            Xuất Excel danh sách phiếu chuyển khoản
            </summary>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.TransferPaymentBillController.ExportExcelDetail(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel)">
            <summary>
            Xuất Excel chi tiết phiếu chuyển khoản
            </summary>
            <param name="transferPaymentBillId">ID phiếu chuyển khoản</param>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.UserBankAccountController">
            <summary>
            Controller quản lý tài khoản ngân hàng người dùng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.UserBankAccountController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm tài khoản ngân hàng người dùng với phân trang
            </summary>
            <param name="param">Tham số tìm kiếm và phân trang</param>
            <returns>Danh sách tài khoản ngân hàng người dùng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.UserBankAccountController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết tài khoản ngân hàng theo ID
            </summary>
            <param name="id">ID tài khoản ngân hàng</param>
            <returns>Thông tin chi tiết tài khoản ngân hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.UserBankAccountController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UserBankAccountModel)">
            <summary>
            Tạo mới hoặc cập nhật tài khoản ngân hàng
            </summary>
            <param name="model">Thông tin tài khoản ngân hàng</param>
            <returns>Kết quả tạo hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.UserBankAccountController.Delete(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UserBankAccountModel)">
            <summary>
            Xóa tài khoản ngân hàng
            </summary>
            <param name="model">Thông tin tài khoản ngân hàng cần xóa</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.UserBankAccountController.GetMyBankAccounts">
            <summary>
            Lấy danh sách tài khoản ngân hàng của người dùng hiện tại
            </summary>
            <returns>Danh sách tài khoản ngân hàng</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.VatInvoiceController">
            <summary>
            Controller quản lý hóa đơn VAT từ Tổng cục Thuế
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.VatInvoiceController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm hóa đơn VAT
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Danh sách hóa đơn VAT</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.VatInvoiceController.SyncManual(Ladaer.BackEnd.Controllers.Finance.VatInvoiceController.DateRangeRequest)">
            <summary>
            Đồng bộ thủ công hóa đơn bán ra từ API Tổng cục Thuế
            </summary>
            <param name="request">Khoảng thời gian cần đồng bộ</param>
            <returns>Kết quả đồng bộ</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.VatInvoiceController.GetLastSyncInfo">
            <summary>
            Lấy thông tin đồng bộ gần nhất
            </summary>
            <returns>Thông tin đồng bộ gần nhất</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.VatInvoiceController.DateRangeRequest">
            <summary>
            Model cho request đồng bộ thủ công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Finance.VatInvoiceController.DateRangeRequest.InvoiceDirection">
            <summary>
            Chiều hóa đơn: 1 = Bán ra (Sold), 2 = Mua vào (Purchase). Mặc định là 1.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Finance.WalletController">
            <summary>
            Controller xử lý các yêu cầu liên quan đến ví điện tử.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.WalletController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh sách các ví điện tử dựa trên các tham số được cung cấp.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.WalletController.GetTransactions(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh sách các giao dịch của ví điện tử dựa trên các tham số được cung cấp.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.WalletController.GetSuggestions(System.String)">
            <summary>
            Lấy danh sách ví cho suggestion (select control).
            </summary>
            <param name="keyword">Từ khóa tìm kiếm (tên, số điện thoại, username).</param>
            <returns>Danh sách tối đa 20 ví.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.WalletController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của ví điện tử dựa trên ID.
            </summary>
            <param name="id">ID ví.</param>
            <returns>Thông tin chi tiết của ví.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.WalletController.GetMyWallet">
            <summary>
            Lấy thông tin chi tiết của ví điện tử của người dùng đang đăng nhập.
            </summary>
            <returns>Thông tin chi tiết của ví.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.WalletController.Transfer(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferWalletModel)">
            <summary>
            Chuyển tiền từ ví của người dùng đang đăng nhập sang ví đích.
            Ví nguồn sẽ được lấy tự động từ người dùng hiện tại.
            </summary>
            <param name="model">Thông tin chuyển tiền</param>
            <returns>Kết quả chuyển tiền</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Finance.WalletController.BalanceAdjustment(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BalanceAdjustmentModel)">
            <summary>
            Điều chỉnh số dư ví (cân ví) - chỉ dành cho Founder và Accountant.
            Tạo giao dịch để khớp số dư ví với số dư mong muốn.
            </summary>
            <param name="walletId">ID ví cần điều chỉnh</param>
            <param name="model">Thông tin điều chỉnh</param>
            <returns>Kết quả điều chỉnh</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.AttendanceController.CreateOrUpdateManual(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualAttendanceModel)">
            <summary>
            Tạo mới hoặc cập nhật bản ghi chấm công thủ công (bổ sung khi quên chấm vào/ra).
            </summary>
            <param name="model">Thông tin chấm công thủ công.</param>
            <returns>Kết quả xử lý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.AttendanceController.SuggestCheckOutTime(System.Int32,System.DateTimeOffset)">
            <summary>
            Gợi ý giờ chấm ra cho một ca dựa trên thời điểm lấy/giao hàng muộn nhất của lái xe
            kể từ khi ca bắt đầu. Dùng cho nút "Lấy giờ ra từ đơn hàng" trong dialog chấm bù công.
            </summary>
            <param name="userId">ID lái xe.</param>
            <param name="checkInTime">Thời điểm ca bắt đầu (giờ vào).</param>
            <returns>Kết quả gợi ý giờ ra kèm cờ có dữ liệu hay không.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.AttendanceController.CheckOverlap(System.Int32,System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset},System.Nullable{System.Guid})">
            <summary>
            Kiểm tra trước xem ca định chấm có bị trùng (chồng lấp thời gian) với ca đã có
            của cùng nhân viên hay không. Dùng cho FE cảnh báo sớm trong dialog chấm công thủ công
            và chấm ra bù. Hàng rào chặn thật vẫn nằm ở các API ghi dữ liệu.
            </summary>
            <param name="userId">ID nhân viên.</param>
            <param name="checkInTime">Giờ vào của ca định ghi (tùy chọn).</param>
            <param name="checkOutTime">Giờ ra của ca định ghi (tùy chọn).</param>
            <param name="excludeId">Id bản ghi đang sửa cần loại trừ (tùy chọn).</param>
            <returns>Kết quả kiểm tra trùng ca.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.AttendanceController.ManualCheckOut(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualCheckOutModel)">
            <summary>
            Chấm ra thủ công cho một bản ghi chưa có giờ ra (admin bổ sung hộ khi lái xe quên chấm ra),
            cho phép upload ảnh ODO bù. Dùng multipart/form-data.
            </summary>
            <param name="model">Thông tin chấm ra thủ công (giờ ra, ODO, ảnh).</param>
            <returns>Kết quả xử lý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.AttendanceController.Delete(System.Guid)">
            <summary>
            Xoá mềm một bản ghi chấm công. <b>Chỉ Founder</b> — không mở role riêng
            <c>Attendance.Delete</c> theo yêu cầu chủ dự án (2026-08-19), vì xoá chấm công đổi thẳng
            số công/kíp của kỳ lương chưa chốt. Frontend cũng chỉ hiện menu xoá cho Founder
            (<c>userStore.user.IsFounder</c>), nhưng hàng rào thật là attribute này.
            </summary>
            <param name="id">Id bản ghi chấm công.</param>
            <returns>Kết quả xử lý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.AttendanceController.ImportExcel(Microsoft.AspNetCore.Http.IFormFile)">
            <summary>
            Import bảng chấm công từ file Excel (máy chấm công vân tay).
            </summary>
            <param name="file">File Excel (.xlsx, .xls).</param>
            <returns>Kết quả import kèm thống kê.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.AttendanceController.ExportToExcel(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Xu?t danh s�ch ch?m c�ng ra file Excel.
            </summary>
            <param name="param">Tham s? t�m ki?m.</param>
            <returns>K?t qu? xu?t file Excel.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.AttendanceController.GetMonthlySummary(System.Int32,System.Int32)">
            <summary>
            Lấy tổng hợp số công của tất cả nhân viên theo tháng.
            </summary>
            <param name="month">Tháng (1-12).</param>
            <param name="year">Năm (ví dụ: 2025).</param>
            <returns>Danh sách tổng hợp số công của nhân viên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.AttendanceController.GetUserAttendanceDetail(System.Int32,System.Int32,System.Int32)">
            <summary>
            Lấy chi tiết công từng ngày của một nhân viên theo tháng.
            </summary>
            <param name="month">Tháng (1-12).</param>
            <param name="year">Năm (ví dụ: 2025).</param>
            <param name="userId">ID nhân viên.</param>
            <returns>Danh sách chi tiết công từng ngày của nhân viên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.AttendanceController.InitFilePath">
            <summary>
            Kh?i t?o du?ng d?n t?p.
            </summary>
            <returns>�u?ng d?n t?p.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.AttendanceController.ConvertToUrl(System.String)">
            <summary>
            Chuy?n d?i du?ng d?n file th�nh URL.
            </summary>
            <param name="filePath">�u?ng d?n file.</param>
            <returns>URL.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Hr.CandidateController">
            <summary>
            Controller d? x? lý các ho?t d?ng liên quan d?n ?ng viên.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.CandidateController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Hr.ICandidateService)">
            <summary>
            Kh?i t?o m?t instance m?i c?a l?p <see cref="T:Ladaer.BackEnd.Controllers.Hr.CandidateController"/>.
            </summary>
            <param name="candidateService">D?ch v? x? lý ?ng viên.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.CandidateController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm ki?m các ?ng viên d?a trên các tham s? du?c cung c?p.
            </summary>
            <param name="param">Các tham s? tìm ki?m.</param>
            <returns>K?t qu? tìm ki?m.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.CandidateController.Delete(System.Int32)">
            <summary>
            Xóa m?t ?ng viên d?a trên ID.
            </summary>
            <param name="id">ID c?a ?ng viên.</param>
            <returns>K?t qu? c?a ho?t d?ng xóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.CandidateController.GetReviewModel(System.Int32)">
            <summary>
            L?y thông tin dánh giá c?a m?t ?ng viên d?a trên ID.
            </summary>
            <param name="id">ID c?a ?ng viên.</param>
            <returns>Thông tin dánh giá c?a ?ng viên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.CandidateController.UpdateReview(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateReviewModel)">
            <summary>
            C?p nh?t thông tin dánh giá c?a m?t ?ng viên.
            </summary>
            <param name="model">Model ch?a thông tin dánh giá c?a ?ng viên.</param>
            <returns>K?t qu? c?a ho?t d?ng c?p nh?t dánh giá.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.CandidateController.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel)">
            <summary>
            T?o ?ng viên m?i.
            </summary>
            <param name="model">Thông tin ?ng viên.</param>
            <returns>K?t qu? c?a ho?t d?ng t?o ?ng viên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.CandidateController.GetById(System.Int32)">
            <summary>
            L?y thông tin ?ng viên theo ID.
            </summary>
            <param name="id">ID c?a ?ng viên.</param>
            <returns>Thông tin ?ng viên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.CandidateController.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel)">
            <summary>
            C?p nh?t thông tin ?ng viên.
            </summary>
            <param name="model">Thông tin ?ng viên.</param>
            <returns>K?t qu? c?a ho?t d?ng c?p nh?t.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.CandidateController.DownloadCv(System.Int32)">
            <summary>
            Download CV c?a ?ng viên
            </summary>
            <param name="id">ID c?a ?ng viên</param>
            <returns>File CV</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.CandidateController.GetContentType(System.String)">
            <summary>
            L?y content type d?a trên extension file
            </summary>
            <param name="fileExtension">Extension file</param>
            <returns>Content type</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Hr.DepositController">
            <summary>
            Quản lý cọc trách nhiệm + Tạm ứng lương — Lịch sử giao dịch
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.DepositController.CreateAdvance(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreateSalaryAdvanceModel)">
            <summary>
            Tạo phiếu tạm ứng lương (Expense Pending — chờ duyệt và chi)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.DepositController.CreateRefund(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreateRefundModel)">
            <summary>
            Hoàn cọc trách nhiệm (Expense Pending — chờ duyệt và chi)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.DepositController.GetHistory(System.Int32)">
            <summary>
            Lấy lịch sử giao dịch cọc/tạm ứng của NV
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.DepositController.GetBalance(System.Int32)">
            <summary>
            Lấy thông tin số dư cọc trách nhiệm của NV
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.DepositController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Search giao dịch cọc/tạm ứng (trang quản trị)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Hr.DepositTrackingController">
            <summary>
            Theo dõi cọc trách nhiệm lái xe — danh sách + tổng hợp
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.DepositTrackingController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Danh sách lái xe kèm trạng thái cọc (Hạn mức / Đã đóng / Đang chờ / Còn thiếu)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.DepositTrackingController.Summary">
            <summary>
            Số liệu tổng hợp cọc toàn công ty (theo scope agency của người xem)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.DepositTrackingController.ResolveAgencyScopeAsync">
            <summary>
            Founder xem tất cả (agencyIds = null); còn lại chỉ thấy agency của mình + con cháu
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Hr.DriverEvaluationController">
            <summary>
            Quản lý đánh giá lái xe (Test Lái / Thử Việc)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Hr.DriverSalaryScaleController">
            <summary>
            Quản lý bảng tra mức lương lái xe
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Hr.EmployeeSalaryConfigController">
            <summary>
            Quản lý cấu hình lương nhân viên
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.EmployeeSalaryConfigController.MySalaryConfig">
            <summary>
            NLĐ tự xem cấu hình lương của mình. Lấy userId từ JWT.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.EmployeeSalaryConfigController.GetConfigsForPeriod(System.Int32,System.Int32,System.Int32)">
            <summary>
            Lấy tất cả cấu hình lương có hiệu lực trong kỳ lương (month/year).
            Dùng cho form lập phiếu lương khi cần hiển thị nhiều config pro-rata.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Hr.EvaluationCriteriaController">
            <summary>
            Quản lý tiêu chí đánh giá lái xe
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Hr.HolidayController">
            <summary>
            Quản lý ngày lễ
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Hr.JobController">
            <summary>
            Controller d? x? l� c�c ho?t d?ng li�n quan d?n c�ng vi?c.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.JobController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Hr.IJobPostService)">
            <summary>
            Kh?i t?o m?t instance m?i c?a l?p <see cref="T:Ladaer.BackEnd.Controllers.Hr.JobController"/>.
            </summary>
            <param name="jobPostService">D?ch v? x? l� c�ng vi?c.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.JobController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            T�m ki?m c�c c�ng vi?c d?a tr�n c�c tham s? du?c cung c?p.
            </summary>
            <param name="param">C�c tham s? t�m ki?m.</param>
            <returns>K?t qu? t�m ki?m.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.JobController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel)">
            <summary>
            T?o ho?c c?p nh?t th�ng tin c�ng vi?c.
            </summary>
            <param name="jobModel">Model ch?a th�ng tin c�ng vi?c.</param>
            <returns>K?t qu? c?a ho?t d?ng t?o ho?c c?p nh?t.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.JobController.GetById(System.Int32)">
            <summary>
            L?y th�ng tin chi ti?t c?a m?t c�ng vi?c d?a tr�n ID.
            </summary>
            <param name="id">ID c?a c�ng vi?c.</param>
            <returns>Th�ng tin chi ti?t c?a c�ng vi?c.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.JobController.Delete(System.Int32)">
            <summary>
            X�a m?t c�ng vi?c d?a tr�n ID.
            </summary>
            <param name="id">ID c?a c�ng vi?c.</param>
            <returns>K?t qu? c?a ho?t d?ng x�a.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Hr.LeaveConfigController">
            <summary>
            Cấu hình loại nghỉ phép + Quỹ phép nhân viên
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Hr.LeaveRequestController">
            <summary>
            Quản lý phiếu nghỉ phép — NV, Manager, HR
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.LeaveRequestController.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreateLeaveRequestModel)">
            <summary>
            Tạo phiếu nghỉ phép
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.LeaveRequestController.Cancel(System.Guid)">
            <summary>
            Hủy phiếu nghỉ phép (chỉ khi đang chờ duyệt)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.LeaveRequestController.MyRequests(System.Nullable{System.Int32})">
            <summary>
            Lấy danh sách đơn nghỉ phép của tôi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.LeaveRequestController.MyBalances(System.Int32)">
            <summary>
            Lấy quỹ phép của tôi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.LeaveRequestController.ManagerPending(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Danh sách đơn chờ Manager duyệt
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.LeaveRequestController.ManagerApprove(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.LeaveApprovalModel)">
            <summary>
            Manager duyệt đơn
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.LeaveRequestController.ManagerReject(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.LeaveApprovalModel)">
            <summary>
            Manager từ chối đơn
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.LeaveRequestController.HrPending(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Danh sách đơn chờ HR duyệt
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.LeaveRequestController.HrApprove(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.LeaveApprovalModel)">
            <summary>
            HR duyệt đơn
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.LeaveRequestController.HrReject(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.LeaveApprovalModel)">
            <summary>
            HR từ chối đơn
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.LeaveRequestController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm tất cả đơn nghỉ phép (admin/HR)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Hr.PayrollAdjustmentController">
            <summary>
            Quản lý Thưởng/Phạt nhân viên
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Hr.PayrollController">
            <summary>
            Quản lý Phiếu lương (Payroll)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.PayrollController.CreatePayroll(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreatePayrollModel)">
            <summary>
            Lập phiếu lương cho kỳ
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.PayrollController.GetByPeriod(System.Int32,System.Int32)">
            <summary>
            Lấy danh sách phiếu lương theo kỳ
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.PayrollController.GetById(System.Guid)">
            <summary>
            Lấy phiếu lương theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.PayrollController.GetByUserId(System.Int32)">
            <summary>
            Lấy lịch sử phiếu lương theo nhân viên
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.PayrollController.MyPayroll(System.Int32,System.Int32)">
            <summary>
            NLĐ tự xem phiếu lương của mình theo kỳ (month/year).
            Lấy userId từ JWT, không yêu cầu quyền đặc biệt.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.PayrollController.MyLatestStatus(Ladaer.BackEnd.Infrastructures.Services.Hr.IMyPayslipStatusService)">
            <summary>
            Kỳ + trạng thái phiếu lương gần nhất (khác Bản nháp) của chính người gọi — thẻ "Phiếu lương tháng M" trên đầu
            Bảng tin. Không số tiền, không tham số: userId lấy từ JWT nên không xem được phiếu của người khác.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.PayrollController.MyPendingPayroll">
            <summary>
            Lái xe xem phiếu lương đang chờ xác nhận (nếu có).
            Không cần tham số — tự tìm phiếu pending mới nhất theo userId từ JWT.
            Dùng cho Driver App.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.PayrollController.SendForConfirmation(System.Guid)">
            <summary>
            KT gửi phiếu lương cho NLĐ xác nhận
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.PayrollController.ConfirmPayroll(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.PayrollConfirmModel)">
            <summary>
            NLĐ xác nhận hoặc từ chối phiếu lương
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.PayrollController.CalculateExpected(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreatePayrollModel,System.Int32)">
            <summary>
            Preview lương ước tính cho 1 nhân viên — không lưu DB.
            Dùng cho nút "Tính trước" trên form lập phiếu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.PayrollController.Delete(System.Guid)">
            <summary>
            Xóa phiếu lương — chỉ cho phép xóa khi ở trạng thái Bản nháp (Draft)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.PayrollController.GetSalaryModes">
            <summary>
            Filter phiếu lương theo SalaryMode trong Search — được xử lý ở Search action
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.PayrollController.ExportExcel(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Xuất danh sách phiếu lương ra Excel
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Hr.PayrollController.MyTeamRevenue(System.Int32,System.Int32)">
            <summary>
            NLĐ (trưởng nhóm/QLBC) tự xem doanh số team. Lấy userId từ JWT.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.AccountController.ChangePassword(Ladaer.BackEnd.Infrastructures.DTO.Models.Users.ChangePasswordModel)">
            <summary>
            Đ?i m?t kh?u cho ngu?i důng
            </summary>
            <param name="model">Thông tin d?i m?t kh?u</param>
            <returns>K?t qu? d?i m?t kh?u</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Identity.PermissionController">
            <summary>
            Controller để quản lý Permission Groups (tập hợp các Role)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.PermissionController.Delete(System.Int32)">
            <summary>
            Xóa Permission Group
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.PermissionController.AssignToUser(Ladaer.BackEnd.Controllers.Identity.AssignPermissionRequest)">
            <summary>
            Gán Permission cho User
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.PermissionController.RemoveFromUser(Ladaer.BackEnd.Controllers.Identity.RemovePermissionRequest)">
            <summary>
            Xóa Permission khỏi User
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.PermissionController.GetRoles(System.Int32)">
            <summary>
            Lấy danh sách Role trong Permission
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.PermissionController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm Permission với phân trang
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.PermissionController.GetAvailableRoles">
            <summary>
            Lấy tất cả Roles có thể gán cho Permission
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.PermissionController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Itentity.PermissionModel)">
            <summary>
            Tạo hoặc cập nhật Permission (theo pattern AgencyController)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.PermissionController.GetById(System.Int32)">
            <summary>
            Lấy thông tin Permission theo ID (trả về PermissionModel)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.PermissionController.UpdatePermissionRoles(Ladaer.BackEnd.Infrastructures.DTO.Models.Itentity.PermissionRoleModel)">
            <summary>
            Cập nhật danh sách Role của Permission (hàm riêng biệt)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Identity.UpdatePermissionRequest.Id">
            <summary>
            PermissionId
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Identity.UpdatePermissionRequest.RoleIds">
            <summary>
            Danh sách Role
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Identity.RoleMigrationController">
            <summary>
            Controller để quản lý migration từ old role system sang new Permission system
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.RoleMigrationController.GetMigrationStatus">
            <summary>
            Kiểm tra trạng thái migration
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.RoleMigrationController.PreviewNewRoles">
            <summary>
            Lấy danh sách Role mới sẽ được tạo
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.RoleMigrationController.PreviewRoleMapping">
            <summary>
            Lấy mapping từ old roles sang Permission Groups
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.RoleMigrationController.CreateNewRoles">
            <summary>
            Tạo các Role mới
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.RoleMigrationController.CreateDefaultPermissions">
            <summary>
            Tạo Permission Groups mặc định
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.RoleMigrationController.MigrateUsers">
            <summary>
            Migration Users từ old roles sang Permission Groups
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.RoleMigrationController.RunFullMigration">
            <summary>
            Chạy full migration process
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.UserController.SugDriverAll(System.String)">
            <summary>
            Gợi ý tất cả lái xe trong hệ thống, không giới hạn bưu cục.
            Dùng cho xuất kho và nhập kho.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.UserController.ChangePassword(Ladaer.BackEnd.Infrastructures.DTO.Models.Users.ChangePasswordModel)">
            <summary>
            Đổi mật khẩu cho người dùng
            </summary>
            <param name="model">Thông tin đổi mật khẩu</param>
            <returns>Kết quả đổi mật khẩu</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Identity.UserTrackController">
            <summary>
            API lịch sử thao tác người dùng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Identity.UserTrackController.GetByUserId(System.Int32,System.Int32)">
            <summary>
            Lấy lịch sử thao tác của người dùng
            </summary>
            <param name="userId">ID người dùng</param>
            <param name="take">Số lượng bản ghi tối đa (mặc định 50)</param>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsAdminController">
            <summary>
            Bảng tin nội bộ — màn NGƯỜI SOẠN (docs/plan-bang-tin-noi-bo.md §3.4, §3.8). Mọi action gác bằng
            <c>InternalNews.Manage | InternalNews.PublishAll</c> (Founder qua tất); role chưa đủ — service kiểm phạm vi từng
            dòng đối tượng lúc lưu và lúc đăng: vượt phạm vi → 403, bài ngoài phạm vi sửa → 404.
            </summary>
            <remarks>
            403 ở đây là lời từ chối theo DỮ LIỆU (người có role nhưng chọn đối tượng ngoài cây mình), nên giao diện gọi các
            action lưu / đăng / ước tính phải khai <c>boQuaChuyenHuong403</c> để không bị đá khỏi trang đang soạn.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsAdminController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách bài tôi quản lý: <c>status</c>, <c>kind</c>, <c>keyword</c> trong <c>Search.PredicateObject</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsAdminController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsPostModel)">
            <summary>Tạo (Id = 0) / sửa thông tin bài + đối tượng. Ghi đè toàn bộ thông tin; <c>Audiences = null</c> giữ nguyên đối tượng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsAdminController.SaveBlocks(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsBlocksModel)">
            <summary>Lưu bộ khối của bản đang sửa (thay cả bộ). Trả <c>DraftVersion</c> để gửi lại khi Đăng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsAdminController.Publish(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsPublishModel)">
            <summary>Đăng ngay / hẹn giờ (<c>PublishAt</c> tương lai) / Đăng lại (bài đang đăng; chuông chỉ gửi khi <c>NotifyAgain</c>).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsAdminController.Unpublish(System.Int32)">
            <summary>Thu hồi về nháp (bài đã đăng / đã lưu trữ) hoặc huỷ hẹn giờ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsAdminController.PreviewRecipientCount(Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudiencePreviewModel)">
            <summary>"≈ N người" cho đối tượng đang chọn — đúng tập sẽ nhận chuông.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsAdminController.AudienceOptions">
            <summary>
            Dữ liệu ô chọn đối tượng đã lọc theo phạm vi người đăng — màn soạn KHÔNG gọi <c>Permission/*</c>, <c>Agency/*</c>
            (đòi role miền khác mà trưởng bưu cục không có).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsAdminController.AudienceUsers(System.String)">
            <summary>Tìm người để chọn đích danh (≥ 2 ký tự, tối đa 20 người, trong phạm vi người đăng).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsAdminController.Preview(System.Int32)">
            <summary>Xem trước bản đang sửa (đã lọc HTML) cùng hình chi tiết người đọc.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsAdminController.BlockProfile">
            <summary>Bộ khối của bài bảng tin cho <c>BlockEditor</c> — máy chủ quyết loại khối, giao diện không chép.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsAdminController.Stats(System.Int32)">
            <summary>
            Thống kê đọc (GĐ D): người nhắm / đã đọc / đã xác nhận + theo đơn vị. Role <c>InternalNews.ViewStats</c> (Founder
            qua) — KHÔNG phải bó <see cref="F:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsNavPermissions.AdminRoles"/>: trưởng đơn vị chỉ có <c>Manage</c> nhận 403.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsAdminController.StatsPeople(System.Int32,System.String,System.Nullable{System.Int32},System.String,System.Int32,System.Int32)">
            <summary>Danh sách người nhắm: <c>status</c> unread (mặc định) | unacknowledged | all; <c>agencyId</c> 0 = không đơn vị.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsAdminController.StatsExport(System.Int32)">
            <summary>Tệp .xlsx trả thẳng (không lưu vào kho media công khai) — 2 trang tính: tổng hợp theo đơn vị, danh sách người nhắm.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsController">
            <summary>
            Bảng tin nội bộ — đường của NGƯỜI ĐỌC (docs/plan-bang-tin-noi-bo.md §3.3, §3.4): mọi người đăng nhập, không đòi role.
            Hàng rào là luật đối tượng ở service — bài không được xem trả 404 (không lộ tồn tại). API này cũng là API của app
            sau này (nợ BT-5), nên chỉ dựa vào JWT.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsController.Feed(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Bảng tin của tôi (POST vì nhận <see cref="T:Lada.Framework.DTO.SmartTable.SmartTableParam"/>): <c>Search.PredicateObject</c> nhận <c>kind</c>,
            <c>unread</c>, <c>archived</c>, <c>keyword</c>. Ghim lên đầu, rồi mới đăng trước; tối đa 50 bài một trang.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsController.GetById(System.Int32)">
            <summary>Chi tiết bài (ảnh chụp lúc đăng + tệp mà khối tham chiếu). Không được xem → 404.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsController.MarkRead(System.Int32)">
            <summary>Đánh dấu đã đọc — mở bài thì giao diện gọi. Lần sau chỉ đổi lần đọc gần nhất.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsController.Acknowledge(System.Int32)">
            <summary>"Tôi đã đọc và hiểu" — chỉ với bài bật yêu cầu xác nhận.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsController.UnreadCount">
            <summary>Số bài đang đăng tôi được xem mà chưa mở.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsController.Nav">
            <summary>
            Cờ cho giao diện — KHÔNG đòi role (rule <c>quyen-hien-thi</c> mục 4): người không có quyền nhận <c>false</c>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsFileController">
            <summary>
            Tài liệu (pdf/xlsx/docx, 30 MB) và video tệp (mp4/webm, 300 MB) của bài Bảng tin nội bộ — ghi vào kho media chung
            <c>Media.RootPath\Files\InternalNews\…</c>, URL trên <c>Media.Domain</c> (docs/plan-bang-tin-noi-bo.md §3.5, §6.5).
            Không có đường đọc nội dung ở đây: người đọc mở thẳng URL kho media (cổng media lo "đăng nhập mới xem", nợ BT-7).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsFileController.DocumentRequestLimitBytes">
            <summary>Trần request = trần tệp + 1 MB cho phần còn lại của multipart.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsFileController.UploadDocument(System.Int32,Microsoft.AspNetCore.Http.IFormFile,System.String,System.Threading.CancellationToken)">
            <summary>Tải lên một tài liệu của bài (multipart, khoá <c>file</c>, tuỳ chọn <c>title</c>). Kiểm bằng nội dung tệp.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsFileController.UploadVideo(System.Int32,Microsoft.AspNetCore.Http.IFormFile,System.String,System.Threading.CancellationToken)">
            <summary>Tải lên một video tệp của bài (multipart, khoá <c>file</c>): mp4, webm — tối đa 300 MB.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.InternalNews.InternalNewsFileController.Delete(System.Int32)">
            <summary>Xoá tệp: xoá file trên đĩa rồi xoá dòng. Từ chối khi khối nội dung (nháp hoặc bản đã đăng) còn dùng tệp.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Kpi.KpiAssignmentController">
            <summary>
            Giao và quản lý chỉ tiêu KPI.
            Role chỉ mở cửa API — phạm vi giao cho ai theo cây quản lý trực tiếp (§7.3)
            và phạm vi xem (§3.6) đều ép server-side trong service, không tin FE.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiAssignmentController.GetSubjects(Lada.Framework.Data.Enums.KpiSubjectKind,System.String,System.Int32)">
            <summary>
            Danh sách chủ thể người gọi giao được chỉ tiêu — nguồn cho ô chọn chủ thể ở màn giao chỉ tiêu.
            </summary>
            <remarks>
            Có endpoint riêng thay vì để FE gọi <c>User/Search</c> hay <c>Agency/Search</c>: hai đường
            đó thuộc miền khác và không bó theo §7.3, dùng chúng ở màn KPI là lặp lại đúng lỗi GĐ C
            (mượn lớp phân quyền của miền này để gác dữ liệu của miền kia). Trả về **chỉ Id và tên**.
            </remarks>
            <param name="subjectKind">Nhân viên hay đơn vị</param>
            <param name="keyword">Lọc theo tên, bỏ trống thì lấy từ đầu danh sách</param>
            <param name="take">Số dòng tối đa (mặc định 50, trần 200)</param>
            <remarks>
            <para>
            Mở cho **mọi role của phân hệ KPI** chứ không riêng role giao chỉ tiêu, vì thứ trả về
            luôn bị bó bởi phạm vi §7.3 của **chính người gọi**: ai không quản lý ai thì nhận danh
            sách rỗng, không có gì để lộ. Siết hẹp hơn thì lợi bất cập hại — người chỉ có quyền xem
            mở đúng màn hình của mình là ăn 403, và interceptor của SPA đá họ ra trang "không có
            quyền" giữa chừng thay vì hiện một danh sách rỗng có giải thích.
            </para>
            <para>
            Ba đường thao tác dùng chung luật §7.3 (giao chỉ tiêu, chốt lại kỳ, đánh giá quý/năm) đều
            cần danh sách này — xem <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiManagementScopeResolver"/>.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiAssignmentController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm chỉ tiêu — không có Kpi.ViewAll thì chỉ thấy của mình + cấp dưới trực tiếp + đơn vị mình quản lý
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiAssignmentController.GetById(System.Int32)">
            <summary>
            Lấy chỉ tiêu theo Id (null nếu ngoài phạm vi xem)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiAssignmentController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentModel)">
            <summary>
            Giao/sửa một dòng chỉ tiêu (Draft lưu lẻ dòng được, response kèm cảnh báo tổng trọng số §7.8)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiAssignmentController.Delete(System.Int32)">
            <summary>
            Xoá chỉ tiêu (xoá mềm — chặn khi kỳ đã chốt)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiAssignmentController.Assign(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentAssignModel)">
            <summary>
            Chuyển cả bộ chỉ tiêu của một chủ thể trong một kỳ sang Đã giao — chặn cứng khi tổng trọng số ≠ 100% (§7.8)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiAssignmentController.CopyFromPreviousPeriod(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentCopyModel)">
            <summary>
            Copy bộ chỉ tiêu của một chủ thể từ kỳ trước sang kỳ mới (Draft)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Kpi.KpiBonusController">
            <summary>
            Cấu hình thưởng KPI và luồng sinh tiền (§7.5, §7.14).
            </summary>
            <remarks>
            Một role duy nhất cho cả mẫu bậc thang lẫn dòng cấu hình nhân viên–tháng
            (<c>KpiBonusPolicy.*</c>, §7.14): cả hai đều là "chuỗi cấu hình đổi được tiền" của §3.10, và
            tách role ra chỉ tạo ảo giác phân quyền — ai sửa được mẫu thì cũng đổi được số tiền của mọi
            dòng đang trỏ tới mẫu đó.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiBonusController.Preview(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusRunModel)">
            <summary>
            Bảng tính thử — hiện tiền sẽ sinh, không ghi gì. Chạy được cả khi công tắc còn tắt (§5.1 bước 4).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiBonusController.Generate(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusRunModel)">
            <summary>
            Sinh/cập nhật thưởng thật cho một kỳ — idempotent. Đường thủ công; chốt kỳ cũng tự gọi.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Kpi.KpiCustomerActivityController">
             <summary>
             Khách hàng không hoạt động theo sale — dữ liệu "đánh dấu để dễ quản lý" mà plan §7.4 yêu cầu.
             </summary>
             <remarks>
             Đặt cùng họ với <c>KpiProgressController</c> và dùng chung role <c>KpiAssignment.Search</c>:
             cùng một đối tượng người dùng (người quản lý theo dõi chỉ tiêu sale), cùng một luật phạm vi
             (<c>IKpiVisibilityResolver</c>), và số ở đây phải khớp thẻ <c>sales.active-customers</c> trên
             màn theo dõi. Tách role riêng chỉ tạo thêm chỗ để cấu hình sai.
            
             Phạm vi ép trong service, role chỉ mở cửa API.
            
             ⚠️ Dữ liệu trả về là **danh bạ CRM** (tên + số điện thoại khách), nên service còn đòi thêm một
             điều kiện nữa mới cho xem ngoài đội của mình: Founder hoặc role <c>Customer.Search</c>. Người
             chỉ có <c>Kpi.ViewAll</c> xem được KPI của mọi người nhưng **không** vì thế mà đọc được cả tệp
             khách hàng — xem chú thích trong <c>CustomerActivityService.GetInactiveInScopeAsync</c>.
            
             ⚠️ Endpoint này **chỉ đọc**. Việc giải phóng khách khỏi sale không chăm ("nhả quản lý") là nợ
             `KPI-1`, làm ở đợt riêng — đừng thêm hành động ghi vào đây.
             </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiCustomerActivityController.GetInactive(System.Nullable{System.DateTimeOffset},System.Nullable{System.Int32})">
            <summary>
            Danh sách khách hàng **không hoạt động** trong phạm vi người đang đăng nhập được xem.
            </summary>
            <param name="asOfDate">Thời điểm chốt; bỏ trống lấy hiện tại</param>
            <param name="saleId">Lọc thêm về một sale; chỉ thu hẹp kết quả, không mở thêm quyền</param>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Kpi.KpiMetricController">
            <summary>
            Quản trị danh mục chỉ số KPI
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiMetricController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh mục chỉ số
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiMetricController.GetById(System.Int32)">
            <summary>
            Lấy chỉ số theo Id
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiMetricController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiMetricModel)">
            <summary>
            Tạo hoặc cập nhật chỉ số
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiMetricController.Delete(System.Int32)">
            <summary>
            Xoá chỉ số (xoá mềm — chặn khi đã có chỉ tiêu tham chiếu)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Kpi.KpiPeriodCloseController">
            <summary>
            Chốt kỳ KPI thủ công và nhập tay giá trị thực (plan §3.4).
            </summary>
            <remarks>
            <para>
            Đường tự động là Hangfire job <c>KpiPeriodCloseJob</c> chạy mùng 1; controller này là đường
            thủ công cho hai ca: chốt sớm/chốt bù một chủ thể, và chốt lại trong cửa sổ
            <c>Kpi.RecloseWindowDays</c> khi dữ liệu đơn hàng còn điều chỉnh.
            </para>
            <para>
            Role <c>KpiAssignment.Close</c> chỉ **mở cửa API**; ai chốt được cho ai vẫn do luật phạm vi
            §7.3 quyết trong service. Job không đi qua đây và không mở endpoint nào mới (§3.10).
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiPeriodCloseController.Close(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodCloseModel)">
            <summary>
            Chốt (hoặc chốt lại) kỳ của một chủ thể.
            </summary>
            <param name="model">Chủ thể và kỳ cần chốt</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiPeriodCloseController.SaveManualValue(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiManualValueModel)">
            <summary>
            Nhập tay giá trị thực cho một chỉ tiêu trước khi chốt kỳ; job chốt không ghi đè giá trị này.
            </summary>
            <param name="model">Chỉ tiêu, giá trị và lý do nhập tay (lý do bắt buộc)</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiPeriodCloseController.GetRecloseWindow(System.Int32,System.Int32,System.Nullable{Lada.Framework.Data.Enums.KpiSubjectKind},System.Int32)">
            <summary>
            Tình trạng cửa sổ chốt lại của một kỳ — màn chốt kỳ dùng để nói "còn N ngày" trước khi bấm.
            </summary>
            <remarks>
            Chỉ đọc. Truyền <paramref name="subjectKind"/> và <paramref name="subjectId"/> thì trả
            thêm chủ thể đó đã chốt kỳ chưa, và chỉ khi chủ thể nằm trong phạm vi §7.3 của người gọi.
            </remarks>
            <param name="periodYear">Năm của kỳ</param>
            <param name="periodMonth">Tháng của kỳ (1-12)</param>
            <param name="subjectKind">Loại chủ thể, bỏ trống nếu chỉ cần thông tin mức kỳ</param>
            <param name="subjectId">Id chủ thể, bỏ trống nếu chỉ cần thông tin mức kỳ</param>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Kpi.KpiPeriodicReviewController">
            <summary>
            Đánh giá KPI định kỳ quý/năm (plan §7.1) — tầng đọc + kết luận của con người, không sinh tiền.
            </summary>
            <remarks>
            Phạm vi XEM (§3.6) và phạm vi THAO TÁC (§7.3) tách hẳn nhau ở đây: người có <c>Kpi.ViewAll</c>
            đọc được bản đánh giá của cả công ty, nhưng chỉ quản lý trực tiếp (hoặc Founder) mới viết và
            chốt được. Role dưới đây chỉ mở cửa API, luật phạm vi nằm trong service.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiPeriodicReviewController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Danh sách bản đánh giá định kỳ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiPeriodicReviewController.GetById(System.Int32)">
            <summary>
            Một bản đánh giá kèm bảng tổng hợp điểm sống của kỳ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiPeriodicReviewController.Aggregate(Lada.Framework.Data.Enums.KpiSubjectKind,System.Int32,Lada.Framework.Data.Enums.KpiPeriodType,System.Int32,System.Int32)">
            <summary>
            Bảng tổng hợp điểm KPI quý/năm của một chủ thể — số sống, chưa gắn với bản đánh giá nào.
            </summary>
            <param name="subjectKind">1 nhân viên, 2 đơn vị</param>
            <param name="subjectId">User.Id hoặc Agency.Id</param>
            <param name="periodType">1 quý, 2 năm</param>
            <param name="periodYear">Năm của kỳ</param>
            <param name="periodIndex">Quý 1-4; bỏ qua khi kỳ năm</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiPeriodicReviewController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodicReviewModel)">
            <summary>
            Tạo hoặc sửa bản đánh giá (chỉ khi còn Draft).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiPeriodicReviewController.Finalize(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodicReviewFinalizeModel)">
            <summary>
            Chốt bản đánh giá — snapshot điểm tổng hợp tại thời điểm chốt, sau đó không sửa được nữa.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiPeriodicReviewController.Delete(System.Int32)">
            <summary>
            Xoá bản đánh giá còn Draft.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Kpi.KpiProgressController">
            <summary>
            Theo dõi KPI trong kỳ — giá trị thực tính tại thời điểm gọi, chưa chốt kỳ (plan §3.4).
            </summary>
            <remarks>
            Dùng chung role <c>KpiAssignment.Search</c> với màn danh sách chỉ tiêu: cùng một tập dữ liệu,
            chỉ khác cách trình bày, nên tách role riêng chỉ tạo thêm chỗ để cấu hình sai.
            Phạm vi xem ép trong service theo §3.6 — role chỉ mở cửa API.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Kpi.KpiProgressController.Get(System.Int32,System.Int32,System.Nullable{Lada.Framework.Data.Enums.KpiSubjectKind},System.Nullable{System.Int32})">
            <summary>
            Tiến độ KPI của một kỳ, gộp theo chủ thể.
            </summary>
            <param name="periodYear">Năm của kỳ; bỏ trống lấy năm hiện tại</param>
            <param name="periodMonth">Tháng của kỳ 1-12; bỏ trống lấy tháng hiện tại</param>
            <param name="subjectKind">Lọc thêm theo loại chủ thể: 1 nhân viên, 2 đơn vị</param>
            <param name="subjectId">Lọc thêm theo một chủ thể; chỉ thu hẹp kết quả, không mở thêm quyền</param>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Medias.NewMediaController">
            <summary>
            Controller demo cho New Media Services
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.NewMediaController.UploadImage(Microsoft.AspNetCore.Http.IFormFile,System.String)">
            <summary>
            Upload ảnh đơn giản (không lưu database)
            </summary>
            <param name="file">File ảnh</param>
            <param name="imageType">Loại ảnh (avatar, product, general, etc.)</param>
            <returns>URL ảnh đã xử lý</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.NewMediaController.UploadMultipleImages(System.Collections.Generic.List{Microsoft.AspNetCore.Http.IFormFile},System.String)">
            <summary>
            Upload nhiều ảnh cùng lúc
            </summary>
            <param name="files">Danh sách file ảnh</param>
            <param name="imageType">Loại ảnh</param>
            <returns>Danh sách kết quả</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.NewMediaController.UploadVideo(Microsoft.AspNetCore.Http.IFormFile,System.String)">
            <summary>
            Upload video đơn giản
            </summary>
            <param name="file">File video</param>
            <param name="videoType">Loại video</param>
            <returns>URL video đã xử lý</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.NewMediaController.UploadMedia(Microsoft.AspNetCore.Http.IFormFile)">
            <summary>
            Upload media tự động detect loại (ảnh hoặc video)
            </summary>
            <param name="file">File media</param>
            <returns>Kết quả xử lý</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.NewMediaController.UploadAttendanceImage(Microsoft.AspNetCore.Http.IFormFile,System.Int32)">
            <summary>
            Upload ảnh cho attendance (có lưu database)
            </summary>
            <param name="file">File ảnh</param>
            <param name="attendanceId">ID chấm công</param>
            <returns>Kết quả xử lý</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.NewMediaController.UploadTruckActivityImage(Microsoft.AspNetCore.Http.IFormFile,System.Int32)">
            <summary>
            Upload ảnh cho truck activity
            </summary>
            <param name="file">File ảnh</param>
            <param name="truckActivityId">ID hoạt động xe</param>
            <returns>Kết quả xử lý</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.NewMediaController.ValidateImage(Microsoft.AspNetCore.Http.IFormFile)">
            <summary>
            Validate file có phải ảnh hợp lệ không
            </summary>
            <param name="file">File cần kiểm tra</param>
            <returns>True nếu hợp lệ</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.NewMediaController.GetUrlBySystemPath(System.String)">
            <summary>
            Convert SystemPath thành URL hiển thị
            </summary>
            <param name="systemPath">Đường dẫn hệ thống</param>
            <returns>URL hiển thị</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Medias.OgImageMigrationController">
            <summary>
            API batch migration: Tạo ảnh JPEG (og:image) từ thumbnails WebP cũ
            Dùng 1 lần để cập nhật dữ liệu cũ, sau đó có thể xóa controller này
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.OgImageMigrationController.MigratePosts">
            <summary>
            Batch tạo ảnh JPEG cho tất cả Posts có thumbnail WebP nhưng chưa có OgImage
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.OgImageMigrationController.MigrateProducts">
            <summary>
            Batch tạo ảnh JPEG cho tất cả Products có thumbnail WebP nhưng chưa có OgImage
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.OgImageMigrationController.MigrateJobPosts">
            <summary>
            Batch tạo ảnh JPEG cho tất cả JobPosts có thumbnail WebP nhưng chưa có OgImage
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.OgImageMigrationController.MigrateAll">
            <summary>
            Chạy migration cho tất cả (Posts + Products + JobPosts)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.OgImageMigrationController.ProcessThumbnail(System.String,System.Int32,System.String)">
            <summary>
            Chuyển URL thumbnail WebP thành đường dẫn file hệ thống,
            tạo bản JPEG, trả về URL mới
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.OgImageMigrationController.UrlToSystemPath(System.String)">
            <summary>
            Chuyển URL (Domain + relative path) → System path (RootPath + relative path)
            VD: https://ladaexpress.vn/Images/PostThumb/2005/5/26/optimized/image.webp
              → C:\uploads\Images\PostThumb\2005\5\26\optimized\image.webp
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Medias.PictureController">
            <summary>
            Controller to handle operations related to pictures.
            Updated to use UnifiedMediaService from Framework.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.PictureController.#ctor(Lada.Framework.Infrastructures.Services.IUnifiedMediaService)">
            <summary>
            Initializes a new instance of the <see cref="T:Ladaer.BackEnd.Controllers.Medias.PictureController"/> class.
            </summary>
            <param name="unifiedMediaService">Unified media service from Framework.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.PictureController.UploadPostContentPicture(Microsoft.AspNetCore.Http.IFormFile)">
            <summary>
            Uploads a picture for post content.
            </summary>
            <param name="file">The picture file to upload.</param>
            <returns>The result of the upload operation.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.PictureController.UploadInternalNewsContentPicture(Microsoft.AspNetCore.Http.IFormFile)">
            <summary>
            Ảnh bìa + ảnh khối Hình ảnh / Bộ ảnh của bài Bảng tin nội bộ — thư mục <c>Images\InternalNews\…</c> trong kho
            media chung (docs/plan-bang-tin-noi-bo.md §3.5, §6.5). Cùng bó role với màn quản trị bảng tin.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.PictureController.UploadLessonContentPicture(Microsoft.AspNetCore.Http.IFormFile)">
            <summary>
            Uploads a picture for training lesson content.
            </summary>
            <param name="file">The picture file to upload.</param>
            <returns>The result of the upload operation.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Medias.PictureController.UploadGeneralPicture(Microsoft.AspNetCore.Http.IFormFile)">
            <summary>
            Tải lên ảnh dùng chung cho các trang cấu hình hệ thống (ví dụ ảnh QR tải app khách hàng).
            </summary>
            <param name="file">Tệp ảnh cần tải lên.</param>
            <returns>Kết quả tải lên kèm URL tuyệt đối của ảnh.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Monitor.OrderMonitor.OrderRiskController.GetOrdersWithoutSourceCashier(System.Nullable{System.DateTime},System.Nullable{System.DateTime},System.Int32,System.Int32)">
            <summary>
            Lấy danh sách đơn hàng thu người gửi nhưng không có SourceCashierId
            </summary>
            <param name="fromDate">Từ ngày (optional)</param>
            <param name="toDate">Đến ngày (optional)</param>
            <param name="page">Trang (default: 1)</param>
            <param name="pageSize">Số bản ghi/trang (default: 50)</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Monitor.OrderMonitor.OrderRiskController.GetOrderRiskOverview(System.Nullable{System.DateTime},System.Nullable{System.DateTime})">
            <summary>
            Lấy tổng quan các rủi ro đơn hàng (số đơn, tổng tiền)
            </summary>
            <param name="fromDate">Từ ngày (optional)</param>
            <param name="toDate">Đến ngày (optional)</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Monitor.OrderMonitor.OrderRiskController.GetOrdersWithoutDestCashier(System.Nullable{System.DateTime},System.Nullable{System.DateTime},System.Int32,System.Int32)">
            <summary>
            Lấy danh sách đơn hàng thu người nhận nhưng không có DestCashierId
            </summary>
            <param name="fromDate">Từ ngày (optional)</param>
            <param name="toDate">Đến ngày (optional)</param>
            <param name="page">Trang (default: 1)</param>
            <param name="pageSize">Số bản ghi/trang (default: 50)</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Monitor.OrderMonitor.OrderRiskController.GetOrderRiskOverviewForDestCashier(System.Nullable{System.DateTime},System.Nullable{System.DateTime})">
            <summary>
            Lấy tổng quan các đơn hàng thu người nhận thiếu DestCashier (số đơn, tổng tiền)
            </summary>
            <param name="fromDate">Từ ngày (optional)</param>
            <param name="toDate">Đến ngày (optional)</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Monitor.OrderMonitor.OrderRiskController.GetOrdersBothPayWithoutCashier(System.Nullable{System.DateTime},System.Nullable{System.DateTime},System.Int32,System.Int32)">
            <summary>
            Lấy danh sách đơn hàng thu cả 2 đầu nhưng thiếu SourceCashierId hoặc DestCashierId
            </summary>
            <param name="fromDate">Từ ngày (optional)</param>
            <param name="toDate">Đến ngày (optional)</param>
            <param name="page">Trang (default: 1)</param>
            <param name="pageSize">Số bản ghi/trang (default: 50)</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Monitor.OrderMonitor.OrderRiskController.GetOrderRiskOverviewForBothPay(System.Nullable{System.DateTime},System.Nullable{System.DateTime})">
            <summary>
            Lấy tổng quan các đơn hàng thu cả 2 đầu thiếu Cashier (số đơn, tổng tiền)
            </summary>
            <param name="fromDate">Từ ngày (optional)</param>
            <param name="toDate">Đến ngày (optional)</param>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Network.AgencyProfileController">
            <summary>
            Hồ sơ công khai của bưu cục (docs/plan-buu-cuc.md §3.5, GĐ A1).
            </summary>
            <remarks>
            Role chỉ mở cửa API. Phạm vi bưu cục (Branch.Manager chỉ bưu cục của mình) và quyền theo nhóm trường đều ép trong
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService"/> — không tin FE. Lỗi trả đúng HTTP status theo
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileErrorCodes.ToHttpStatus(System.String)"/> (403/404/409/422), body vẫn là <c>AgencyProfileResult</c>
            (<c>Result</c>, <c>Message</c>, <c>ErrorCode</c>…). <c>apiClient</c> của SPA chỉ nhận 2xx — service FE phải bắt riêng.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách hồ sơ — 200 trả thẳng <c>SmartTableResult</c> như mọi màn danh sách; 403 khi không có phạm vi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.Get(System.Int32)">
            <summary>Chi tiết hồ sơ + điều kiện đăng + cờ quyền. 403 ngoài phạm vi, 404 chưa có hồ sơ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.CreateProfile(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileCreateModel)">
            <summary>Tạo hồ sơ nháp. 409 PROFILE_ALREADY_EXISTS, 422 AGENCY_NOT_BRANCH / INVALID_DISPLAY_NAME.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel)">
            <summary>Sửa theo nhóm trường. 403 FORBIDDEN_FIELD kèm tên nhóm; 409 VERSION_CONFLICT kèm <c>Current</c>; 422 lỗi dữ liệu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.SetStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileSetStatusModel)">
            <summary>Công bố / tạm ngưng (SetStatus) hoặc đóng (Close). 422 INVALID_TRANSITION / PUBLISH_PRECONDITION_FAILED kèm <c>Missing</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.Reopen(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileReopenModel)">
            <summary>Mở lại hồ sơ đã đóng về nháp.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.UpsertHours(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyHoursUpsertModel)">
            <summary>Giờ làm việc đủ 7 ngày — Branch.Manager sửa trực tiếp bưu cục của mình.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.UpsertException(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyHourExceptionUpsertModel)">
            <summary>Ngoại lệ giờ một ngày (thêm/sửa/gỡ).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.BulkUpsertExceptions(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyHourExceptionBulkModel)">
            <summary>
            Ngoại lệ giờ cho nhiều bưu cục một lần (GĐ D — nghỉ lễ). Một ngày hoặc khoảng ≤ 31 ngày; mỗi bưu cục có thay đổi
            được một phiên bản + nhật ký, tất cả một transaction. Một bưu cục ngoài phạm vi → 403 cả lần gọi, không ghi gì.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.CreateChangeRequest(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestCreateModel)">
            <summary>
            Branch.Manager gửi đề xuất sửa một nhóm trường chỉ-đề-xuất (Toạ độ, Giới thiệu/hỏi đáp, Tuyến, Ghi chú vùng,
            Nhân sự — GĐ D). Dữ liệu kiểm ngay bằng luật của đường ghi; 422 <c>NO_CHANGES</c> khi giống hồ sơ hiện tại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.ChangeRequests(System.Nullable{System.Int32},System.Nullable{System.Int32},System.Int32,System.Int32)">
            <summary>
            Hàng đợi đề xuất kèm bảng so sánh hiện tại ↔ đề xuất. Người duyệt thấy mọi bưu cục; Branch.Manager chỉ thấy
            bưu cục mình (ép ở truy vấn). <c>status</c>: 1 chờ, 2 đã duyệt, 3 từ chối, 4 bị thay; trống = mọi trạng thái.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.ApproveChangeRequest(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestApproveModel)">
            <summary>
            Duyệt: áp vào hồ sơ qua đúng đường ghi sẵn có (luật nội dung chạy lại), sinh một phiên bản. Chỉ người phạm vi
            toàn mạng lưới. 409 <c>CHANGE_REQUEST_CLOSED</c> khi đề xuất đã xử lý; 409 <c>VERSION_CONFLICT</c> khi hồ sơ đổi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.RejectChangeRequest(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestRejectModel)">
            <summary>Từ chối kèm lý do bắt buộc — hồ sơ không đổi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.Report(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyWebReportQuery)">
            <summary>
            Báo cáo bưu cục một tháng (GĐ D): lượt + phiên theo bưu cục × loại sự kiện (nguồn <c>AgencyWebEventDaily</c>),
            nguồn truy cập / trang (sự kiện thô). Branch.Manager chỉ thấy bưu cục mình.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.ExportReport(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyWebReportQuery,System.String)">
            <summary>
            Xuất CSV (UTF-8 BOM, ô chữ chống công thức) một bảng của báo cáo: <c>view</c> = agencies | daily | sources | pages.
            Thành công trả file; lỗi trả vỏ JSON đúng HTTP status như mọi endpoint của miền.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.SetRoutes(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyRoutesSetModel)">
            <summary>Thay toàn bộ tuyến. 422 INVALID_ROUTE_PAGE nếu Product không phải trang dich-vu/.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.UpsertStaff(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyStaffUpsertModel)">
            <summary>Thêm/sửa nhân sự hiển thị.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.DeleteStaff(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyStaffDeleteModel)">
            <summary>Gỡ nhân sự hiển thị.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.ReorderStaff(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyStaffReorderModel)">
            <summary>Sắp lại thứ tự mọi nhân sự hiển thị trong một phiên bản — gửi đủ đúng tập nhân sự hiện có.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.UploadMedia(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaUploadModel)">
            <summary>
            Tải MỘT ảnh (multipart/form-data: <c>File</c> + các trường của <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaUploadModel"/>). Loại ảnh xét
            theo nội dung (JPEG/PNG/WebP), ≤ 10 MB, bỏ EXIF/GPS, tên file server sinh. Branch.Manager tải lên → ảnh chờ duyệt.
            422 INVALID_MEDIA khi file giả/quá lớn; 403 FORBIDDEN_FIELD Media khi không có quyền.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.UpdateMedia(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaUpdateModel)">
            <summary>Sửa vai / alt / chú thích / cờ ảnh thật / thứ tự của một ảnh. 404 MEDIA_NOT_FOUND nếu ảnh không thuộc bưu cục.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.DeleteMedia(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaDeleteModel)">
            <summary>Gỡ một ảnh (xoá mềm) + gỡ tham chiếu ảnh Open Graph / chân dung nhân sự trong cùng transaction.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.ReorderMedia(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaReorderModel)">
            <summary>Sắp lại thứ tự mọi ảnh của một vai. Branch.Manager chỉ sắp được thư viện ảnh (Gallery).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.ApproveMedia(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaApproveModel)">
            <summary>Duyệt / bỏ duyệt ảnh — chỉ ảnh đã duyệt lên trang công khai và được tính điều kiện công bố #5.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.MediaPreview(System.Int32,System.String)">
            <summary>
            Xem ảnh CHỜ DUYỆT (nợ BC-14): file không nằm trong thư mục media công khai; <c>Get</c> cấp cho người đã qua phạm
            vi bưu cục một URL tới đây kèm vé ký HMAC hết hạn sau 1 giờ. Không đăng nhập vì thẻ <c>&lt;img&gt;</c> không gửi
            được header Authorization — vé chính là quyền. Sai vé/hết hạn/ảnh đã gỡ → 404 như nhau.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.ChangeSlug(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileChangeSlugModel)">
            <summary>Đổi slug. 409 SLUG_TAKEN nếu trùng hồ sơ khác hoặc lịch sử slug của bưu cục khác; 422 INVALID_SLUG.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.Versions(System.Int32,System.Int32,System.Int32)">
            <summary>Lịch sử phiên bản (không kèm ảnh chụp), mới nhất trước; <c>start</c>/<c>pageSize</c> phân trang (mặc định 50, tối đa 200).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.GetVersion(System.Int32,System.Int32)">
            <summary>Một phiên bản kèm ảnh chụp — để xem trước khi khôi phục. 404 VERSION_NOT_FOUND.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.RestoreVersion(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileRestoreModel)">
            <summary>
            Khôi phục nội dung một phiên bản thành phiên bản MỚI. Không đổi trạng thái công bố, slug, ảnh. Phần dữ liệu cũ vi
            phạm luật hiện hành giữ nguyên hiện tại, liệt kê ở <c>Notices</c>.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.MediaRequestLimitBytes">
            <summary>Trần một request tải ảnh: ảnh 10 MB + các trường form + vỏ multipart.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.Lookups">
            <summary>
            Danh mục chọn: tỉnh bộ 2 cấp, trang tuyến, loại hàng, chi nhánh chưa có hồ sơ (chỉ trả cho người có Update).
            Mở cho mọi role của các trang dùng nó — danh sách (Search), chi tiết (Get/ManageOwn), hộp thoại tạo hồ sơ (Update);
            dữ liệu không nhạy cảm.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.AgencyProfileController.NavPermissions">
            <summary>
            Cờ mức trang. CỐ Ý không gác role (rule <c>quyen-hien-thi</c>): câu "tôi được thấy gì" phải trả lời được cho cả
            người không có quyền nào — họ nhận toàn false.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Network.FranchiseAdminController">
            <summary>
            Trang "Quản trị nhượng quyền" — gộp Bảng giá nhượng quyền, Quản trị bảng giá, Nội dung cổng và Cấu hình trợ lý thành
            bốn tab, chỉ Founder và nhóm "Quản lý mạng lưới" xem được (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseAdminNavPermissions"/>).
            </summary>
            <remarks>
            Không có endpoint dữ liệu riêng: mỗi tab gọi đúng controller của màn cũ (<c>FranchisePrice</c>,
            <c>FranchisePortalSection</c>, <c>FranchisePortalFile</c>, <c>FranchisePortalAssistant</c>). Menu
            <c>mang-luoi/quan-tri-nhuong-quyen</c> khai đúng role của cờ trang (<c>GopMenuQuanTriNhuongQuyen.sql</c>) — đổi role ở
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseAdminNavPermissions"/> thì sửa cả menu.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseAdminController.GetNavPermissions">
            <summary>
            Cờ trang và cờ từng tab trong MỘT lời gọi. CỐ Ý không gác role (rule <c>quyen-hien-thi</c>): người không có quyền
            vẫn hỏi được và nhận toàn <c>false</c>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Network.FranchiseBusinessPlanController">
            <summary>
            Tham số mục "Kế hoạch kinh doanh" của cổng nhượng quyền (GĐ M, plan cổng §3.13, §6.24) — màn
            <c>/mang-luoi/bang-gia-nhuong-quyen/ke-hoach</c>: năm dòng sản lượng theo bậc phường + bộ tham số chung + ô tính thử.
            Dữ liệu nội bộ, chỉ phục vụ SPA quản trị.
            </summary>
            <remarks>
            Cùng hai bó quyền với bảng giá phường (§6.24 mục 5 — không role mới):
            <list type="bullet">
            <item><c>FranchisePrice.Export</c> — xem + tính thử; <c>FranchisePrice.Manage</c> — xem, tính thử và sửa.</item>
            </list>
            Menu <c>mang-luoi/bang-gia-nhuong-quyen/ke-hoach</c> khai đúng hợp hai role này (<c>SeedMenuKeHoachKinhDoanh.sql</c>).
            Service kiểm lại role — attribute ở đây là lớp đầu, không phải lớp duy nhất. Tính thử không nhận Id mã truy cập nào.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseBusinessPlanController.GetNavPermissions">
            <summary>
            Cờ hiển thị cho giao diện. CỐ Ý không gác role (rule <c>quyen-hien-thi</c>): người không có quyền nào vẫn hỏi
            được và nhận toàn <c>false</c> để giao diện ẩn nút.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseBusinessPlanController.Get">
            <summary>Cả bộ tham số kèm dấu phiên bản cho form sửa.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseBusinessPlanController.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseBusinessPlanUpdateModel)">
            <summary>Sửa cả bộ (năm bậc + tham số) trong một lần; dấu <c>Stamp</c> lệch → từ chối.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseBusinessPlanController.Preview(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseBusinessPlanPreviewModel)">
            <summary>Tính thử với số phường mỗi bậc + tham số đang sửa — không ghi gì, không đọc mã nào.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Network.FranchiseLeadController">
            <summary>
            Đăng ký tư vấn nhượng quyền bưu cục — từ website (<c>/nhuong-quyen</c>) hoặc nhân viên nhập tay cho người nhắn
            tin, gọi tổng đài — tách khỏi lead khách gửi hàng (docs/plan-nhuong-quyen-website.md §3.1, §6.2).
            </summary>
            <remarks>
            Hai bó quyền (seed <c>SeedRoleLeadNhuongQuyen.sql</c>):
            <list type="bullet">
            <item><c>FranchiseLead.Search</c> — xem, sửa thông tin, đổi trạng thái đăng ký MÌNH phụ trách; nhập tay đăng ký
            mới (tự phụ trách).</item>
            <item><c>FranchiseLead.Manage</c> — thấy tất cả, giao người phụ trách, xuất Excel.</item>
            </list>
            Phạm vi ép trong service (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadNavPermissions.ApplyScope(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},System.Collections.Generic.IReadOnlyCollection{System.String},System.Int32)"/>), không dựa vào giao diện:
            đăng ký ngoài phạm vi trả 404 như không tồn tại. Đổi role ở đây thì sửa cả <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadNavPermissions"/>.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseLeadController.GetNavPermissions">
            <summary>
            Cờ hiển thị cho giao diện. CỐ Ý không gác role (rule <c>quyen-hien-thi</c>): người không có quyền nào
            vẫn hỏi được và nhận toàn <c>false</c> để giao diện ẩn nút.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseLeadController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Danh sách đăng ký trong phạm vi người gọi. <c>Search.PredicateObject</c>: <c>globalSearch</c>, <c>status</c>,
            <c>provinceCode</c>, <c>picId</c> (0 = chưa giao), <c>channel</c>, <c>fromDate</c>, <c>toDate</c> (ngày gửi),
            <c>updatedFromDate</c>, <c>updatedToDate</c> (ngày cập nhật gần nhất), <c>portalSeenFromDate</c>, <c>portalSeenToDate</c>
            (ngày khách vào xem Cổng nhượng quyền gần nhất, §6.28) — đều <c>yyyy-MM-dd</c>; <c>idleMinDays</c>,
            <c>idleMaxDays</c>, <c>openOnly</c> (khoá của ô báo cáo tồn đọng, <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadSearchFilter"/>).
            <c>Sort.Predicate</c>: <c>CreatedTime</c> (mặc định, mới trước), <c>UpdatedTime</c>, <c>PortalLastSeenAt</c>, <c>Id</c>,
            <c>FullName</c>, <c>Status</c>, <c>ProvinceName</c>, <c>PicUserName</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseLeadController.GetBacklog(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Báo cáo tồn đọng (tab "Tồn đọng" của màn <c>/dang-ky-nhuong-quyen</c>): trạng thái × thời gian chờ theo tỉnh
            đăng ký, và tỉnh × trạng thái — trong phạm vi người gọi, cùng bộ lọc với <c>search</c> (thường là
            <c>channel</c>, <c>picId</c>, <c>fromDate</c>/<c>toDate</c>). Bấm vào ô thì giao diện gọi <c>search</c> thêm
            khoá <c>status</c>, <c>provinceCode</c>, <c>idleMinDays</c>/<c>idleMaxDays</c>, <c>openOnly</c> của ô đó.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseLeadController.GetStatusTimeline(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadTimelineModel)">
            <summary>
            Các đoạn trạng thái theo thời gian của nhiều đăng ký (<c>{ Ids: [...] }</c>, tối đa 600) — thanh của biểu đồ Gantt
            trang lịch hẹn (plan cổng §6.30). Id ngoài phạm vi người gọi bị bỏ qua: kết quả chỉ có đăng ký người gọi xem được.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseLeadController.GetFilterOptions">
            <summary>
            Danh mục cho ô lọc và form nhập tay: trạng thái, tỉnh (kèm <c>khac</c>), tình trạng doanh nghiệp, kênh tiếp
            nhận — giao diện đọc ở đây, không chép danh sách sang JS. Cùng bó role với <c>search</c> vì chỉ có nghĩa khi danh sách đọc được.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseLeadController.GetById(System.Int32)">
            <summary>Chi tiết một đăng ký (kèm câu đồng ý, UTM, trang gửi); 404 khi không có hoặc ngoài phạm vi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseLeadController.GetHistory(System.Int32)">
            <summary>
            Lịch sử cập nhật của một đăng ký, mới nhất trước: tạo, sửa thông tin, đổi trạng thái, giao người phụ trách,
            ghi chú. Cùng phạm vi với <c>{id}</c> — 404 khi không có hoặc ngoài phạm vi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseLeadController.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadCreateModel)">
            <summary>
            Nhập tay một đăng ký cho người nhắn tin hoặc gọi tổng đài; trả <c>Id</c> của bản ghi mới. Người chỉ có
            <c>FranchiseLead.Search</c> tự phụ trách đăng ký mình nhập (<c>PicId</c> gửi lên bị bỏ qua).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseLeadController.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadModel)">
            <summary>Sửa thông tin người đăng ký (không đổi trạng thái, người phụ trách).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseLeadController.UpdateStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadStatusModel)">
            <summary>Đổi trạng thái kèm ghi chú.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseLeadController.Assign(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadAssignModel)">
            <summary>Giao người phụ trách (<c>PicId</c> rỗng/0 = bỏ giao).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseLeadController.AssignMany(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadAssignManyModel)">
            <summary>
            Giao cùng một người phụ trách cho nhiều đăng ký (<c>{ Ids: [...], PicId }</c>, tối đa
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.MaxAssignLeads"/>) — các dòng đang chọn trên danh sách. Id ngoài phạm vi bị bỏ
            qua và đếm riêng; người được giao không hợp lệ thì không đăng ký nào đổi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseLeadController.GetAssignees">
            <summary>Người có thể được giao: giữ Search hoặc Manage, còn làm việc.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseLeadController.Export(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Xuất Excel theo cùng bộ lọc với danh sách (bỏ qua phân trang).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Network.FranchisePackageTierController">
            <summary>
            Tham số bốn bậc gói vùng phủ POINT / HUB / ZONE / REGION (GĐ K, plan cổng §6.16, §6.17) — màn
            <c>/mang-luoi/bang-gia-nhuong-quyen/goi</c>. Dữ liệu nội bộ, chỉ phục vụ SPA quản trị.
            </summary>
            <remarks>
            Cùng hai bó quyền với bảng giá phường (<see cref="T:Ladaer.BackEnd.Controllers.Network.FranchisePriceController"/>):
            <list type="bullet">
            <item><c>FranchisePrice.Export</c> — xem; <c>FranchisePrice.Manage</c> — xem và sửa.</item>
            </list>
            Menu <c>mang-luoi/bang-gia-nhuong-quyen/goi</c> khai đúng hợp hai role này (<c>SeedMenuGoiGiaNhuongQuyen.sql</c>,
            đổi nhãn ở <c>M202610151520</c>). Service kiểm lại role — attribute ở đây là lớp đầu, không phải lớp duy nhất.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePackageTierController.GetNavPermissions">
            <summary>
            Cờ hiển thị cho giao diện. CỐ Ý không gác role (rule <c>quyen-hien-thi</c>): người không có quyền nào vẫn hỏi
            được và nhận toàn <c>false</c> để giao diện ẩn nút.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePackageTierController.List">
            <summary>Mọi bậc theo thứ tự ngưỡng kèm dấu phiên bản cho form sửa.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePackageTierController.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePackageTierUpdateModel)">
            <summary>Sửa cả bộ bậc trong một lần — dải phường các bậc phải liền nhau.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController">
            <summary>
            Mã truy cập Cổng nhượng quyền: người phụ trách một đăng ký nhượng quyền tạo mã cho khách đó, mở/khoá từng mục,
            gia hạn, thu hồi, xem dấu vết (docs/plan-cong-nhuong-quyen.md §3.2, GĐ A; mã gắn vào đăng ký từ GĐ L, §6.23 — giao
            diện là khối "Mã truy cập" của màn Đăng ký nhượng quyền).
            </summary>
            <remarks>
            Hai bó quyền (seed <c>SeedCongNhuongQuyen.sql</c>; nhóm quyền "Quản lý mạng lưới" / "Mạng lưới 2" — §6.23):
            <list type="bullet">
            <item><c>FranchisePortal.Sale</c> — mọi thao tác trên mã của đăng ký MÌNH phụ trách.</item>
            <item><c>FranchisePortal.Manage</c> — thấy mọi mã.</item>
            </list>
            Phạm vi ép trong service (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalNavPermissions.ApplyScope(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchisePortalAccessCode},System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},System.Collections.Generic.IReadOnlyCollection{System.String},System.Int32)"/>), không dựa vào giao diện: mã
            ngoài phạm vi trả 404 như không tồn tại. Mã rõ chỉ có ở <c>create</c> và <c>{id}</c> — luôn kèm <c>no-store</c>.
            Đổi role ở đây thì sửa cả <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalNavPermissions"/> và <c>AllowRoles</c> của menu.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.GetNavPermissions">
            <summary>
            Cờ hiển thị cho giao diện. CỐ Ý không gác role (rule <c>quyen-hien-thi</c>): người không có quyền nào
            vẫn hỏi được và nhận toàn <c>false</c> để giao diện ẩn nút.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Danh sách mã trong phạm vi người gọi — ô chọn mã "Hỏi thử" của màn Cấu hình trợ lý. <c>Search.PredicateObject</c>:
            <c>globalSearch</c>, <c>status</c> (<c>active</c> / <c>expiring</c> / <c>expired</c> / <c>revoked</c>),
            <c>provinceCode</c>, <c>priceScope</c> (<c>none</c> / <c>below</c>), <c>fromDate</c>, <c>toDate</c>
            (<c>yyyy-MM-dd</c>). <c>Sort.Predicate</c>: <c>CreatedTime</c> (mặc định, mới trước), <c>ExpiresAt</c>,
            <c>CustomerName</c>, <c>LastAccessAt</c>. Mỗi dòng kèm tóm tắt phạm vi giá
            (<c>PriceScopeState</c>, <c>PriceScopeLabel</c>, <c>PriceScopeProvinceName</c>).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.GetById(System.Int32)">
            <summary>Chi tiết một mã kèm MÃ RÕ, trạng thái mở/khoá từng mục, lịch sử gần nhất; 404 khi không có hoặc ngoài phạm vi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAccessCodeCreateModel)">
            <summary>
            Tạo mã cho khách của một đăng ký nhượng quyền; trả mã rõ <c>NQ-XXXX-XXXX</c> và <c>Id</c>. Chỉ người phụ trách
            đăng ký tạo được, và đăng ký chưa có mã chưa thu hồi (§6.23 mục 3).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.Unlock(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionIdsModel)">
            <summary>Mở các mục cho mã (chỉ mục đang bật).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.Lock(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionIdsModel)">
            <summary>Khoá lại các mục của mã.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.SetPriceScope(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalPriceScopeModel)">
            <summary>
            Gắn phạm vi giá: các phường/xã (được nhiều tỉnh); gửi danh sách trống = gỡ. Gói vùng phủ tự xếp theo số phường
            (GĐ K). Khách chỉ xem lại đúng thứ đã gắn ở mục bảng giá của cổng. CỐ Ý dùng role của cổng, không đòi thêm
            <c>FranchisePrice.*</c>: sale là người báo giá cho khách của mình (plan cổng §6.10, CNQ-45).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.GetPriceProvinces">
            <summary>
            Tỉnh/thành phố có giá ở phiên bản giá hiện hành (không đòi vùng phủ — plan cổng §6.26) cho ô chọn của khối
            "Phạm vi giá". Ba nguồn <c>price-options/*</c> gác bằng role của cổng như <c>price-scope</c> — sale không có
            <c>FranchisePrice.*</c> vẫn chọn được phường (CNQ-39).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.GetPriceTiers">
            <summary>Bốn bậc gói vùng phủ — drawer báo gói theo số phường đang chọn (GĐ K).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.GetPriceWards(System.Int32,System.String)">
            <summary>Phường/xã của một tỉnh CÓ GIÁ ở phiên bản giá hiện hành; <paramref name="q"/> lọc theo tên (không dấu).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.UnlockAll(System.Int32)">
            <summary>Mở mọi mục đang bật cho mã.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.Extend(System.Int32)">
            <summary>Gia hạn thêm 7 ngày, tính từ mốc muộn hơn giữa bây giờ và hạn hiện tại.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.Revoke(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalRevokeModel)">
            <summary>Thu hồi mã ngay lập tức — mọi phiên đang mở của khách bị đóng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.GetHistory(System.Int32)">
            <summary>Lịch sử thao tác của một mã, mới nhất trước; 404 khi không có hoặc ngoài phạm vi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.GetEvents(System.Int32,System.Int32,System.Int32)">
            <summary>
            Dấu vết của khách dùng mã này: một trang sự kiện (mới trước) + tổng thời gian xem theo mục; 404 khi không có
            hoặc ngoài phạm vi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAccessCodeController.GetChat(System.Int32,System.Int32,System.Int32)">
            <summary>
            Transcript hỏi-đáp của khách với trợ lý AI (tab Hỏi đáp, GĐ G): một trang tin nhắn (mới trước) + số câu đã hỏi;
            404 khi không có hoặc ngoài phạm vi — sale chỉ đọc được transcript của mã thuộc đăng ký mình phụ trách.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Network.FranchisePortalAssistantController">
            <summary>
            Màn "Cấu hình trợ lý" của Cổng nhượng quyền (docs/plan-cong-nhuong-quyen.md §3.6, GĐ G): nhà cung cấp / model,
            hạn mức câu hỏi, trần ngữ cảnh, văn bản nền, thông báo sale, và "Hỏi thử". Chỉ <c>FranchisePortal.Manage</c>
            (Founder vượt mọi kiểm tra) — kiểm lần hai trong service bằng cờ <c>CanConfigure</c>. Không endpoint nào trả API key.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAssistantController.GetNavPermissions">
            <summary>
            Cờ hiển thị cho giao diện. CỐ Ý không gác role (rule <c>quyen-hien-thi</c>): người không có quyền vẫn hỏi được
            và nhận <c>false</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalAssistantController.AskTest(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAssistantTestModel,System.Threading.CancellationToken)">
            <summary>
            Hỏi trợ lý một câu với ngữ cảnh của một mã — mã ngoài phạm vi trả 404. Gọi nhà cung cấp trả phí: câu hỏi tối đa
            1.000 ký tự, trần thời gian 60 giây; không lưu transcript, không trừ lượt của khách.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Network.FranchisePortalFileController">
            <summary>
            Tệp riêng tư của Cổng nhượng quyền — tài liệu (pdf/xlsx/docx) và video tệp (mp4/webm) — lưu trên ổ đĩa dưới
            <c>AppConfig FranchisePortal.PrivateRootPath</c>, ngoài web root của media (docs/plan-cong-nhuong-quyen.md §6.5).
            </summary>
            <remarks>
            Controller này chỉ tải lên / liệt kê / xoá cho biên tập viên; KHÔNG có đường đọc nội dung tệp — khách đọc qua
            <c>/thong-tin-nhuong-quyen/tep/{id}</c> của website sau khi kiểm mã truy cập (GĐ C). Mọi action đòi
            <c>FranchisePortal.Content</c> hoặc <c>FranchisePortal.Manage</c>.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.Network.FranchisePortalFileController.DocumentRequestLimitBytes">
            <summary>Trần request = trần tệp + 1 MB cho phần còn lại của multipart.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalFileController.UploadDocument(Microsoft.AspNetCore.Http.IFormFile,System.Nullable{System.Int32},System.String,System.Threading.CancellationToken)">
            <summary>
            Tải lên một tài liệu (multipart, khoá <c>file</c>): pdf, xlsx, docx — tối đa 30 MB. Kiểm bằng nội dung tệp,
            không tin phần mở rộng. PDF được trích văn bản cho trợ lý AI.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalFileController.UploadVideo(Microsoft.AspNetCore.Http.IFormFile,System.Nullable{System.Int32},System.String,System.Threading.CancellationToken)">
            <summary>Tải lên một video tệp (multipart, khoá <c>file</c>): mp4, webm — tối đa 300 MB.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalFileController.List(System.Nullable{System.Int32})">
            <summary>Tệp của một mục; bỏ <c>sectionId</c> = mọi tệp.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalFileController.Delete(System.Int32)">
            <summary>Xoá một tệp (bản ghi và tệp trên đĩa). Từ chối khi tệp đang là audio thuyết minh của một mục.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController">
            <summary>
            Mục của Cổng nhượng quyền riêng tư <c>/thong-tin-nhuong-quyen</c> (docs/plan-cong-nhuong-quyen.md §3.4, GĐ A):
            danh sách, siêu dữ liệu, thứ tự, bật/tắt; và từ GĐ E khối nội dung của mục — đọc / lưu bản đang sửa, xuất bản, cấp
            link xem trước (§3.9, §6.8). Khối vẫn nằm ở topic vật chủ nhưng KHÔNG đi qua <c>api/Topic</c> nữa (CNQ-12).
            </summary>
            <remarks>
            Mọi action dữ liệu đòi <c>FranchisePortal.Content</c> hoặc <c>FranchisePortal.Manage</c> (seed
            <c>SeedCongNhuongQuyen.sql</c>). Đổi role ở đây thì sửa cả <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalNavPermissions"/> và
            <c>AllowRoles</c> của menu <c>cong-nhuong-quyen/noi-dung</c>.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController.PortalOffPreviewMessage">
            <summary>Câu từ chối cấp link xem trước khi công tắc cổng đang tắt (website trả 404 cho mọi đường của cổng).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController.GetNavPermissions">
            <summary>
            Cờ hiển thị cho giao diện. CỐ Ý không gác role (rule <c>quyen-hien-thi</c>): người không có quyền nào
            vẫn hỏi được và nhận toàn <c>false</c> để giao diện ẩn nút.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController.List">
            <summary>Mọi mục cổng theo thứ tự hiển thị, kèm trạng thái xuất bản và thuyết minh.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController.GetFormOptions">
            <summary>Bộ icon và các đoạn đường dẫn dành riêng cho form mục — giao diện đọc ở đây, không chép sang JS.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController.GetById(System.Int32)">
            <summary>Chi tiết một mục; 404 khi không có.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionModel)">
            <summary>Tạo một mục nội dung (kèm topic vật chủ của nó); trả <c>Id</c> của mục mới.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionModel)">
            <summary>Sửa tiêu đề, đường dẫn, tóm tắt, icon của mục — không chạm khối nội dung.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController.Reorder(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalReorderModel)">
            <summary>Sắp lại thứ tự: gửi Id của TOÀN BỘ mục theo thứ tự mới.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController.Deactivate(System.Int32)">
            <summary>Tắt mục: ẩn với mọi mã truy cập, kể cả mã đã được mở mục này.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController.Activate(System.Int32)">
            <summary>Bật lại mục — mã nào đã được mở mục này thì xem lại được ngay.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController.GetBlocks(System.Int32)">
            <summary>
            Bản ĐANG SỬA của khối nội dung một mục, kèm bộ khối của mục, dấu phiên bản, trạng thái xuất bản và cảnh báo
            khối trỏ tới tệp không còn dùng được. Mục bảng giá trả <c>HasBlocks = false</c>. 404 khi không có mục.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController.SaveBlocks(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionBlocksModel)">
            <summary>
            Lưu bản đang sửa: thay TOÀN BỘ khối của mục. Không đổi gì trên trang khách đang thấy. Khối sai, hoặc khối trỏ
            tới tệp không thuộc đúng mục này, trả 400 kèm câu chỉ rõ khối thứ mấy. <c>Version</c> là dấu
            <c>DraftVersion</c> lấy từ <c>GET {id}/blocks</c> — có người lưu khối sau đó thì không ghi
            (<c>DraftChanged = true</c>) thay vì đè mất bản của họ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController.Publish(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalPublishModel)">
            <summary>
            Xuất bản bản đang sửa thành bản khách thấy trên cổng (cần ít nhất 1 khối). <c>Version</c> là dấu
            <c>DraftVersion</c> lấy từ <c>GET {id}/blocks</c> — có người lưu khối sau đó thì không xuất bản
            (<c>DraftChanged = true</c>).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController.PreviewToken(System.Int32)">
            <summary>
            Cấp link xem trước bản ĐANG SỬA của đúng mục này trên website (hạn 30 phút; link cấp trước vẫn sống). Link
            không cần mã truy cập và không ghi dấu vết; chỉ mở được khi cổng đang bật — công tắc tắt thì từ chối kèm câu
            giải thích, thay vì đưa biên tập viên tới trang 404 chung của website (bấm thật GĐ I+J).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePortalSectionController.UploadPicture(Microsoft.AspNetCore.Http.IFormFile)">
            <summary>
            Tải một ảnh cho khối nội dung của mục (slide, bộ ảnh, ảnh bìa video…) — multipart, khoá <c>file</c>. Ảnh đi
            media công khai như ảnh của topic (plan §3.4, nợ CNQ-3); role của cổng là đủ, không cần
            <c>Picture.UploadTopicContentPicture</c>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Network.FranchisePriceController">
            <summary>
            Bảng giá nhượng quyền bưu cục — dữ liệu nội bộ, chỉ phục vụ SPA quản trị.
            </summary>
            <remarks>
            Hai bó quyền, không mượn miền khác (seed <c>SeedRoleBangGiaNhuongQuyen.sql</c>):
            <list type="bullet">
            <item><c>FranchisePrice.Manage</c> — tải mẫu, kiểm/lưu file giá, lịch sử phiên bản, thêm/sửa tay từng dòng (chỉ quản trị).</item>
            <item><c>FranchisePrice.Export</c> — chọn tỉnh, phường/xã, xuất bảng giá (sale nhượng quyền, quản lý khu vực); Manage cũng xuất được.</item>
            </list>
            Menu <c>mang-luoi/bang-gia-nhuong-quyen</c> và <c>.../quan-tri</c> khai đúng hợp của các role này
            (<c>SeedMenuBangGiaNhuongQuyen.sql</c>) — đổi role ở đây thì sửa cả script menu và <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavPermissions"/>.
            File trả thẳng qua <c>File()</c> với <c>no-store</c>, không lưu ra <c>wwwroot</c>: giá nhượng quyền không được nằm ở URL công khai.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePriceController.GetNavPermissions">
            <summary>
            Cờ hiển thị cho giao diện. CỐ Ý không gác role (rule <c>quyen-hien-thi</c>): người không có quyền nào
            vẫn hỏi được và nhận toàn <c>false</c> để giao diện ẩn nút.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePriceController.GetTemplateProvinces">
            <summary>Mọi tỉnh/thành phố 2 cấp để chọn khi tải mẫu; <c>IsDefault</c> = thuộc vùng phủ hiện tại.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePriceController.DownloadTemplate(System.Int32[])">
            <summary>Tải file mẫu gồm toàn bộ phường/xã của các tỉnh được chọn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePriceController.Preview(Microsoft.AspNetCore.Http.IFormFile)">
            <summary>Kiểm toàn bộ file. Có lỗi → danh sách lỗi theo dòng; không lỗi → bản xem trước. Không ghi gì.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePriceController.Import(Microsoft.AspNetCore.Http.IFormFile)">
            <summary>Xác nhận: kiểm lại toàn bộ file rồi lưu thành phiên bản mới, đặt làm hiện hành.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePriceController.GetVersions">
            <summary>Lịch sử phiên bản, mới nhất trước — phiên bản cũ giữ lại để tra.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePriceController.GetCurrent">
            <summary>Phiên bản hiện hành (mã, ngày hiệu lực, tham số) — đầu trang xuất; 204 khi chưa upload lần nào.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePriceController.GetExportProvinces">
            <summary>Các tỉnh có phường/xã có giá trong phiên bản hiện hành.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePriceController.SearchWards(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Phường/xã có giá của một tỉnh. <c>Search.PredicateObject</c>: <c>ProvinceId</c> (bắt buộc), <c>Keyword</c>
            (tìm theo tên, có dấu hay không dấu đều ra).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePriceController.Export(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceExportModel)">
            <summary>Xuất bảng giá Excel. Không tích phường/xã nào → cả tỉnh, không có phần tổng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePriceController.GetLine(System.Int32)">
            <summary>Chi tiết một dòng giá của phiên bản hiện hành để nạp form sửa; 404 khi phường/xã không có giá.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePriceController.GetUnpricedWards(System.Int32)">
            <summary>Phường/xã 2 cấp của một tỉnh chưa có giá trong phiên bản hiện hành — ô chọn của form thêm dòng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePriceController.CreateLine(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceLineModel)">
            <summary>Thêm tay một dòng giá vào phiên bản hiện hành. Ô sai → 400 kèm <c>Errors[]</c> theo tên trường.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchisePriceController.UpdateLine(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceLineModel)">
            <summary>Sửa tay một dòng giá của phiên bản hiện hành; <c>Stamp</c> lệch (người khác vừa sửa) → 400.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Network.FranchiseSettlementController">
            <summary>Phiếu đối soát tháng bưu cục nhượng quyền (docs/bang-gia-noi-bo/SPEC.md §3.6, §3.8 <c>api/FranchiseSettlement</c>).</summary>
            <remarks>Bưu cục chỉ thấy / xác nhận / tải bảng kê phiếu của chính mình — service ép phạm vi phía máy chủ, kể cả đường xuất Excel.</remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseSettlementController.GetNavPermissions">
            <summary>Cờ hiển thị — không đòi role.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseSettlementController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách phiếu. Khoá lọc: agencyId (bưu cục bị ép về mình), period (yyyyMM), status.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseSettlementController.Get(System.Int32)">
            <summary>Chi tiết phiếu (tổng theo loại, bảng kê hai chiều, phụ lục K1).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseSettlementController.Agencies">
            <summary>Bưu cục nhượng quyền cho ô lọc / hộp lập phiếu của kế toán LADA.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseSettlementController.Generate(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementGenerateModel)">
            <summary>Lập / làm mới nháp cho một kỳ đã qua.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseSettlementController.Publish(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementNoteModel)">
            <summary>Phát hành (Nháp → Chờ xác nhận).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseSettlementController.Confirm(System.Int32)">
            <summary>Bưu cục xác nhận.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseSettlementController.Lock(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementNoteModel)">
            <summary>Khoá (dòng Ví → đã đối soát).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseSettlementController.MarkInvoiced(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementInvoiceModel)">
            <summary>Đánh dấu đã lập hoá đơn (ghi số hoá đơn hai chiều, không tích hợp hoá đơn điện tử).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseSettlementController.Export(System.Int32,System.Int32)">
            <summary>Tải bảng kê: 0 = đủ 4 sheet, 1 = LADA → bưu cục, 2 = bưu cục → LADA, 3 = phụ lục K1, 4 = chi tiết.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController">
            <summary>
            Ví bưu cục nhượng quyền (docs/bang-gia-noi-bo/SPEC.md §3.8 <c>api/FranchiseWallet</c>).
            </summary>
            <remarks>
            Bưu cục (role View) chỉ thấy ví của chính mình — service ép bộ lọc bưu cục về bưu cục của người gọi ở phía máy chủ,
            mọi yêu cầu ví khác trả 403. Kế toán LADA (Manage) thấy mọi ví, tạo điều chỉnh, duyệt lần 1; Approve duyệt lần 2.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.GetNavPermissions">
            <summary>Cờ hiển thị — không đòi role (rule quyen-hien-thi).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Dòng Ví (SmartTable). Khoá lọc: agencyId (bưu cục bị ép về ví mình), orderCode, orderId, entryType, status, eventAtStart, eventAtEnd.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.Get(System.Int64)">
            <summary>Một dòng Ví kèm cách tính.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.Summary(System.Nullable{System.Int32},System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset})">
            <summary>Tổng tạm tính / đã chốt theo loại dòng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.Wallets">
            <summary>Danh sách ví của mọi bưu cục nhượng quyền (LADA).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.EnableWallet(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletEnableModel)">
            <summary>
            Bật ví cho một chi nhánh (Ví v2 §1.1): tạo <c>FranchiseWallet</c> Active + <c>EnabledAt</c>, tham số mặc định; chi nhánh LADA
            không chặn xuất kho (§6 mục 15). Chỉ role Config (kế toán trưởng) / Founder. Từ đây planner mới sinh dòng cho chi nhánh đó.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.CreateAdjustment(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseAdjustmentCreateModel)">
            <summary>Tạo điều chỉnh tay (chờ duyệt).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.ApproveAdjustment(System.Int64)">
            <summary>Duyệt điều chỉnh tay (lần 1: Manage / Approve; lần 2 từ ngưỡng: Approve, khác người tạo và người duyệt lần 1).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.RejectAdjustment(System.Int64,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseAdjustmentRejectModel)">
            <summary>Từ chối điều chỉnh tay.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.Issues(System.Nullable{Lada.Framework.Data.Domains.Network.FranchiseLedgerIssueKind},System.Nullable{System.Int32},System.Boolean,System.Nullable{System.DateTime},System.Nullable{System.DateTime})">
            <summary>Vấn đề ghi Ví đang mở (cần soát).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.Forecast(System.Int32)">
            <summary>Dự kiến phí nếu đơn giao thành công (Ví v2 plan §3.8.1, không ghi sổ); bưu cục chỉ đơn mình tham gia, chỉ dòng của mình.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.UpdateWalletConfig(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletConfigModel)">
            <summary>Sửa tham số + tài khoản nhận / ảo của một ví (Ví v2 plan §3.8.1) — role Config.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.WalletConfigHistory(System.Int32)">
            <summary>Lịch sử đổi cấu hình của một ví — role Config.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.Reconcile(System.Int32)">
            <summary>Đối chiếu lại Ví của một đơn ngay (không chờ job đêm).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.GetCustomerOwner(System.Int32)">
            <summary>Bưu cục sở hữu khách (màn khách hàng).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.SetCustomerOwner(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.CustomerOwnerAgencyModel)">
            <summary>Gán / bỏ bưu cục sở hữu khách (role sửa khách hàng) — SPEC §3.7, M14.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.CreateWithdrawal(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalCreateModel)">
            <summary>
            Chủ bưu cục tạo lệnh rút (Ví v2 §3.5): ví = bưu cục của người gọi, tài khoản nhận chụp từ ví — request không mang bưu cục hay tài
            khoản. Ví trừ ngay; không đủ điều kiện → từ chối nêu số tối đa được rút.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.CancelWithdrawal(System.Int32)">
            <summary>Chủ bưu cục huỷ lệnh rút còn chờ của bưu cục mình — ví hoàn ngay.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.TransferWithdrawal(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalTransferModel)">
            <summary>Kế toán quỹ xác nhận đã chuyển tiền lệnh rút.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.RejectWithdrawal(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalRejectModel)">
            <summary>Kế toán quỹ từ chối lệnh rút — hoàn ví (từ ngưỡng duyệt hai người: chờ người duyệt thứ hai).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.Withdrawals(System.Nullable{System.Int32},System.Nullable{Lada.Framework.Data.Domains.Network.FranchiseWithdrawalStatus})">
            <summary>Lệnh rút — bưu cục bị ép về ví mình; LADA (Manage / Approve / Treasury) lọc theo bưu cục.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.RecordDeposit(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseDepositCreateModel)">
            <summary>Kế toán quỹ ghi nhận tiền bưu cục nạp vào tài khoản LADA — ví cộng ngay (không có đường cho bưu cục tự nạp).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.Deposits(System.Nullable{System.Int32})">
            <summary>Khoản nạp — bưu cục bị ép về ví mình; LADA lọc theo bưu cục.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.ReturnFeeDebts(System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{Lada.Framework.Data.Domains.Network.FranchiseReturnFeeDebtStatus})">
            <summary>Đơn nợ cước đơn hoàn theo bưu cục sale / khách (mặc định: còn nợ + đang cấn trong phiếu) — bưu cục bị ép về ví mình.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.FranchiseWalletController.SettleReturnFeeDebtOutside(System.Int64,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseReturnFeeDebtSettleModel)">
            <summary>Kế toán ghi nhận bưu cục sale đã tự thu khoản nợ cước đơn hoàn ngoài ví — đóng nợ, không có E13.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Network.InternalPriceController">
            <summary>
            Bảng giá nội bộ cho bưu cục nhượng quyền: giá mua đơn / phí lấy / phí giao (docs/bang-gia-noi-bo/SPEC.md §3.8).
            </summary>
            <remarks>
            Attribute là lớp đầu, service kiểm lại role và phạm vi bưu cục (fail-closed) — bưu cục chỉ có role View thì chỉ
            xem được bản đang / sắp áp cho bưu cục của chính mình, mọi yêu cầu khác trả 403.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.InternalPriceController.GetNavPermissions">
            <summary>Cờ hiển thị — không đòi role (rule quyen-hien-thi).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.InternalPriceController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách phiên bản. Khoá lọc trong <c>Search.PredicateObject</c>: kind, status, agencyId, effectiveAt, keyword.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.InternalPriceController.Get(System.Int32)">
            <summary>Chi tiết một phiên bản (bưu cục: chỉ bản đang / sắp áp cho mình).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.InternalPriceController.Export(System.Int32)">
            <summary>Tải Excel một phiên bản — cùng luật xem như chi tiết (bưu cục: chỉ bản đang / sắp áp cho mình, không có giá niêm yết).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.InternalPriceController.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel)">
            <summary>Tạo nháp từ khung niêm yết hoặc sao chép bản khác.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.InternalPriceController.Update(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionUpdateModel)">
            <summary>Sửa nháp.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.InternalPriceController.Generate(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceGenerateModel)">
            <summary>Sinh theo hệ số.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.InternalPriceController.Approve(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceApproveModel)">
            <summary>Duyệt.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.InternalPriceController.Cancel(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceCancelModel)">
            <summary>Huỷ — chỉ người duyệt (SPEC §3.8 "approve/cancel: Approve", §3.10).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.InternalPriceController.SetEffectiveTo(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceEffectiveToModel)">
            <summary>Đặt / bỏ ngày ngừng áp dụng của bản đã duyệt.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.InternalPriceController.BalanceCheck(System.Nullable{System.Int32},System.Nullable{System.DateTime},System.Nullable{System.Int32})">
            <summary>Kiểm tra cân đối tại một ngày; <paramref name="draftVersionId"/> thay một bảng bằng bản nháp đang xem.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.InternalPriceController.Applicable(System.Nullable{System.Int32},System.Nullable{System.DateTime})">
            <summary>Ba bảng đang áp + sắp áp cho một bưu cục (bưu cục: chỉ bưu cục của mình).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.InternalPriceController.SuggestCode(Lada.Framework.Data.Domains.Network.InternalPriceTableKind,System.Nullable{System.DateTime})">
            <summary>Gợi ý mã phiên bản.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Network.InternalPriceController.Agencies">
            <summary>Bưu cục nhượng quyền để chọn phạm vi (endpoint riêng, không mượn Agency/* để người soạn khỏi cần role Agency.*).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.OrderBusiness.OrderFailReasonController">
            <summary>
            Controller quản lý lý do thất bại lấy/giao hàng (Admin)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.OrderBusiness.OrderFailReasonController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm lý do thất bại
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.OrderBusiness.OrderFailReasonController.GetById(System.Int32)">
            <summary>
            Lấy thông tin lý do thất bại theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.OrderBusiness.OrderFailReasonController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.OrderBusiness.OrderFailReasonModel)">
            <summary>
            Tạo mới hoặc cập nhật lý do thất bại
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.OrderBusiness.OrderFailReasonController.Delete(Ladaer.BackEnd.Infrastructures.DTO.Models.OrderBusiness.OrderFailReasonModel)">
            <summary>
            Xóa lý do thất bại (soft delete)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Orders.OrderAddressController">
            <summary>
            Controller xử lý các hoạt động liên quan đến địa chỉ đơn hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderAddressController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderAddressService,Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Orders.OrderAddressController"/>.
            </summary>
            <param name="orderAddressService">Dịch vụ xử lý địa chỉ đơn hàng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderAddressController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của một địa chỉ đơn hàng dựa trên ID.
            </summary>
            <param name="id">ID của địa chỉ đơn hàng.</param>
            <returns>Thông tin chi tiết của địa chỉ đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderAddressController.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel)">
            <summary>
            Cập nhật thông tin địa chỉ đơn hàng.
            </summary>
            <param name="model">Model chứa thông tin địa chỉ đơn hàng.</param>
            <returns>Kết quả của hoạt động cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderAddressController.UpdateCoord(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressCoordModel)">
            <summary>
            Cập nhật riêng định vị (toạ độ) của địa chỉ đơn hàng. Không đụng tới
            tỉnh/phường nên không kéo theo tính lại cước hay đổi bưu cục dự kiến.
            </summary>
            <param name="model">Toạ độ mới (để null cả Lat và Long để xoá định vị).</param>
            <returns>Kết quả của hoạt động cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderAddressController.ResolveMapLink(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.ResolveMapLinkModel)">
            <summary>
            Bóc toạ độ từ một link Google Maps. Dành cho link RÚT GỌN (maps.app.goo.gl):
            browser không đọc được Location header của redirect nên phải nhờ server.
            </summary>
            <param name="model">Link người dùng dán vào.</param>
            <returns>Toạ độ bóc được hoặc thông báo lỗi.</returns>
            <remarks>
            Nhận thêm role của sổ địa chỉ khách hàng: màn tạo đơn cũng ghim toạ độ cho
            CustomerAddress bằng chính ô dán link này, mà nhân viên ở đó chưa chắc có
            quyền sửa địa chỉ đơn hàng. Endpoint chỉ bóc toạ độ từ URL, không đọc/ghi
            dữ liệu nghiệp vụ nào nên mở thêm là an toàn.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Orders.OrderController">
            <summary>
            Controller để xử lý các hoạt động liên quan tới đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderController.#ctor(Microsoft.Extensions.Options.IOptions{Ladaer.BackEnd.Infrastructures.AppSettings.AppSetting},Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Orders.OrderController"/>.
            </summary>
            <param name="options">Tùy chọn cấu hình ứng dụng.</param>
            <param name="orderService">Dịch vụ xử lý đơn hàng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm đơn hàng theo các tham số cung cấp
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderController.SearchByAgency(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm đơn của bưu cục người đang đăng nhập — màn "Đơn hàng bưu cục" của chủ bưu cục.
            </summary>
            <remarks>
            Khoá <c>Scope</c> trong <c>Search.PredicateObject</c> chọn nhóm: 1 dự kiến lấy · 2 đã lấy · 3 dự kiến giao ·
            4 đã nhận từ kho tổng · 5 nhân sự bưu cục tạo. Các khoá lọc còn lại giống <c>Search</c>. Bưu cục lấy từ
            tài khoản (<c>User.AgencyId</c>), không nhận từ tham số; tài khoản chưa gắn bưu cục nhận danh sách rỗng.
            </remarks>
            <param name="param">Các tham số tìm kiếm.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderController.GetAgencyScope">
            <summary>
            Cờ hiển thị của màn "Đơn hàng bưu cục": xem được không, của bưu cục nào, kèm option bộ lọc trạng thái.
            </summary>
            <remarks>
            Cố ý chỉ cần đăng nhập, không đòi role (rule quyen-hien-thi): người không có quyền vẫn hỏi được và nhận
            <c>CanView = false</c>. Luật nằm ở hàm thuần <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyNavPermissions"/>.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderController.CreateOrder(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel)">
            <summary>
            Tạo mới một đơn hàng.
            </summary>
            <param name="model">Model chứa thông tin đơn hàng.</param>
            <returns>Kết quả của hoạt động tạo đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderController.Orderdetail(System.String)">
            <summary>
            Lấy thông tin chi tiết của đơn hàng dựa trên mã đơn hàng.
            </summary>
            <param name="code">Mã đơn hàng.</param>
            <returns>Thông tin chi tiết của đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderController.OrderdetailWithUnits(System.String)">
            <summary>
            Lấy thông tin chi tiết của đơn hàng theo mã đơn hàng với thông tin đơn vị do.
            </summary>
            <param name="code">Mã đơn hàng.</param>
            <returns>Thông tin chi tiết của đơn hàng với đơn vị do.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderController.Cancel(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Updates.UpdateStatusModel)">
            <summary>
            Hủy một đơn hàng.
            </summary>
            <param name="model">Model chứa thông tin đơn hàng cần hủy.</param>
            <returns>Kết quả của hoạt động hủy đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderController.RemoveCancel(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Updates.UpdateStatusModel)">
            <summary>
            Gỡ bỏ trạng thái hủy của một đơn hàng.
            </summary>
            <param name="model">Model chứa thông tin đơn hàng cần gỡ bỏ trạng thái hủy.</param>
            <returns>Kết quả của hoạt động gỡ bỏ trạng thái hủy.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderController.GetPaymentMethods">
            <summary>
            Lấy danh sách các phương thức thanh toán có sẵn
            </summary>
            <returns>Danh sách phương thức thanh toán</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderController.GetTimeFilterTypes">
            <summary>
            Lấy danh sách các loại thời gian có sẵn cho bộ lọc
            </summary>
            <returns>Danh sách các loại thời gian</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderController.ExportOrders(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel)">
            <summary>
            Xuất Excel danh sách đơn hàng
            </summary>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderController.DownloadFile(System.String)">
            <summary>
            Download file Excel đã xuất
            </summary>
            <param name="fileName">Tên file</param>
            <returns>File Excel</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderController.PrepareOrderListFilter(Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderListFilter)">
            <summary>
            Chuẩn bị dữ liệu bộ lọc danh sách đơn hàng
            </summary>
            <returns>Các danh sách option cho bộ lọc</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Orders.OrderExportController">
            <summary>
            Controller cho việc xuất Excel đơn hàng (Generic)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderExportController.ExportOrders(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel)">
            <summary>
            Xuất Excel đơn hàng với template được chỉ định
            </summary>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderExportController.ExportOrdersWithFilter(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel)">
            <summary>
            Xuất Excel đơn hàng với filter nâng cao
            </summary>
            <param name="model">Model xuất Excel với filter</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderExportController.ExportFinanceOrders(System.Collections.Generic.List{System.Int32})">
            <summary>
            Xuất Excel đơn hàng theo template Finance (backward compatibility)
            </summary>
            <param name="orderIds">Danh sách ID đơn hàng</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderExportController.ExportBasicOrders(System.Collections.Generic.List{System.String})">
            <summary>
            Xuất Excel đơn hàng theo template Basic
            </summary>
            <param name="orderCodes">Danh sách mã đơn hàng</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderExportController.GetAvailableTemplates">
            <summary>
            Lấy danh sách template có sẵn
            </summary>
            <returns>Danh sách template</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderExportController.DownloadFile(System.String)">
            <summary>
            Download file Excel đã xuất
            </summary>
            <param name="fileName">Tên file</param>
            <returns>File Excel</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderExportController.GetExportedFiles">
            <summary>
            Lấy danh sách file Excel đã xuất
            </summary>
            <returns>Danh sách file</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Orders.OrderFinController">
            <summary>
            Controller để xử lý các hoạt động liên quan đến tài chính đơn hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderFinController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderFinService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Orders.OrderFinController"/>.
            </summary>
            <param name="orderFinService">Dịch vụ xử lý tài chính đơn hàng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderFinController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của tài chính đơn hàng dựa trên ID.
            </summary>
            <param name="id">ID của tài chính đơn hàng.</param>
            <returns>Thông tin chi tiết của tài chính đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderFinController.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel)">
            <summary>
            Cập nhật thông tin tài chính đơn hàng.
            </summary>
            <param name="model">Model chứa thông tin tài chính đơn hàng.</param>
            <returns>Kết quả của hoạt động cập nhật.</returns>
            <remarks>
            <para>
            <b>Ai được sửa:</b> người quản lý khách hàng, sale phụ trách đơn, hoặc <b>Founder</b>
            (chủ dự án chốt 2026-08-05). Chốt này nằm trong <c>OrderFinService.Update</c> chứ không ở
            attribute <c>[Authorize]</c>, vì nó phụ thuộc DỮ LIỆU của từng đơn (ai quản lý khách, ai là sale)
            — attribute chỉ chặn được theo role. Muốn đổi luật thì sửa ở service.
            </para>
            <para>
            ⚠️ <b>Hàm này nay TỰ ĐỘNG TÍNH LẠI CƯỚC</b> khi client gửi <c>GoodsAttributes</c> (chủ dự án chốt
            2026-08-05). Nghĩa là số tiền sau khi sửa có thể khác trước nếu bảng giá đã thay đổi kể từ lúc lên
            đơn — đó là hành vi mong muốn, không phải lỗi.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderFinController.Collect(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.CollectMoneyModel)">
            <summary>
            Thu tiền
            </summary>
            <param name="model">Model chứa thông tin tài chính đơn hàng.</param>
            <returns>Kết quả của hoạt động cập nhật.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Orders.OrderPackageController">
            <summary>
            Controller để xử lý các hoạt động liên quan đến kiện hàng đơn hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderPackageController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderPackageService)">
            <summary>
            Initializes a new instance of the <see cref="T:Ladaer.BackEnd.Controllers.Orders.OrderPackageController"/> class.
            </summary>
            <param name="orderPackageService">Dịch vụ xử lý kiện hàng đơn hàng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderPackageController.GetByOrderId(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của kiện hàng đơn hàng dựa trên ID.
            </summary>
            <param name="id">ID của đơn hàng.</param>
            <returns>Thông tin chi tiết của kiện hàng đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderPackageController.GetByOrderIdWithUnits(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của kiện hàng đơn hàng dựa trên ID với thông tin đơn vị.
            </summary>
            <param name="id">ID của đơn hàng.</param>
            <returns>Thông tin chi tiết của kiện hàng đơn hàng với thông tin đơn vị.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Orders.OrderPackageController.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderPackageModel)">
            <summary>
            Cập nhật thông tin kiện hàng đơn hàng.
            </summary>
            <param name="model">Model chứa thông tin kiện hàng đơn hàng.</param>
            <returns>Kết quả của hoạt động cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Premises.PremiseController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh sách mặt bằng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Premises.PremiseController.GetById(System.Int32)">
            <summary>
            Lấy chi tiết mặt bằng theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Premises.PremiseController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseModel)">
            <summary>
            Tạo mới hoặc cập nhật mặt bằng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Premises.PremiseController.Delete(System.Int32)">
            <summary>
            Xóa mặt bằng (soft delete)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Premises.PremiseController.ChangeStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseStatusModel)">
            <summary>
            Chuyển trạng thái mặt bằng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Premises.PremiseController.UpdateFinancial(Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseFinancialModel)">
            <summary>
            Cập nhật thông tin tài chính mặt bằng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Premises.PremiseController.DeleteMedia(System.Int32)">
            <summary>
            Xóa ảnh/media của mặt bằng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Premises.PremiseScoringController.SearchCriteria(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm tiêu chí chấm điểm
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Premises.PremiseScoringController.GetCriteriaById(System.Int32)">
            <summary>
            Lấy tiêu chí theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Premises.PremiseScoringController.CreateOrUpdateCriteria(Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseScoringCriteriaModel)">
            <summary>
            Tạo mới hoặc cập nhật tiêu chí (kèm options)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Premises.PremiseScoringController.DeleteCriteria(System.Int32)">
            <summary>
            Xóa tiêu chí (soft delete kèm options)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Premises.PremiseScoringController.GetAllActiveCriteria">
            <summary>
            Lấy tất cả tiêu chí đang active (cho NV khi chấm điểm)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Promotions.PromotionCodeController">
            <summary>
            Quản lý mã khuyến mãi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionCodeController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Nullable{System.Int32})">
            <summary>
            Tìm kiếm mã khuyến mãi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionCodeController.GetById(System.Int32)">
            <summary>
            Lấy chi tiết mã khuyến mãi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionCodeController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Promotions.PromotionCodeModel)">
            <summary>
            Tạo hoặc cập nhật mã khuyến mãi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionCodeController.Delete(System.Int32)">
            <summary>
            Xóa mã khuyến mãi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionCodeController.GenerateCodes(Ladaer.BackEnd.Infrastructures.DTO.Models.Promotions.GenerateCodesModel)">
            <summary>
            Sinh mã khuyến mãi hàng loạt
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionCodeController.ChangeStatus(Ladaer.BackEnd.Controllers.Promotions.ChangeCodeStatusModel)">
            <summary>
            Thay đổi trạng thái mã khuyến mãi
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Promotions.ChangeCodeStatusModel">
            <summary>
            Model thay đổi trạng thái mã
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Promotions.PromotionProgramController">
            <summary>
            Quản lý chương trình khuyến mãi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionProgramController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm chương trình khuyến mãi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionProgramController.GetById(System.Int32)">
            <summary>
            Lấy chi tiết chương trình khuyến mãi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionProgramController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Promotions.PromotionProgramModel)">
            <summary>
            Tạo hoặc cập nhật chương trình khuyến mãi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionProgramController.Delete(System.Int32)">
            <summary>
            Xóa chương trình khuyến mãi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionProgramController.ChangeStatus(Ladaer.BackEnd.Controllers.Promotions.ChangeStatusModel)">
            <summary>
            Thay đổi trạng thái chương trình khuyến mãi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionProgramController.GetUsageLogs(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Nullable{System.Int32})">
            <summary>
            Lấy log sử dụng khuyến mãi
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Promotions.ChangeStatusModel">
            <summary>
            Model thay đổi trạng thái
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionRewardRuleController.GetByProgramId(System.Int32)">
            <summary>
            Lấy danh sách quy tắc hoàn thưởng theo chương trình
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionRewardRuleController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Promotions.PromotionRewardRuleModel)">
            <summary>
            Tạo hoặc cập nhật quy tắc
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionRewardRuleController.Delete(System.Int32)">
            <summary>
            Xóa quy tắc
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionWalletController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm ví khuyến mãi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionWalletController.GetByCustomerId(System.Int32)">
            <summary>
            Lấy ví theo customerId
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionWalletController.SearchLogs(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Nullable{System.Int32})">
            <summary>
            Tìm kiếm log giao dịch ví
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Promotions.PromotionWalletController.ManualCredit(Ladaer.BackEnd.Controllers.Promotions.ManualCreditModel)">
            <summary>
            Nạp tiền thủ công vào ví khuyến mãi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FinanceReportController.CostControl(Ladaer.BackEnd.Controllers.Reports.CostControlReportRequest)">
            <summary>
            Lấy báo cáo kiểm soát chi phí (Bảng kiểm soát chi phí)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FinanceReportController.CostControlExport(Ladaer.BackEnd.Controllers.Reports.CostControlReportRequest)">
            <summary>
            Xuất Excel báo cáo kiểm soát chi phí
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FinanceReportController.BackfillPaymentsDate">
            <summary>
            Backfill PaymentsDate từ lịch sử cho các expense đã Paid (chạy 1 lần)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FinanceReportController.CashFlow(Ladaer.BackEnd.Controllers.Reports.CashFlowReportRequest)">
            <summary>
            Lấy báo cáo dòng tiền tổng hợp (Cash Flow Dashboard)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FinanceReportController.CashFlowExport(Ladaer.BackEnd.Controllers.Reports.CashFlowReportRequest)">
            <summary>
            Xuất Excel báo cáo dòng tiền
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FinanceReportController.CashFlowFeeDetail(System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Drill-down: danh sách đơn Thu cước vận chuyển theo khoảng thời gian
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FinanceReportController.CashFlowCodDetail(System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Drill-down: danh sách đơn Thu COD từ Shipper theo khoảng thời gian
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FinanceReportController.ShortTermLiability(System.Int32,System.Int32)">
            <summary>
            Lấy báo cáo nợ ngắn hạn (Short-term Liability)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FinanceReportController.CustomerArSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>SmartTable search: Công nợ phải thu theo khách hàng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FinanceReportController.CustomerArExport(System.Int32)">
            <summary>Xuất Excel danh sách đơn nợ cước theo khách hàng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FinanceReportController.CodDebtByCustomerSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>SmartTable search: Nợ COD theo khách hàng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Reports.CostControlReportRequest">
            <summary>
            Request model cho báo cáo kiểm soát chi phí
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Reports.CashFlowReportRequest">
            <summary>
            Request model cho báo cáo dòng tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Reports.CashFlowReportRequest.ViewMode">
            <summary>
            "daily" hoặc "weekly"
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Reports.FuelCards.FuelRefillReportController">
            <summary>
            Controller để xử lý các báo cáo đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FuelCards.FuelRefillReportController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.IFuelRefillReportService,Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.IFuelRefillReportExcelService)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Controllers.Reports.FuelCards.FuelRefillReportController"/>.
            </summary>
            <param name="fuelRefillReportService">Dịch vụ báo cáo đổ dầu.</param>
            <param name="fuelRefillReportExcelService">Dịch vụ xuất Excel báo cáo đổ dầu.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FuelCards.FuelRefillReportController.GetByDriver(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy báo cáo đổ dầu theo lái xe
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Danh sách báo cáo đổ dầu theo lái xe</returns>
            <remarks>
            Filters có thể truyền trong PredicateObject:
            - StartDate, EndDate: Khoảng thời gian đổ dầu
            - DriverIds: Mảng ID lái xe
            - TruckIds: Mảng ID xe
            - Statuses: Mảng trạng thái phiếu (0: Pending, 1: Approved, 2: Rejected). Mặc định [1]
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FuelCards.FuelRefillReportController.GetByDate(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy báo cáo đổ dầu theo ngày
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Danh sách báo cáo đổ dầu theo ngày (nhóm theo ngày, chi tiết lái xe + xe bên trong)</returns>
            <remarks>
            Filters có thể truyền trong PredicateObject:
            - StartDate, EndDate: Khoảng thời gian đổ dầu
            - DriverIds: Mảng ID lái xe
            - TruckIds: Mảng ID xe
            - Statuses: Mảng trạng thái phiếu (0: Pending, 1: Approved, 2: Rejected). Mặc định [1]
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FuelCards.FuelRefillReportController.ExportByDriver(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Xuất Excel báo cáo đổ dầu theo lái xe
            </summary>
            <param name="param">Tham số bảng thông minh (cùng điều kiện lọc với GetByDriver)</param>
            <returns>Kết quả xuất file Excel</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FuelCards.FuelRefillReportController.ExportByDate(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Xuất Excel báo cáo đổ dầu theo ngày
            </summary>
            <param name="param">Tham số bảng thông minh (cùng điều kiện lọc với GetByDate)</param>
            <returns>Kết quả xuất file Excel</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FuelCards.FuelRefillReportController.GetByTruck(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy báo cáo đổ dầu theo xe
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Danh sách báo cáo đổ dầu theo xe (nhóm theo xe, chi tiết lái xe bên trong)</returns>
            <remarks>
            Filters có thể truyền trong PredicateObject:
            - StartDate, EndDate: Khoảng thời gian đổ dầu
            - DriverIds: Mảng ID lái xe
            - TruckIds: Mảng ID xe
            - Statuses: Mảng trạng thái phiếu (0: Pending, 1: Approved, 2: Rejected). Mặc định [1]
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.FuelCards.FuelRefillReportController.ExportByTruck(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Xuất Excel báo cáo đổ dầu theo xe
            </summary>
            <param name="param">Tham số bảng thông minh (cùng điều kiện lọc với GetByTruck)</param>
            <returns>Kết quả xuất file Excel</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Reports.Operations.DriverReportController">
            <summary>
            Controller để xử lý các báo cáo hoạt động lái xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Operations.DriverReportController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Report.OperationReports.IDriverReportService)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Controllers.Reports.Operations.DriverReportController"/>.
            </summary>
            <param name="driverReportService">Dịch vụ báo cáo lái xe.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Operations.DriverReportController.GetDriverProductivityReportByDate(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy báo cáo năng suất lái xe theo từng ngày
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Danh sách báo cáo năng suất lái xe theo ngày</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Reports.Orders.OrderBacklogController">
            <summary>
            Controller thống kê tồn đọng đơn hàng (Backlog)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Orders.OrderBacklogController.GetCurrentAgencyHierarchyAsync">
            <summary>
            Lấy danh sách AgencyIds mà user hiện tại có quyền truy cập.
            Founder: null (không giới hạn). Khác: bưu cục mình + con cháu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Orders.OrderBacklogController.GetSummary(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy thống kê tồn đọng đơn hàng theo trạng thái và thời gian (D0-D7+)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Orders.OrderBacklogController.GetSummaryByAgency(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy thống kê tồn đọng đơn hàng phân nhóm theo Agency
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Orders.OrderBacklogController.GetDetail(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy danh sách chi tiết đơn hàng drill-down (có phân trang)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Orders.OrderBacklogController.EnsureAgencyFilter(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Collections.Generic.List{System.Int32})">
            <summary>
            Đảm bảo AgencyIds trong SearchParam bị giới hạn bởi allowedIds.
            Nếu user truyền AgencyIds: lấy giao (intersection).
            Nếu user không truyền: dùng toàn bộ allowedIds.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Reports.Orders.OrderFinReportController">
            <summary>
            Controller để xử lý các báo cáo tài chính đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Orders.OrderFinReportController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Report.Orders.IOrderFinReportService)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Controllers.Reports.Orders.OrderFinReportController"/>.
            </summary>
            <param name="orderFinReportService">Dịch vụ báo cáo tài chính đơn hàng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Orders.OrderFinReportController.PrepareBankTransferSummaryBySaleModel">
            <summary>
            Chuẩn bị dữ liệu bộ lọc: trạng thái và trạng thái vật lý
            </summary>
            <returns>Model chứa danh sách option trạng thái và trạng thái vật lý</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Orders.OrderFinReportController.GetBankTransferSummaryBySale(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy thống kê chuyển khoản ngân hàng theo sale
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Danh sách thống kê chuyển khoản theo sale</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Orders.OrderFinReportController.GetBankTransferSummaryBySaleTotals(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy dòng Tổng toàn cục (summary cards) cho báo cáo CK theo sale.
            </summary>
            <param name="param">Tham số bảng thông minh (dùng cùng bộ lọc với search)</param>
            <returns>Dòng tổng toàn cục</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Orders.OrderFinReportController.GetBankTransferSummaryByCustomer(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy thống kê chuyển khoản ngân hàng theo khách hàng
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Danh sách thống kê chuyển khoản theo khách hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Orders.OrderFinReportController.GetBankTransferSummaryByCustomerTotals(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy dòng Tổng toàn cục (summary cards) cho báo cáo CK theo khách hàng — tính trên
            toàn bộ khách hàng khớp bộ lọc, không phụ thuộc trang đang xem của SmartTable.
            </summary>
            <param name="param">Tham số bảng thông minh (dùng cùng bộ lọc với search)</param>
            <returns>Dòng tổng toàn cục</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Orders.OrderFinReportController.GetBankTransferOrdersDetail(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy danh sách đơn CK kế toán chi tiết theo từng ô số liệu (metric), có phân trang server-side.
            Metric: "total"/null (tất cả), "notcollected" (chưa thu), "createdbill" (đã tạo phiếu), "collected" (đã thu).
            Truyền SaleId/CustomerId trong Search.PredicateObject để lọc theo sale/khách hàng
            (SaleId chỉ áp dụng khi là Founder/Accountant).
            </summary>
            <param name="param">Tham số lọc giống báo cáo tổng hợp, bổ sung Metric; phân trang qua Pagination/Sort</param>
            <returns>Trang dữ liệu danh sách đơn chi tiết (SmartTableResult)</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.ReportController.OrderReportByRoute(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy báo cáo số lượng đơn và doanh số theo tuyến
            </summary>
            <param name="param">Tham số bảng thông minh chứa các điều kiện lọc:
            - StartDate/EndDate: Khoảng thời gian
            - SaleId: Lọc theo sale (chỉ Founder)
            - SourceCityId: Lọc theo tỉnh/thành phố gửi
            - DestCityId: Lọc theo tỉnh/thành phố nhận
            </param>
            <returns>Danh sách báo cáo theo tuyến và trạng thái</returns>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.DimensionRoles">
            <summary>Role của ô lọc dùng chung cho ba trang doanh số theo chiều — người vào được trang nào cũng nạp được ô lọc.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.SaleRevenueStatistics(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Thống kê doanh thu bán hàng
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Kết quả thống kê doanh thu</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.OrderRevenueByDate(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Thống kê đơn hàng và doanh thu theo ngày
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Kết quả thống kê đơn hàng và doanh thu theo ngày</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.OrderRevenueByCollectionDate(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Thống kê doanh thu theo ngày công ty nhận tiền (Collection Date)
            Chỉ bao gồm thống kê tài chính, không có thống kê trạng thái triển khai
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Kết quả thống kê doanh thu theo ngày nhận tiền</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.OrderRevenueBySale(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Thống kê doanh thu theo Sale (chỉ thống kê tài chính)
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Kết quả thống kê doanh thu theo Sale</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.CustomerRevenue(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Thống kê doanh thu theo khách hàng
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Kết quả thống kê doanh thu theo khách hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.GetCustomerRevenuePermissions">
            <summary>
            Lấy thông tin quyền của user cho báo cáo doanh thu theo khách hàng
            </summary>
            <returns>Thông tin quyền (có thể chọn sale hay không)</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.NavPermissions">
            <summary>
            Cờ hiển thị của ba báo cáo doanh số theo chiều + nút Xuất Excel + link mã đơn. CỐ Ý không gác role (rule
            <c>quyen-hien-thi</c>): người không có quyền nào vẫn hỏi được và nhận toàn <c>false</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.OrderRevenueByAgency(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Doanh số theo bưu cục bán × 4 nhóm trạng thái. Phạm vi: Founder/kế toán mọi bưu cục (kể cả đã ngừng),
            người đứng tên bưu cục thì bưu cục đó + con cháu, còn lại rỗng.
            </summary>
            <param name="param"><c>Search.PredicateObject</c>: <c>FromDate</c>, <c>ToDate</c>, <c>AgencyId</c> (chỉ thu hẹp).</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.OrderRevenueByTeam(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Doanh số theo nhóm (quản lý trực tiếp của sale) × 4 nhóm trạng thái. Phạm vi: bản thân + cấp dưới + nhân sự
            bưu cục mình đứng tên; Founder/kế toán không giới hạn.
            </summary>
            <param name="param"><c>Search.PredicateObject</c>: <c>FromDate</c>, <c>ToDate</c>, <c>ManagerId</c> (0 = chưa có quản lý; chỉ thu hẹp).</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.OrderRevenueByWard(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Doanh số theo phường/xã (bộ 2 cấp) của điểm lấy hoặc điểm giao × 4 nhóm trạng thái. Phạm vi như báo cáo bưu cục.</summary>
            <param name="param"><c>Search.PredicateObject</c>: <c>FromDate</c>, <c>ToDate</c>, <c>AddressType</c> (1/2), <c>CityId</c>, <c>Keyword</c>, <c>AgencyId</c>.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.OrderRevenueDetail(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Danh sách đơn của một ô (drill-down). Action chỉ đòi đăng nhập vì role phụ thuộc <c>Dimension</c> trong body —
            service kiểm role của chiều qua <c>IUserRoleResolver</c> rồi ép CÙNG phạm vi với báo cáo của chiều đó.
            </summary>
            <param name="param"><c>Search.PredicateObject</c>: <c>FromDate</c>, <c>ToDate</c>, <c>Dimension</c>, <c>Key</c>, <c>StatusGroup</c>, <c>AddressType</c>, <c>AgencyId</c>; <c>Pagination</c>.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.OrderRevenueFilterOptions">
            <summary>Bưu cục và nhóm trong phạm vi người xem cho ô lọc — không gọi danh mục toàn cục.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.OrderRevenueByAgencyExport(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Xuất Excel báo cáo bưu cục — đòi role của chiều VÀ <c>RevenueReport.Export</c> (hai <c>[Authorize]</c> là phép AND).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.OrderRevenueByTeamExport(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Xuất Excel báo cáo nhóm — đòi role của chiều VÀ <c>RevenueReport.Export</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.OrderRevenueByWardExport(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Xuất Excel báo cáo phường/xã — đòi role của chiều VÀ <c>RevenueReport.Export</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Reports.Sales.RevenueReportController.FileOrError(Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueExcelFileResult)">
            <summary>
            Trả thẳng byte với <c>no-store</c>, không lưu ra <c>wwwroot</c> — doanh số theo bưu cục/nhóm không được nằm ở
            một URL tải công khai (khuôn <c>FranchisePriceController</c>).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Rewards.AutoPenaltyConfigController">
            <summary>
            Controller quản lý cấu hình phạt tự động
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.AutoPenaltyConfigController.GetCurrentConfig">
            <summary>
            Lấy cấu hình đang hiệu lực
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.AutoPenaltyConfigController.UpdateConfig(Ladaer.BackEnd.Infrastructures.Services.Rewards.AutoPenaltyConfigModel)">
            <summary>
            Cập nhật cấu hình (tạo version mới)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.AutoPenaltyConfigController.TogglePause(Ladaer.BackEnd.Controllers.Rewards.PauseRequest)">
            <summary>
            Tạm dừng / Mở lại job tự động
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.AutoPenaltyConfigController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh sách cấu hình
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.AutoPenaltyConfigController.GetById(System.Int32)">
            <summary>
            Lấy chi tiết cấu hình theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.AutoPenaltyConfigController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.Services.Rewards.AutoPenaltyConfigModel)">
            <summary>
            Tạo mới hoặc cập nhật cấu hình
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.AutoPenaltyConfigController.Delete(System.Int32)">
            <summary>
            Xóa cấu hình
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Rewards.RewardPenaltyController">
            <summary>
            Controller quản lý phiếu thưởng/phạt
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.RewardPenaltyController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm phiếu thưởng/phạt
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.RewardPenaltyController.GetById(System.Int32)">
            <summary>
            Lấy phiếu thưởng/phạt theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.RewardPenaltyController.CreateManual(Ladaer.BackEnd.Infrastructures.DTO.Models.Rewards.RewardPenaltyTicketModel)">
            <summary>
            Tạo phiếu thưởng/phạt thủ công
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.RewardPenaltyController.Approve(System.Int32)">
            <summary>
            Duyệt phiếu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.RewardPenaltyController.Reject(System.Int32)">
            <summary>
            Từ chối phiếu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.RewardPenaltyController.Cancel(System.Int32,Ladaer.BackEnd.Controllers.Rewards.CancelTicketRequest)">
            <summary>
            Gỡ/hủy phiếu (có giới hạn amnesty nếu Auto)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.RewardPenaltyController.CreateFromCashier(Ladaer.BackEnd.Controllers.Rewards.CreateFromCashierRequest)">
            <summary>
            Tạo biên bản vi phạm nộp tiền trễ từ trang Cashier
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.RewardPenaltyController.Forgive(System.Int32,Ladaer.BackEnd.Controllers.Rewards.ForgiveTicketRequest)">
            <summary>
            Tha thứ / bỏ qua biên bản (Forgive)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Rewards.RewardPenaltyController.Delete(System.Int32)">
            <summary>
            Xóa biên bản vi phạm
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Rewards.CancelTicketRequest.Reason">
            <summary>
            Lý do gỡ biên bản (bắt buộc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Rewards.ForgiveTicketRequest.Reason">
            <summary>
            Lý do tha thứ (bắt buộc)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController">
             <summary>
             Màn hình "Đồng bộ tìm kiếm": xem trạng thái index của từng URL và ba nút bấm tay.
            
             <para>
             <b>Quyền tách làm hai mức theo hậu quả, không theo động từ HTTP.</b> <c>SearchConsole.View</c>
             cho mọi lời gọi chỉ đọc lại 5 bảng đã có — kể cả <c>POST search</c>, vốn là POST chỉ vì
             <c>SmartTable</c> gửi bộ lọc trong thân request. <c>SearchConsole.Manage</c> cho ba nút thật sự
             làm phát sinh lời gọi ra Google và tiêu hạn mức chung với job chạy nền.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.MaxApiLogTake">
            <summary>
            Trần số dòng nhật ký trả về một lượt.
            </summary>
            <remarks>
            Bảng nhật ký giữ tới <c>Search.ApiLogRetentionDays</c> ngày nên nó lớn dần; không kẹp thì
            một lời gọi <c>?take=999999</c> kéo cả bảng về trình duyệt. Màn hình chỉ hiện vài chục dòng
            gần nhất.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.DefaultApiLogTake">
            <summary>Số dòng nhật ký mặc định — đủ nhìn được một ngày chạy job mà không phải bấm thêm.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.DefaultPerformanceDays">
            <summary>Số ngày mặc định của tab hiệu suất — bằng cửa sổ giao diện Search Console hay dùng.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.DefaultBotVisitDays">
            <summary>
            Số ngày mặc định của tab lượt bot. Ngắn hơn tab hiệu suất vì câu hỏi ở đây luôn là về hiện
            tại ("bot nào đang ghé"), và vì dữ liệu chỉ được giữ 90 ngày.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Bảng chính: hàng tồn kho URL kèm trạng thái index gần nhất</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.GetSummary(Lada.Framework.Data.Enums.SearchEngine)">
            <summary>Các con số tổng hợp đầu trang, kèm trạng thái công tắc và hạn mức còn lại</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.GetSitemapStatus(Lada.Framework.Data.Enums.SearchEngine)">
            <summary>Trạng thái tệp sitemap dưới mắt công cụ tìm kiếm</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.GetPerformance(Lada.Framework.Data.Enums.SearchEngine,System.Int32)">
            <summary>
            Số liệu hiệu suất tìm kiếm của một khoảng ngày: lượt bấm, lượt hiển thị, CTR, vị trí, và
            đường xu hướng theo ngày.
            </summary>
            <remarks>
            Chỉ đọc bảng <c>SearchMetricDaily</c> — <b>không</b> gọi ra Google, nên không tiêu hạn mức
            và chạy được cả khi mọi công tắc còn tắt. Vì thế nó nằm ở mức quyền <c>View</c>.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.GetTopPages(Lada.Framework.Data.Enums.SearchEngine,System.Int32,System.Int32)">
            <summary>Xếp hạng trang theo lượt bấm</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.GetTopQueries(Lada.Framework.Data.Enums.SearchEngine,System.Int32,System.Int32)">
            <summary>Xếp hạng truy vấn theo lượt bấm</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.GetQueriesForPage(System.String,Lada.Framework.Data.Enums.SearchEngine,System.Int32,System.Int32)">
            <summary>Các truy vấn đưa người dùng tới đúng một trang</summary>
            <remarks>
            Tham số <c>url</c> chỉ được dùng làm <b>giá trị so sánh</b> trong một truy vấn tham số hoá,
            không ghép vào chuỗi nào và không đi ra ngoài — nên không có đường để một địa chỉ lạ trở
            thành một lời gọi. URL không có trong bảng thì trả về danh sách rỗng.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.GetBotVisits(System.Int32,System.String)">
            <summary>Tổng hợp lượt bot ghé website — theo User-Agent tự khai</summary>
            <remarks>
            Số ở đây do middleware của <c>ladaexpress.vn</c> ghi, API chỉ đọc lại. Không có lời gọi ra
            ngoài nào, nên chỉ đòi quyền xem.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.GetBotVisitTopPaths(System.Int32,System.String,System.Int32,System.Boolean)">
            <summary>Xếp hạng đường dẫn theo số lượt bot</summary>
            <remarks>
            Tham số <c>bot</c> chỉ được dùng làm <b>giá trị so sánh</b> trong một truy vấn tham số hoá,
            không ghép vào chuỗi nào và không đi ra ngoài. Tên bot lạ thì trả về danh sách rỗng.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.GetApiLogs(Lada.Framework.Data.Enums.SearchEngine,System.Int32)">
            <summary>Nhật ký lời gọi ra công cụ tìm kiếm — cũng chính là sổ đếm hạn mức đã dùng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.InspectNow(Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchInspectNowRequest)">
            <summary>
            Kiểm ngay trạng thái index của một URL trong hàng tồn kho.
            </summary>
            <remarks>
            <b>Chỉ nhận URL đã có trong bảng <c>SearchUrl</c></b> — service từ chối mọi địa chỉ khác
            <b>trước khi</b> có lời gọi nào đi ra. Đó vừa là hàng rào SSRF (không ai mượn được máy chủ
            để gọi hộ một địa chỉ tự chọn) vừa là hàng rào hạn mức. Lượt kiểm này trừ vào cùng sổ hạn
            mức ngày với job chạy nền.
            <para>
            <b>Cố ý không truyền <c>HttpContext.RequestAborted</c> xuống service.</b> Người bấm đóng tab
            giữa chừng sẽ huỷ token, mà điểm huỷ nguy hiểm nhất nằm đúng giữa "đã gọi ra Google" và
            "đã ghi dòng nhật ký": huỷ ở đó là mất dấu một lượt đã tiêu hạn mức, và lượt sau sẽ tiêu
            thêm đúng ngần ấy nữa. Lời gọi chỉ vài trăm mili-giây nên chạy nốt là lựa chọn rẻ hơn.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.SubmitSitemapNow">
            <summary>
            Nộp lại tệp sitemap đang cấu hình.
            </summary>
            <remarks>
            <b>Cố ý không nhận tham số</b>: địa chỉ tệp luôn lấy từ khoá <c>Search.Google.SitemapUrl</c>.
            Cho người bấm chọn tệp là cho phép nộp một địa chỉ bất kỳ dưới danh nghĩa property của LADA.
            Bị từ chối kèm lý do khi công tắc <c>Search.Google.SubmitEnabled</c> còn tắt.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleController.TestConnection">
            <summary>
            Thử kết nối tới công cụ tìm kiếm để biết khoá và quyền đã đúng chưa.
            </summary>
            <remarks>
            Câu trả lời cố ý chỉ nói được/không được kèm cách sửa — <b>không</b> kèm địa chỉ service
            account hay mẩu khoá nào, vì nó hiện thẳng lên giao diện quản trị.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleNavController">
            <summary>
            Cờ hiển thị cho màn hình "Đồng bộ tìm kiếm" — "tôi được thấy nút nào".
            </summary>
            <remarks>
            Endpoint này <b>cố ý không đòi role nào</b> (chỉ cần đăng nhập): người không có quyền gì vẫn
            phải hỏi được và nhận về toàn <c>false</c> để giao diện ẩn nút. Gác nó bằng một role là dựng lại
            đúng lỗi nó sinh ra để chữa — trang sẽ hiện nút cho người không bấm được, hoặc gãy vì lời gọi
            hỏi quyền lại bị 403. Luật nằm ở hàm thuần <see cref="T:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleNavPermissions"/>, controller
            chỉ hỏi role rồi chuyển tiếp (mẫu: <c>AdsNavController</c>).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleNavController.GetNavPermissions">
            <summary>Cờ hiển thị nút của màn hình đồng bộ tìm kiếm cho người đang đăng nhập</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleNavPermissions">
            <summary>
            Luật "ai thấy gì" của màn hình Đồng bộ tìm kiếm.
            </summary>
            <remarks>
            <para>
            <b>Hàm thuần</b> — không chạm database, không đọc <c>HttpContext</c>: nhận danh sách role đã
            phân giải qua <c>IUserRoleResolver</c>, trả các cờ. Cùng khuôn với <c>AdsNavPermissions</c>, và
            vì cùng một lý do: luật này phải có ca test gọi thẳng vào nó, mà controller thì không test được
            sạch (<c>User.GetCurrentUser()</c> nuốt mọi ngoại lệ rồi trả <c>UserId = 0</c>).
            </para>
            <para>
            <b><c>CanManage</c> không kéo theo <c>CanView</c>.</b> Cám dỗ ở đây là coi "quản lý" như một
            mức cao hơn "xem" rồi cho nó bao luôn. Nhưng hàng rào thật là các thuộc tính
            <c>[Authorize(Roles = …)]</c> trên <c>SearchConsoleController</c>: mọi endpoint đọc đòi đúng
            <c>SearchConsole.View</c>. Một người chỉ được cấp <c>SearchConsole.Manage</c> mà thấy trang mở
            ra sẽ ăn 403 ngay ở lời gọi nạp bảng. Cờ phải soi đúng bó quyền mà nó gác, không mượn bó khác.
            Hai quyền này luôn được cấp cùng nhau qua nhóm <c>Permission</c> "Marketing", nên trường hợp
            lệch chỉ xảy ra khi có người gán tay — và khi đó giao diện phải nói đúng sự thật.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleNavPermissions.Founder">
            <summary>Vai bỏ qua mọi kiểm tra role của hệ thống — ẩn nút của Founder là dựng hàng rào không có thật.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleNavPermissions.View">
            <summary>Role của mọi lời gọi chỉ đọc: <c>search</c>, <c>summary</c>, <c>sitemap-status</c>, <c>api-logs</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleNavPermissions.Manage">
            <summary>Role của ba nút làm phát sinh lời gọi ra Google: <c>inspect-now</c>, <c>submit-sitemap-now</c>, <c>test-connection</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleNavPermissions.Resolve(System.Collections.Generic.IEnumerable{System.String})">
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c>; <c>null</c> hoặc rỗng = không có role nào</param>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleNavFlags">
            <summary>Cờ hiển thị của màn hình Đồng bộ tìm kiếm — mỗi cờ gác đúng một bó quyền (xem <see cref="T:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleNavPermissions"/>)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleNavFlags.#ctor(System.Boolean,System.Boolean)">
            <summary>Cờ hiển thị của màn hình Đồng bộ tìm kiếm — mỗi cờ gác đúng một bó quyền (xem <see cref="T:Ladaer.BackEnd.Controllers.SearchEngines.SearchConsoleNavPermissions"/>)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController">
            <summary>
            Quản lý kênh chat: kết nối Zalo Official Account qua OAuth, bật/tắt, xoá.
            <para>
            Toàn bộ endpoint đòi quyền <c>ChatChannel.Manage</c> — đây là chỗ nắm token của OA,
            tách hẳn khỏi quyền trả lời tin nhắn. Ngoại lệ duy nhất là endpoint nhận callback,
            vì trình duyệt được Zalo chuyển hướng sang nên không mang theo JWT; nó tự bảo vệ
            bằng tham số <c>state</c> đã ký HMAC.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.OAuthCallbackRoutePrefix">
            <summary>
            Tiền tố đường dẫn công khai của endpoint nhận callback OAuth. Khai đúng một chỗ rồi
            cho <c>FrontendOriginMiddleware.BypassPaths</c> dùng lại — chép chuỗi ra hai nơi là
            sớm muộn có nơi quên đổi, và nơi quên đó thành lỗ hổng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.GetAll">
            <summary>
            Danh sách kênh đã kết nối. Phản hồi không chứa token dưới bất kỳ dạng nào — chỉ có hai
            cờ <c>HasAccessToken</c> / <c>HasRefreshToken</c>.
            <para>
            Ba role chứ không phải một, và đó là bản vá cho lần thứ BA của cùng một hình dạng lỗi
            (finding FB-2 giai đoạn B, rồi L7 và L12 của phiên bấm thật P1b): <b>route mở cho vai
            A nhưng API mà trang đó gọi lại đòi vai B</b>. Trang <c>/dieu-phoi-chat</c> mở cho
            <c>ChatDistribution.Manage</c> và <c>ChatConversation.ViewChannel</c>, mà ô lọc kênh
            của nó gọi đúng endpoint này — trước bản vá nó trả 403 cho cả hai vai, và
            <c>apiClient</c> dịch mọi 403 thành một cú chuyển hướng cả SPA sang trang "không có
            quyền". Tức trang điều phối hỏng với ĐÚNG những vai nó được mở cho; chỉ
            <c>Founder</c> dùng được, và chỉ vì Founder bỏ qua mọi kiểm tra role.
            </para>
            <para>
            Nới ở đây không mở thêm dữ liệu nào: hai vai được thêm vốn đã đọc được hội thoại của
            những kênh ấy, và mỗi hội thoại đã mang sẵn tên kênh trong danh sách.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.GetById(System.Int32)">
            <summary>Chi tiết một kênh</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.GetZaloAuthorizationUrl">
            <summary>
            Lấy đường dẫn cấp quyền để admin của Zalo OA bấm vào.
            Phản hồi kèm code challenge cần khai trên cổng nhà phát triển (nếu có dùng PKCE).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.ZaloOAuthCallback(System.String,System.String,System.String,System.String)">
            <summary>
            Zalo chuyển hướng trình duyệt của admin OA về đây kèm <c>code</c> và <c>oa_id</c>
            sau khi cấp quyền xong.
            <para>
            Không yêu cầu đăng nhập vì request đến từ một lần chuyển hướng của Zalo. Chống việc
            người ngoài tự gắn Official Account của họ vào hệ thống bằng tham số <c>state</c> đã ký
            HMAC kèm dấu thời gian; state sai hoặc hết hạn là từ chối ngay ở tầng service.
            </para>
            <para>
            Giới hạn tốc độ theo policy ẩn danh: luồng thật chỉ gọi đúng một lần cho mỗi lần cấp quyền.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.GetFacebookAuthorizationUrl">
            <summary>
            Lấy đường dẫn hộp thoại Facebook Login for Business để quản trị viên bấm vào và tự cấp
            quyền — thay cho việc dán tay user access token lấy ở Graph API Explorer.
            <para>
            Phản hồi kèm chuỗi <c>state</c>; giao diện phải giữ lại chuỗi đó để hỏi danh sách Page
            sau khi cửa sổ cấp quyền đóng. Token không bao giờ đi qua trình duyệt.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.FacebookOAuthCallback(System.String,System.String,System.String,System.String)">
            <summary>
            Facebook chuyển hướng trình duyệt của quản trị viên về đây kèm <c>code</c> và
            <c>state</c> sau khi cấp quyền xong.
            <para>
            Không yêu cầu đăng nhập vì request đến từ một lần chuyển hướng của Facebook — cửa sổ
            bật lên không mang theo phiên của SPA. Chống người ngoài tự gắn Page của họ vào hệ
            thống bằng tham số <c>state</c> đã ký HMAC kèm dấu thời gian và mã người dùng; state
            sai hoặc hết hạn là từ chối ngay ở tầng service.
            </para>
            <para>
            Trả về một trang HTML tối giản tự đóng cửa sổ. Đây là chỗ DUY NHẤT trong repo trả HTML
            từ controller, và có lý do: người dùng đang nhìn thẳng vào cửa sổ này, mà JSON trần thì
            họ phải tự hiểu rồi tự đóng.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.GetFacebookPages(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.FacebookPagesLookupModel)">
            <summary>
            Danh sách Facebook Page mà quản trị viên đang quản lý.
            <para>
            Dùng POST dù đây là thao tác đọc: <c>state</c> và token dự phòng phải đi trong thân
            request. Trên query string chúng sẽ nằm lại trong nhật ký truy cập của mọi proxy trên
            đường, mà Page access token dẫn xuất từ token đó thì không có hạn dùng.
            </para>
            <para>Phản hồi không chứa token của Page nào.</para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.ConnectFacebookPage(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ConnectFacebookPageModel)">
            <summary>
            Kết nối một Facebook Page thành kênh chat.
            <para>
            Bước chọn Page luôn nằm sau đăng nhập kèm quyền <c>ChatChannel.Manage</c>, kể cả khi
            đi bằng luồng Facebook Login: callback ẩn danh chỉ giữ token vào bộ nhớ máy chủ chứ
            không tạo kênh, nên không có đường nào gắn được Page mà không qua cửa này.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.ResubscribeFacebookPage(System.Int32)">
            <summary>
            Đăng ký lại webhook (<c>subscribed_apps</c>) cho một kênh Facebook đã lưu (SC-20).
            Dành cho kênh kết nối trước khi bước đăng ký được tự động hoá, hoặc khi bước đó thất bại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.SetActive(System.Int32,System.Boolean)">
            <summary>Bật hoặc tắt một kênh</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.Delete(System.Int32)">
            <summary>Xoá mềm một kênh</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.GetChannelStaff(System.Int32)">
            <summary>
            Danh sách nhân viên phụ trách một kênh.
            <para>
            Quyền riêng <c>ChatChannel.StaffAssign</c> chứ không dùng chung <c>ChatChannel.Manage</c>:
            quyền kia nắm token OA — thứ mà trưởng bưu cục xếp lịch trực cho đội sale của mình
            không có lý do gì phải chạm tới.
            </para>
            <para>
            Role mới trả lời được "có được cấu hình sale phụ trách không", chưa trả lời "kênh nào".
            Câu thứ hai hỏi tầng dịch vụ — không hỏi thì một trưởng nhóm đọc được danh sách sale của
            mọi bưu cục khác, kèm họ tên (finding F-1).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.SaveChannelStaff(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatChannelStaffModel)">
            <summary>Thêm hoặc sửa một nhân viên phụ trách kênh</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.RemoveChannelStaff(System.Int32)">
            <summary>Gỡ một nhân viên khỏi danh sách phụ trách kênh (xoá mềm, giữ lịch sử)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.UpdateAssignmentSettings(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatChannelAssignmentModel)">
            <summary>
            Đổi bưu cục sở hữu và chế độ phân phối của kênh.
            <para>
            Chuyển kênh khỏi chế độ "Dùng chung" là <b>bật hàng rào quyền xem</b> — từ đó chỉ người
            trong phạm vi mới đọc được hội thoại của kênh. Giao diện phải hỏi lại trước khi gọi;
            tầng dịch vụ còn chặn thêm hai ca hỏng người ("chưa ai phụ trách" và "kênh một chủ mà
            không có đúng một chủ").
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatChannelController.CallbackPage(System.Boolean,System.String)">
            <summary>
            Trang kết thúc luồng cấp quyền Facebook: báo kết quả rồi tự đóng cửa sổ.
            <para>
            Thông điệp luôn đi qua <see cref="T:System.Text.Encodings.Web.HtmlEncoder"/> — một phần trong đó là nguyên văn lời
            Facebook nói (<c>error_description</c> trên query string), tức là chuỗi do bên ngoài
            điều khiển. Nhúng thẳng vào HTML là mở đường chèn mã ngay trên tên miền của API.
            </para>
            <para>
            Trang không nhận tham số nào khác từ query và không tự chuyển hướng đi đâu: cửa sổ này
            do SPA mở ra, đóng lại là xong, phần còn lại của luồng do SPA làm bằng chuỗi
            <c>state</c> nó đang giữ.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.SocialChat.ChatDistributionController">
            <summary>
            Máy phân phối khách chat — nhật ký quyết định và bản phát lại đối chiếu (giai đoạn D).
            </summary>
            <remarks>
            <para>
            Route chữ thường tường minh <c>api/socialchat/distribution</c>, đúng nếp của
            <c>SocialChatController</c> và <c>ChatPresenceController</c>. Hàng chờ vẫn nằm ở
            <c>POST api/socialchat/distribution/queue</c> của <c>SocialChatController</c> — không dời
            sang đây vì dời là đổi đường một trang đang chạy, mà nguyên tắc số 1 nói đừng.
            </para>
            <para>
            <b>Đối chiếu role với trang gọi nó.</b> Route <c>/dieu-phoi-chat</c> mở cho
            <c>ChatDistribution.Manage</c> và <c>ChatConversation.ViewChannel</c>, nên hai đường ĐỌC ở
            đây gác đúng bằng hai vai ấy — mở hẹp hơn là tái lập FB-2 / L7 / L12, ba lần cùng một hình
            dạng "trang mở được nhưng lời gọi của nó trả 403".
            </para>
            <para>
            Đường <b>phát lại</b> thì hẹp hơn hẳn: nó ghi hàng loạt dòng nhật ký và là công cụ của
            người vận hành máy phân phối, không phải của người đọc hàng chờ. Chỉ
            <c>ChatDistribution.Manage</c>.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatDistributionController.SearchDecisions(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Nhật ký quyết định của máy phân phối, đã thu hẹp theo phạm vi kênh của người đọc.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatDistributionController.GetStatus">
            <summary>
            Trạng thái máy phân phối — để giao diện nói rõ "đang chạy thử" thay vì để người đọc
            tưởng khách đã được chia thật.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatDistributionController.Replay(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatDistributionReplayModel)">
            <summary>
            Phát lại tin inbound lịch sử qua máy phân phối và trả về bảng đối chiếu — bằng chứng của
            cổng D2.
            </summary>
            <remarks>
            Không bao giờ ghi <c>AssignedStaffId</c>: mọi dòng nó sinh ra mang <c>Source = Replay</c>
            và <c>IsDryRun = true</c>, và chạy lại thì dọn đúng những dòng phát lại cũ trong cùng
            cửa sổ chứ không đụng dòng của máy chạy thật.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.SocialChat.ChatPresenceController">
            <summary>
            Trạng thái sẵn sàng của sale (giai đoạn C đợt phân phối khách chat).
            </summary>
            <remarks>
            <para>
            Route chữ thường tường minh <c>api/socialchat/presence</c>, đúng nếp của
            <c>SocialChatController</c> (<c>api/socialchat</c>) và <c>ChatChannelController</c>
            (<c>api/socialchat/channel</c>) chứ không theo quy ước Pascal của phần còn lại repo.
            </para>
            <para>
            <b>Đường "của tôi" và đường "của người khác" là HAI endpoint riêng</b>, không phải một
            endpoint phân nhánh theo <c>StaffId</c> trong thân yêu cầu. Gộp lại nghĩa là quyền cần có
            phụ thuộc vào nội dung thân — loại hàng rào dễ quên nhất, và không đọc ra được bằng cách
            nhìn <c>[Authorize]</c>.
            </para>
            <para>
            <b>Đối chiếu role với trang gọi nó</b> (bài học FB-2 → L7 → L12, ba lần cùng một hình dạng):
            chip trạng thái nằm trên thanh điều hướng của <b>mọi</b> trang, nên hai endpoint
            <c>me</c> gác bằng <c>ChatConversation.Search</c> — quyền hẹp nhất mà một người làm chat
            chắc chắn có. Phía trình duyệt vẫn phải đọc 403 thành "ẩn chip" thay vì để
            <c>apiClient</c> đá cả SPA sang trang không có quyền.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatPresenceController.GetPermissions">
            <summary>
            Ba đường GHI của hộp thoại quản lý có mở cho người đang đăng nhập hay không.
            </summary>
            <remarks>
            <para>
            <b>Sổ nợ PP-36 chỗ (b).</b> Hộp thoại quản lý ở <c>/trang-thai-sale</c> mở cho người chỉ
            có <c>ChatConversation.ViewChannel</c> — đường ĐỌC nhận vai ấy, nhưng cả ba tab bên
            trong gọi ba đường GHI mà vai ấy <b>chắc chắn</b> ăn 403. Máy chủ trả cờ, giao diện ẩn
            hẳn tab; cùng khuôn <c>CanViewTeam</c> đã chạy đúng ở trang điểm.
            </para>
            <para>
            <b>Không đòi role nào</b>: câu "tôi được làm gì" phải trả lời được cho cả người không có
            quyền nào — họ nhận ba cờ <c>false</c>. Luật nằm ở hàm thuần
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresencePermissions"/> để có ca test gọi thẳng vào.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatPresenceController.GetMyPresence">
            <summary>Trạng thái sẵn sàng của chính người đăng nhập</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatPresenceController.SetMyPresence(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceModel)">
            <summary>Đặt trạng thái sẵn sàng cho chính mình</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatPresenceController.GetStaffPresence(System.Int32)">
            <summary>Trạng thái sẵn sàng của một nhân viên khác</summary>
            <remarks>
            Role chỉ mở cửa vào tính năng; <b>phạm vi "được xem của ai" nằm ở tầng service</b>.
            Không chấm phạm vi ở đây thì endpoint này thành máy tra tên và ghi chú theo mã tuỳ ý —
            đúng hình dạng finding F-4 của giai đoạn A, và đúng bài học IDOR của
            <c>docs/security-audit-2026-07-11.md</c>: chặn ở giao diện không phải là chặn.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatPresenceController.SetStaffPresence(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceModel)">
            <summary>Đặt trạng thái sẵn sàng hộ một nhân viên khác</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatPresenceController.SetMyWorkingHours(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel)">
            <summary>
            Đặt, sửa hoặc xoá giờ làm việc riêng của chính mình (KC-18). Gửi giờ bắt đầu và giờ kết
            thúc cùng trống là xoá, về "chưa đặt".
            </summary>
            <remarks>
            Cùng role với <c>POST me</c>: đặt giờ làm là việc của chính người làm chat, và chip
            trạng thái mở hộp này ở mọi trang. Service <b>không đọc</b> <c>StaffId</c> trong thân.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatPresenceController.SetStaffWorkingHours(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel)">
            <summary>Đặt, sửa hoặc xoá giờ làm việc riêng hộ một nhân viên khác (KC-18)</summary>
            <remarks>
            Chủ dự án chốt (§8.7 câu 4): <b>cùng quyền</b> với đặt trạng thái hộ, không tạo quyền mới.
            Phạm vi "được đặt cho ai" chấm ở tầng service như <c>POST staff</c>.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatPresenceController.Suspend(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceSuspendModel)">
            <summary>Tạm ngưng chia khách cho một nhân viên, hoặc gỡ lệnh tạm ngưng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatPresenceController.Delegate(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceDelegateModel)">
            <summary>
            Uỷ quyền tạm hội thoại của một người đang không sẵn sàng cho người khác cùng kênh.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatPresenceController.SearchDurations(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Bảng thời lượng theo trạng thái — mỗi nhân viên một dòng.
            </summary>
            <remarks>
            Nhận <see cref="T:Lada.Framework.DTO.SmartTable.SmartTableParam"/>, nên client <b>bắt buộc</b> gửi đủ cả
            <c>Pagination</c>, <c>Search</c> và <c>Sort</c>. Ba trường ấy là kiểu tham chiếu
            non-nullable trong một assembly bật <c>&lt;Nullable&gt;enable</c>, nên ASP.NET Core suy
            ra <c>[Required]</c> ngầm và <c>[ApiController]</c> biến thiếu trường thành <b>400
            trước khi dòng code đầu tiên của action chạy</b>. Đó là lỗi L13 đã làm hàng chờ
            <c>/dieu-phoi-chat</c> chưa từng nạp được kể từ khi trang ra đời, và không ca test nào
            bắt được vì test gọi thẳng service.
            <para>
            Phạm vi "được nhìn thấy ai" nằm ở tầng service, không ở đây: ba vai mở được trang có
            phạm vi rất khác nhau.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.SocialChat.ChatQualityController">
            <summary>
            Điểm chất lượng chat (giai đoạn F) — điểm của chính mình và bảng điểm đội.
            </summary>
            <remarks>
            <para>
            <b>Hai đường, hai mức quyền khác hẳn nhau</b>, và đó là chốt CH-8: xem điểm <b>của mình</b>
            thì ai cũng xem được, không đòi quyền gì; xem điểm <b>người khác</b> đòi
            <c>ChatQuality.ViewTeam</c>. Đặt cả hai sau cùng một role là hoặc chặn sale xem điểm của
            chính họ (làm bộ điểm thành bảng phạt bí mật), hoặc mở điểm của mọi người cho tất cả.
            </para>
            <para>
            <b>Trả cờ <c>CanViewTeam</c> để giao diện ẩn hẳn tab thay vì đặt ở đó một cái nút chắc chắn
            trả 403.</b> Khuôn <c>CanReplay</c> của giai đoạn D, và nó tồn tại vì hình dạng "route mở
            cho vai A nhưng API đòi vai B" đã cắn <b>bốn lần</b> trong đợt này. <c>ChatQuality.ViewTeam</c>
            là quyền hẹp hơn quyền vào trang — trang <c>/diem-chat-cua-toi</c> mở cho mọi người.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatQualityController.GetMyScore">
            <summary>
            Điểm của chính người đang đăng nhập, kèm điểm từng tiêu chí, cỡ mẫu và việc cần làm.
            </summary>
            <remarks>
            Cố ý <b>không</b> nhận tham số <c>staffId</c>. Một đường "xem điểm của người X" nhận mã
            người từ client là một lỗ IDOR sẵn sàng — bài học của <c>docs/security-audit-2026-07-11.md</c>
            và của chính đợt này ở 13 endpoint giai đoạn A. Muốn xem người khác thì đi đường
            <c>team</c>, và đường ấy có role riêng cộng một phép thu hẹp phạm vi.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatQualityController.GetTeam">
            <summary>Điểm của những người trong phạm vi xem của mình.</summary>
            <remarks>
            Role mở cửa, <c>IChatVisibilityResolver</c> quyết phạm vi. Hai lớp, không một —
            <b>Founder bypass chỉ vượt kiểm tra ROLE, không vượt <c>DataAccessScope</c></b>.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.SocialChat.ChatQuickReplyController">
            <summary>
            API mẫu tin nhắn nhanh — danh sách chọn ở ô soạn tin và trang quản lý <c>/tin-nhan-nhanh</c>
            (docs/plan-tin-nhan-nhanh-chat.md §3.3). Gửi tin từ mẫu nằm ở <c>api/socialchat/send-quick-reply</c>.
            </summary>
            <remarks>
            <para>
            <b>Mỗi phạm vi một cặp endpoint ghi, gác bằng một role khác nhau</b> — <c>save-personal</c>/
            <c>personal/{id}</c> đòi <c>ChatConversation.Send</c>, <c>save-shared</c>/<c>shared/{id}</c> đòi
            <c>ChatQuickReply.ManageShared</c>. Role không nằm trong JWT (rule <c>backend-contracts</c>), nên chấm
            "được sửa mẫu dùng chung không" trong service là phải kéo lớp phân giải role vào; đặt trên attribute
            thì <c>/security-review</c> đọc được ngay. Phạm vi và chủ nhân của bản ghi thì chấm ở service.
            </para>
            <para>
            <b>Ba lời gọi ĐỌC mở cho cả ba role</b> <c>ChatConversation.Search</c>, <c>ChatConversation.Send</c>,
            <c>ChatQuickReply.ManageShared</c> — rộng hơn plan §3.3 (chỉ <c>Search</c>) một cách có chủ ý: dòng
            menu <c>/tin-nhan-nhanh</c> mở cho <c>Send</c> và <c>ManageShared</c>, nên gác trang bằng
            <c>Search</c> là để người chỉ có <c>ManageShared</c> vào được trang rồi ăn 403 và bị đá khỏi SPA —
            đúng họ lỗi rule <c>quyen-hien-thi</c> chặn. Không mở thêm dữ liệu nào: ai đọc được gì vẫn do
            hàng rào của service quyết định.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatQuickReplyController.ForPicker">
            <summary>Danh sách gọn cho ô chọn ở ô soạn tin: mẫu dùng chung đang bật + mẫu cá nhân đang bật của tôi</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatQuickReplyController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,Lada.Framework.Data.Enums.ChatQuickReplyScope)">
            <summary>Bảng ở trang quản lý, theo một phạm vi</summary>
            <param name="model">Phân trang, sắp xếp; <c>Search.PredicateObject</c> nhận <c>globalSearch</c>, <c>IsActive</c></param>
            <param name="scope">1 = của tôi, 2 = dùng chung</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatQuickReplyController.GetById(System.Int32)">
            <summary>Một mẫu để mở form sửa; ngoài phạm vi thấy được thì 404</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatQuickReplyController.SavePersonal(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SaveChatQuickReplyModel)">
            <summary>Tạo hoặc sửa mẫu cá nhân của chính mình (multipart, kèm ảnh tuỳ chọn)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatQuickReplyController.SaveShared(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SaveChatQuickReplyModel)">
            <summary>Tạo hoặc sửa mẫu dùng chung cho cả công ty (multipart, kèm ảnh tuỳ chọn)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatQuickReplyController.DeletePersonal(System.Int32)">
            <summary>Xoá mềm mẫu cá nhân của chính mình; tệp ảnh giữ nguyên</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatQuickReplyController.DeleteShared(System.Int32)">
            <summary>Xoá mềm mẫu dùng chung; tệp ảnh giữ nguyên</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.ChatQuickReplyController.CanManageSharedAsync(System.Int32)">
            <summary>
            Cùng nguồn với cờ <c>CanManageSharedQuickReplies</c> của <c>nav-permissions</c>: giao diện ẩn nút ghi
            theo cờ ấy, và bảng dùng chung hiện mẫu đã tắt theo đúng luật ấy — hai nơi không được đọc hai luật.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController">
            <summary>
            API khung chat cho SPA quản trị.
            <para>
            Mọi hành động chấm quyền server-side bằng <c>[Authorize(Roles = …)]</c> — role tra từ
            database qua <c>ServerRoleAuthorizationHandler</c>, không nằm trong JWT. Không có endpoint
            nào ở đây tin vào việc giao diện đã ẩn nút.
            </para>
            <para>
            <b>Phạm vi dữ liệu chấm ở tầng service, không phải ở đây.</b> Mọi action truyền
            <c>User.GetCurrentUser().UserId</c> xuống service, và service hỏi
            <c>IChatVisibilityResolver</c> — một luật, một chỗ. Rải <c>if</c> phạm vi lên controller là
            đúng hình dạng lỗi IDOR của <c>docs/security-audit-2026-07-11.md</c>: đường thứ hai vào
            cùng dữ liệu sẽ quên mất cái <c>if</c> ấy.
            </para>
            <para>
            Kênh còn ở chế độ <c>Shared</c> thì hàng rào không đổi gì — ai có quyền vẫn xem được mọi
            hội thoại của kênh đó, đúng hành vi trước đợt phân phối (§6.3).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.SearchConversations(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách hội thoại cho cột trái của khung chat</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.GetConversation(System.Int32,System.Int32)">
            <summary>Chi tiết một hội thoại kèm các tin gần nhất</summary>
            <param name="id">Hội thoại cần mở</param>
            <param name="messageLimit">Số tin nạp sẵn; bỏ trống là 50, trần 200</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.GetOlderMessages(System.Int32,System.Int32,System.Int32)">
            <summary>
            Nạp thêm tin CŨ HƠN một tin đã có trên màn hình — nút "xem thêm tin cũ".
            </summary>
            <param name="id">Hội thoại</param>
            <param name="beforeMessageId">Mã tin cũ nhất đang hiện; chỉ lấy tin có mã nhỏ hơn nó</param>
            <param name="limit">Số tin lấy thêm; bỏ trống là 50, trần 200</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.MarkRead(System.Int32)">
            <summary>Đánh dấu một hội thoại là đã đọc hết</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.SyncHistory(System.Int32)">
            <summary>
            Kéo lại các tin gần nhất của hội thoại từ nền tảng và chèn tin LADA còn thiếu — nút
            "Đồng bộ lại" trên khung chat.
            </summary>
            <remarks>
            Ca gốc là tin Page tự trả lời riêng từ bình luận Facebook: webhook không chở tới, nên khung chat
            chỉ có câu trả lời của khách mà mất câu hỏi đứng trước. Job <c>chat-history-sync</c> tự kéo cho
            hội thoại mới; nút này cho hội thoại có từ trước.
            <para>
            Gác bằng <c>ChatConversation.GetById</c> — role mở hội thoại, cùng role với
            <c>mark-read</c> — và phạm vi ĐỌC ở tầng service: thao tác chỉ chép lại thứ đã có trên nền tảng,
            không gửi gì cho khách.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.GetNavPermissions">
            <summary>
            Những phần tử điều hướng của miền chat mà người đang đăng nhập được phép thấy.
            </summary>
            <remarks>
            <para>
            <b>Khuôn <c>CanReplay</c> / <c>CanViewTeam</c>, áp cho hai liên kết trên thanh công cụ
            khung chat</b> (sổ nợ PP-39). Máy chủ trả cờ, giao diện <b>ẩn hẳn</b> liên kết — không
            để giao diện đoán theo role tự chép sang JavaScript, cũng không để liên kết hiện rồi
            người dùng bấm vào và ăn 403. Đây là lần thứ <b>bảy và tám</b> của họ lỗi "route mở cho
            vai A nhưng API đòi vai B" trong cùng một đợt, và khuôn chống nó đã chạy đúng ngay cạnh:
            P7 đo được tab "Điểm đội" <b>không tồn tại trong DOM</b> của một sale.
            </para>
            <para>
            <b>Endpoint riêng thay vì ký sinh vào <c>unread-count</c></b>, vì có <b>ba</b> màn cần
            hai cờ này — khung chat, <c>/trang-thai-sale</c>, và <c>/kenh-chat</c> — mà chỉ khung
            chat gọi <c>unread-count</c>. Ký sinh thì hai màn kia phải tự chép lại luật.
            </para>
            <para>
            <b>Không đòi role nào</b>: câu "tôi được thấy gì" phải trả lời được cho cả người không
            có quyền chat nào — họ nhận hai cờ <c>false</c>. Gác nó bằng role là dựng đúng cái lỗi
            nó sinh ra để chữa.
            </para>
            <para>
            <b>Bốn cờ đọc bốn bó quyền KHÁC NHAU, và cố ý không dùng quyền của lời gọi dữ liệu.</b>
            Riêng trang <c>/kenh-chat</c> cần <b>ba</b> cờ vì nó có ba nhóm thao tác gác bằng ba
            bó quyền khác nhau: <c>CanOpenChannelPage</c> (vào được trang — <c>ChatChannel.Manage</c>
            <b>hoặc</b> <c>ChatChannel.StaffAssign</c>), <c>CanManageChannels</c> (cấp quyền OAuth
            — chỉ <c>ChatChannel.Manage</c>) và <c>CanUpdateAssignmentSettings</c> (khối cấu hình
            kênh — <c>StaffAssign</c> <b>và</b> <c>ChatDistribution.Manage</c>, đúng phép AND hai
            lớp gác của <c>channel/assignment-settings</c>; PP-46). Gộp cờ theo chiều nào cũng sai:
            gộp về <c>Manage</c> thì trưởng nhóm mất đường vào trang duy nhất của họ, gộp về bó của
            <c>channel/all</c> thì người chỉ ĐỌC thấy nút cấp quyền OAuth và ăn 403.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.GetUnreadCount">
            <summary>Tổng số tin chưa đọc trên mọi hội thoại</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.Send(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendChatMessageModel)">
            <summary>Trả lời một hội thoại bằng tin nhắn văn bản</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.SendReaction(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendChatReactionModel)">
            <summary>
            Thả hoặc gỡ một biểu tượng cảm xúc trên một tin nhắn.
            <para>
            Dùng chung quyền <c>ChatConversation.Send</c> với việc gửi tin, không tạo quyền thứ hai:
            đây vẫn là một hành động ra ngoài, khách nhìn thấy được, và ai được trả lời khách thì
            đương nhiên được thả một biểu tượng cảm xúc. Một quyền riêng chỉ thêm một dòng phải seed
            và một chỗ nữa để quên cấp.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.SendImage(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendChatImageModel)">
            <summary>
            Trả lời một hội thoại bằng hình ảnh.
            <para>
            Nhận CHÍNH TỆP chứ không nhận đường dẫn: <c>SendChatMessageParam.LocalImagePath</c> là
            đường dẫn trên đĩa máy chủ, để client đặt được giá trị đó là mở đường đọc tệp bất kỳ
            của máy chủ rồi gửi ra ngoài cho khách. Ở đây máy chủ lưu tệp rồi tự điền đường dẫn.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.SendQuickReply(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendQuickReplyModel)">
            <summary>
            Trả lời một hội thoại, xuất phát từ một mẫu tin nhắn nhanh (docs/plan-tin-nhan-nhanh-chat.md §3.2, §3.3).
            <para>
            <b>Ảnh lấy từ mẫu, không nhận từ client.</b> Client chỉ gửi mã mẫu và cờ <c>WithImage</c>; đường dẫn tệp
            trên đĩa máy chủ do máy chủ tra theo mã mẫu — cùng lý do <c>send-image</c> nhận chính tệp chứ không nhận
            đường dẫn. Mẫu phải thấy được với người gửi (mẫu dùng chung, hoặc mẫu cá nhân của chính họ) và đang bật.
            </para>
            <para>
            Nội dung gửi đi là chữ trong ô soạn mà nhân viên đã sửa, không phải nội dung gốc của mẫu. Bên trong gọi
            <b>đúng</b> <c>SendMessageAsync</c> mà <c>send</c> và <c>send-image</c> dùng — cùng hàng rào phạm vi ghi,
            cùng kiểm kênh, cùng luật trích dẫn. Zalo/Facebook không biết có "mẫu".
            </para>
            <para>
            Không hỏi <c>EnsureCanSendAsync</c> trước như <c>send-image</c>: ở đó câu hỏi trước tồn tại để khỏi ghi
            một tệp mồ côi xuống đĩa, còn ở đây ảnh đã nằm sẵn trên đĩa — <c>SendMessageAsync</c> tự chặn đúng những
            trường hợp ấy trước khi lưu tin.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.SuggestCustomers(System.String)">
            <summary>
            Gợi ý khách hàng để gắn vào hội thoại.
            <para>
            <b>Đi qua đúng <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.Suggest(System.String,System.Int32)"/> của phân hệ khách hàng, không tự
            truy vấn bảng Customer.</b> Phân hệ đó có sẵn một luật phạm vi mà cả hệ thống đang
            dựa vào: ngoài Founder, không ai được duyệt danh sách khách của người khác — người
            dùng thường chỉ tìm trong khách mình phụ trách, và chỉ khi gõ ĐỦ số điện thoại mới
            tìm được toàn hệ thống (kết quả khi đó là duy nhất nên không lộ tệp khách của ai).
            </para>
            <para>
            Role <c>ChatConversation.LinkCustomer</c> mở CỬA vào tính năng gắn khách; nó không, và
            không được, mở rộng phạm vi dữ liệu khách hàng mà tài khoản đó vốn được xem. Tự viết
            một câu truy vấn mới ở đây là dựng một cửa sau vào tệp khách hàng của công ty.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.LinkCustomer(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.LinkChatCustomerModel)">
            <summary>
            Gắn hội thoại với một khách hàng trong hệ thống.
            <para>
            Trước khi gắn, mã khách hàng được đối chiếu lại bằng CHÍNH đường gợi ý có phạm vi ở
            trên. Nếu không, endpoint này thành một máy tra tên khách hàng theo mã: gọi lần lượt
            <c>CustomerId</c> = 1, 2, 3… là đọc được tên của cả tệp khách hàng, không cần từ khoá.
            Đối chiếu lại bằng cùng một luật thì không có luật thứ hai để lệch.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.UnlinkCustomer(System.Int32)">
            <summary>Gỡ liên kết khách hàng khỏi hội thoại (gắn nhầm người)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.SuggestStaff(System.String,System.Int32)">
            <summary>
            Danh sách nhân viên có thể nhận phân công.
            <para>
            Endpoint riêng của phân hệ chứ không dùng chung <c>User/SugStaff</c>: đường kia đòi
            role <c>User.SugStaff</c> mà nhân viên chăm sóc khách hàng không có lý do gì phải có.
            </para>
            <para>
            Nhưng nó phải chấm ĐÚNG phạm vi dữ liệu mà <c>User/SugStaff</c> chấm — mặc định của
            <c>DataAccessScope</c> là <c>SelfOnly</c>, nên bỏ bước này là một tài khoản vốn chỉ
            thấy chính mình lại đọc được danh bạ nhân sự của cả công ty. Role mở cửa vào tính
            năng, không mở rộng phạm vi dữ liệu.
            </para>
            </summary>
            <param name="keyword">Từ khoá theo tên hoặc tên đăng nhập</param>
            <param name="chatChannelId">
            Kênh của hội thoại sắp phân công. Truyền vào thì kết quả bị thu hẹp thêm một lần nữa —
            chỉ còn người có tên trong danh sách phụ trách của kênh, nếu kênh đó đã bật hàng rào.
            Không truyền thì giữ nguyên hành vi cũ; kênh <c>Shared</c> cũng vậy.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.Assign(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.AssignChatConversationModel)">
            <summary>
            Phân công hội thoại cho nhân viên, hoặc gỡ phân công khi không truyền mã nhân viên.
            <para>
            Trên kênh <c>Shared</c> đây vẫn CHỈ là nhãn. Trên kênh đã bật hàng rào, phân công là
            hành động <b>đổi phạm vi dữ liệu</b> — nên có ba lớp chặn: hội thoại phải nằm trong
            phạm vi mình thấy (tầng service), người được gán phải trong phạm vi nhân sự của mình
            (ngay dưới đây), và phải có tên trong danh sách phụ trách kênh (tầng service).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.Release(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ReleaseChatConversationModel)">
            <summary>
            Nhả hội thoại về hàng chờ.
            </summary>
            <remarks>
            <para>
            Không chấm gì thêm ở đây, và đó là chủ ý: câu hỏi "tôi có được nhả hội thoại này không"
            chính là câu hỏi "hội thoại này có nằm trong phạm vi ghi của tôi không", mà phạm vi thì
            tầng service hỏi <c>IChatVisibilityResolver</c>. Một sale mức <c>Self</c> vì thế chỉ nhả
            được hội thoại mình đang cầm; trưởng nhóm nhả được hội thoại của kênh mình.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.Transfer(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.TransferChatConversationModel)">
            <summary>
            Chuyển hội thoại sang nhân viên khác.
            </summary>
            <remarks>
            <para>
            <b>Đường này không được thành đường đọc trộm</b> (§3.11). "Chuyển về cho mình rồi đọc"
            bị chặn ở tầng service, bằng chính hàng rào: hội thoại phải nằm trong phạm vi <b>ghi</b>
            của người thực hiện trước đã, nên một sale không chuyển được hội thoại của người khác
            về mình — họ không nạp nổi nó.
            </para>
            <para>
            Ở đây chỉ còn vế thứ hai, giống hệt <c>assign</c>: người nhận phải nằm trong phạm vi
            nhân sự của người chuyển. Vế thứ ba — người nhận phải có tên trong danh sách phụ trách
            kênh — nằm ở tầng service, dùng lại đúng một hàm với <c>assign</c>.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.RevokeReadAccess(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.RevokeChatReadAccessModel)">
            <summary>
            Thu hồi quyền xem một hội thoại của nhân viên đã thôi giữ nó.
            </summary>
            <remarks>
            <para>
            Đường này tồn tại vì §6.2 có một khe hở mà chính người sắp bị cắt điều khiển được: cờ
            <c>KeepReadAccess</c> chỉ ghi lúc đóng một lượt đang mở, nên sale tự nhả trước với lý
            do hành chính là lượt của họ đóng lại với cờ giữ quyền — và từ đó quản lý không còn
            lượt nào để đóng, dù khách đã phàn nàn.
            </para>
            <para>
            Role là quyền định đoạt người phụ trách (<c>Transfer</c>) hoặc quản trị phân phối; phạm
            vi dữ liệu vẫn do tầng service chấm, nên một sale không thu hồi được quyền xem của ai
            trên hội thoại ngoài phạm vi ghi của mình.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.GetAssignments(System.Int32)">
            <summary>
            Lịch sử phân công của một hội thoại — "ai từng cầm hội thoại này, vì sao thôi cầm".
            Hội thoại ngoài phạm vi đọc trả về danh sách rỗng, không phải lỗi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.SearchQueue(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Hàng chờ — hội thoại chưa giao cho ai (sổ nợ PP-14).
            </summary>
            <remarks>
            <para>
            Hai quyền cùng vào được, vì có hai vai làm cùng một việc: người điều phối toàn hệ thống
            (<c>ChatDistribution.Manage</c>) và trưởng nhóm của một kênh
            (<c>ChatConversation.ViewChannel</c>). Phạm vi dữ liệu của hai vai vẫn khác nhau —
            trưởng nhóm chỉ thấy hàng chờ của kênh mình, và điều đó do
            <c>IChatVisibilityResolver</c> quyết, không do role.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.IsStaffInMyScopeAsync(System.Int32,System.Int32,System.Int32)">
            <summary>
            Một nhân viên có nằm trong phạm vi nhân sự mà người đang đăng nhập được phép chọn không.
            </summary>
            <remarks>
            <para>
            Đúng luật của <c>staff/suggest</c> ở trên, viết một lần cho cả <c>assign</c> lẫn
            <c>transfer</c>. Không có bước này thì gọi lần lượt mã 1, 2, 3… là đọc được tên của
            toàn bộ bảng người dùng, kể cả tài khoản khách hàng, và giao được việc cho tài khoản đã
            khoá. Hai đường ghi cùng hình dạng mà chép luật ra hai chỗ là để chúng lệch nhau ở lần
            sửa sau — đúng hình dạng lỗi IDOR của <c>docs/security-audit-2026-07-11.md</c>.
            </para>
            <para>
            <b>Ba mức, và mức <c>SelfOnly</c> lấy phạm vi từ một nguồn KHÁC hai mức kia</b>
            (sổ nợ PP-38, kế hoạch §6.6, chốt 2026-08-30). <c>All</c> và <c>ManagedTeam</c> đọc
            phạm vi nhân sự từ <c>UserPreference</c>; <c>SelfOnly</c> thì không có phạm vi nhân sự
            nào cả, nên nó lấy <b>danh sách phụ trách của chính kênh chứa hội thoại này</b>. Lý do
            là một con số: <b>40/40 sale nhóm "Kinh doanh" đều <c>SelfOnly</c></b> (đo trên dev
            2026-08-30, chưa đối chiếu production), nên trước bản vá này nút "Chuyển khách" là ngõ
            cụt với toàn đội: họ chỉ chọn được chính mình, mà chọn chính mình thì <c>transfer</c>
            trả "Người này đang phụ trách hội thoại."
            </para>
            <para>
            <b>Phạm vi mới HẸP hơn <c>ManagedTeam</c>, và hẹp theo hai chiều cùng lúc</b>: người
            nhận phải có tên trong danh sách phụ trách kênh, <b>và</b> chính người chuyển cũng phải
            có tên trong đó. Vế thứ hai là chữ "<b>cùng</b>" của §6.6, và nó không phải trang trí:
            thiếu nó thì trong suốt cửa sổ dry-run — mọi kênh còn <c>Shared</c>, nên
            <c>BuildWritableConversationFilter</c> trả <c>_ =&gt; true</c> và mọi sale có phạm vi
            GHI trên mọi hội thoại — một sale bất kỳ sẽ chuyển được hội thoại bất kỳ cho bất kỳ ai
            trong danh sách phụ trách của kênh đó, rộng hơn hẳn điều §6.6 mở ra. Có vế thứ hai thì
            hành vi trước bước 3 gần như không đổi, đúng nguyên tắc số 1.
            </para>
            <para>
            Trên kênh đã bật hàng rào, bản vá này <b>chỉ làm ô chọn khớp với luật máy chủ vốn đã
            áp</b>: người nhận vốn đã phải qua <c>IsAssignableToChannelAsync</c> ở tầng service.
            Trên kênh <c>Shared</c> thì máy chủ không áp hàng rào kênh nào cả (hàm kia trả
            <c>true</c> vô điều kiện), nên ở đó luật này <b>chặt hơn</b> máy chủ — sai về phía an
            toàn, chiều duy nhất được phép sai.
            </para>
            <para>
            <b>Ba điều bản vá KHÔNG làm</b> (§6.6): không nới phạm vi ĐỌC —
            <c>ChatVisibilityResolver</c> không đổi một dòng, nên sale vẫn không thấy hội thoại của
            người mình vừa chọn; không nâng <c>DataAccessScope</c> — lối ra (c) bị loại có chủ ý vì
            nó nới cả phạm vi đọc của CRM và nhân sự, đúng bẫy "mượn phân quyền miền khác" đã cắn
            ba lần ở đợt KPI; không để <c>staff/suggest</c> lệch khỏi hàm này — hai chỗ cùng đọc
            một danh sách qua <c>IChatChannelStaffService</c>, và lệch nhau là tự tay dựng lại một
            PP-36 mới.
            </para>
            <para>
            <b>Vì sao nới cả <c>assign</c> chứ không tách hai luật.</b> Nhóm quyền 2 giữ
            <c>ChatConversation.Assign</c> từ đợt chat đa nền tảng, nên hàm này phục vụ cả hai
            đường của cùng một người, và <c>staff/suggest</c> cũng phục vụ cả hai ô chọn. Tách hai
            luật là để ô "Phân công" gợi ý ra những người mà <c>assign</c> sẽ từ chối — tự tay dựng
            lại PP-36, đúng điều ràng buộc thứ hai của §6.6 cấm. Hệ quả phải nói ra chứ không giấu:
            <c>assign</c> ghi nhật ký với lý do cố định và ghi chú rỗng, còn <c>transfer</c> bắt
            buộc lý do + ghi chú, và chính lý do đó quyết định người cũ còn quyền xem hay không
            (§6.2). Nghĩa là sale nay có một đường đổi người <b>không ghi lý do</b>. Vẫn có vết —
            một dòng <c>ChatConversationAssignment</c> — nên nguyên tắc số 1 mục 4 không bị vi phạm,
            nhưng giao diện phải tiếp tục dẫn người dùng vào nút "Chuyển".
            </para>
            <para>
            "Nhận về tôi" luôn nằm trong phạm vi: chọn chính mình không mở rộng phạm vi đọc của ai.
            </para>
            </remarks>
            <param name="staffId">Nhân viên được chọn làm người nhận</param>
            <param name="currentUserId">Người đang thực hiện</param>
            <param name="conversationId">
            Hội thoại đang thao tác — nguồn của "cùng kênh" ở mức <c>SelfOnly</c>. Máy chủ tự tra
            kênh từ mã hội thoại; <b>tuyệt đối không nhận mã kênh từ client</b>, vì khi đó người gọi
            gửi mã kênh mình CÓ phụ trách kèm mã hội thoại của kênh KHÁC là chấm người nhận trên
            sai kênh.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.LaDongNghiepCungKenhAsync(System.Int32,System.Int32,System.Int32)">
            <summary>
            Hai người có <b>cùng</b> nằm trong danh sách phụ trách kênh của một hội thoại không —
            phạm vi của mức <c>SelfOnly</c> (sổ nợ PP-38).
            </summary>
            <remarks>
            Bước cuối vẫn đi qua <c>IChatStaffDirectory</c>, không tự truy vấn bảng người dùng: sàn
            "tài khoản kiểu nhân viên, chưa khoá" phải giữ nguyên. Một dòng <c>ChatChannelStaff</c>
            trỏ tới tài khoản đã khoá hay tài khoản khách hàng vẫn phải bị chặn —
            <c>restrictToStaffIds</c> là phép THU HẸP thêm, không phải đường đi vòng.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatController.ChangeStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChangeChatStatusModel)">
            <summary>
            Đổi trạng thái vòng đời của hội thoại: đang xử lý / chờ khách / đóng / mở lại.
            <para>
            Cả bốn chuyển dịch dùng chung role <c>ChatConversation.Close</c> — đó là quyền "định
            đoạt vòng đời hội thoại". Role này seed từ giai đoạn B, mô tả của nó được migration
            giai đoạn D chỉnh lại cho khớp phạm vi thật.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.SocialChat.SocialChatWebhookController">
            <summary>
            Điểm nhận webhook của các nền tảng chat. Đây là bề mặt công khai duy nhất của phân hệ chat.
            <para>
            Ba nguyên tắc của mọi endpoint trong lớp này:
            (1) tự bảo vệ bằng chữ ký chứ không bằng đăng nhập — nền tảng gọi tới không mang JWT;
            (2) LUÔN trả 200 khi lỗi nội bộ, nếu không nền tảng sẽ gửi lại vô hạn;
            (3) không bao giờ ghi nhật ký nội dung khoá bí mật hay chữ ký.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.SocialChat.SocialChatWebhookController.RoutePrefix">
            <summary>
            Tiền tố đường dẫn của toàn bộ endpoint webhook. Dùng chung cho
            <c>FrontendOriginMiddleware.BypassPaths</c> và phần miễn giới hạn tốc độ toàn cục —
            giữ một chỗ khai báo để ba nơi không bao giờ lệch nhau.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.SocialChat.SocialChatWebhookController.MaxBodyBytes">
            <summary>Giới hạn kích thước thân request: 1 MB, đủ rộng cho payload webhook lớn nhất của Zalo/Facebook</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatWebhookController.Zalo">
            <summary>
            Nhận sự kiện webhook của Zalo Official Account.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatWebhookController.FacebookVerify(System.String,System.String,System.String)">
            <summary>
            Bước bắt tay Facebook gọi đúng một lần lúc khai báo webhook trên cổng nhà phát triển
            (và mỗi lần đổi URL). Khớp verify token thì phải trả về nguyên văn <c>hub.challenge</c>.
            <para>
            Zalo không có bước này — đây là lý do endpoint Facebook cần thêm một động từ GET.
            Trả <c>text/plain</c> chứ không phải JSON: Facebook so sánh nguyên văn thân phản hồi
            với giá trị nó gửi đi, thêm dấu nháy của JSON là hỏng.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatWebhookController.Facebook">
            <summary>
            Nhận sự kiện webhook của Facebook Messenger (Page).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.SocialChat.SocialChatWebhookController.EnforceSignature">
            <summary>
            Bật thì chữ ký sai bị từ chối bằng 401; tắt thì chỉ ghi cảnh báo rồi vẫn xử lý.
            <para>
            Mặc định BẬT khi khoá cấu hình vắng mặt. Trước đây mặc định là tắt, nghĩa là một
            <c>appsettings.json</c> cũ chưa có khối <c>SocialChat</c> sẽ nhận mọi webhook không cần
            chữ ký — lớp bù duy nhất lúc đó là đối chiếu <c>app_id</c>, mà app_id không phải bí mật:
            nó nằm ngay trong đường dẫn cấp quyền được gửi cho admin OA bên ngoài. Muốn tắt thì
            phải khai tường minh <c>false</c>, tức là một quyết định có người ký tên.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatWebhookController.ReadRequestAsync">
            <summary>
            Đọc thân request nguyên văn cùng toàn bộ header.
            Chữ ký được tính trên chuỗi thô nên tuyệt đối không đọc qua model binding.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatWebhookController.ProcessAsync(Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.IWebhookParser,Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookRequestContext)">
            <summary>
            Chạy luồng xử lý chung. Mọi lỗi nội bộ đều bị nuốt và trả 200 kèm nhật ký mức Error —
            trả mã lỗi ra ngoài chỉ khiến nền tảng gửi lại mãi mà không sửa được gì.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.SocialChat.SocialChatWebhookController.IsExpectedZaloApp(System.String)">
            <summary>
            Kiểm <c>app_id</c> trong payload có đúng ứng dụng Zalo của LADA không.
            <para>
            Đây là lớp bảo vệ duy nhất còn lại khi chữ ký chưa xác minh được (sổ nợ SC-7), nên nó
            **đóng khi thiếu cấu hình**: chưa khai App ID thì không có cách nào biết payload là của ai,
            và một webhook công khai không danh tính thì phải từ chối chứ không phải cho qua.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.AgencyController">
            <summary>
            Controller để xử lý các hoạt động liên quan đến đại lý.
            </summary>
            <summary>
            Controller để xử lý các hoạt động liên quan đến đại lý.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyService,Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService,Ladaer.BackEnd.Infrastructures.Services.Identity.IUserRoleResolver,Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyCoverageExcelService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Systems.AgencyController"/>.
            </summary>
            <param name="agencyService">Dịch vụ xử lý đại lý.</param>
            <param name="userService">Dịch vụ xử lý người dùng.</param>
            <param name="roleResolver">Dịch vụ phân giải role của user.</param>
            <param name="coverageExcelService">Dịch vụ xuất Excel vùng phủ.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyController.GetCurrentAgencyHierarchyAsync">
            <summary>
            Lấy danh sách agencyIds thuộc chi nhánh hiện tại và con cháu.
            Trả về null nếu user không bị giới hạn phạm vi (Founder hoặc không có agency).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyController.IsAgencyInScopeAsync(System.Int32)">
            <summary>
            Kiểm tra agencyId có nằm trong phạm vi chi nhánh cho phép không.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các đại lý dựa trên các tham số được cung cấp.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyModel)">
            <summary>
            Tạo hoặc cập nhật thông tin đại lý.
            </summary>
            <param name="agencyModel">Model chứa thông tin đại lý.</param>
            <returns>Kết quả của hoạt động tạo hoặc cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của một đại lý dựa trên ID.
            </summary>
            <param name="id">ID của đại lý.</param>
            <returns>Thông tin chi tiết của đại lý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyController.AutoComplete(System.String)">
            <summary>
            Tìm kiếm đại lý dựa trên từ khóa.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <returns>Danh sách đại lý phù hợp.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyController.Delete(System.Int32)">
            <summary>
            Xóa một đại lý dựa trên ID.
            </summary>
            <param name="id">ID của đại lý.</param>
            <returns>Kết quả của hoạt động xóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyController.UpdateStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyStatusModel)">
            <summary>
            Cập nhật trạng thái của một đại lý.
            </summary>
            <param name="agencyStatusModel">Model chứa thông tin trạng thái của đại lý.</param>
            <returns>Kết quả của hoạt động cập nhật trạng thái.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyController.GetTree(System.String)">
            <summary>
            Lấy danh sách đại lý dưới dạng cây.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <returns>Danh sách đại lý dưới dạng cây.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyController.ExportCoverage">
            <summary>
            Xuất Excel vùng phủ của tất cả chi nhánh trong phạm vi quyền
            </summary>
            <returns>Kết quả xuất file Excel</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.AgencyLocationController">
            <summary>
            Controller để xử lý các hoạt động liên quan đến vùng phủ của đại lý
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyLocationController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyLocationService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Systems.AgencyLocationController"/>.
            </summary>
            <param name="agencyLocationService">Service xử lý vùng phủ của đại lý</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyLocationController.GetAgencyCoverage(System.Int32)">
            <summary>
            Lấy thông tin vùng phủ của đại lý
            </summary>
            <param name="agencyId">ID của đại lý</param>
            <returns>Thông tin vùng phủ bao gồm danh sách location</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyLocationController.AddLocation(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AddLocationsToAgencyModel)">
            <summary>
            Thêm location vào đại lý
            </summary>
            <param name="model">Model chứa AgencyId và danh sách LocationIds cần thêm</param>
            <returns>Kết quả của hoạt động thêm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyLocationController.RemoveLocation(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AddLocationsToAgencyModel)">
            <summary>
            Xóa location khỏi đại lý
            </summary>
            <param name="model">Model chứa AgencyId và danh sách LocationIds cần xóa</param>
            <returns>Kết quả của hoạt động xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AgencyLocationController.GetAvailableLocationsTree(System.Int32,System.Int32)">
            <summary>
            Lấy danh sách location chưa được gán cho đại lý dưới dạng cây (lazy loading)
            </summary>
            <param name="agencyId">ID của đại lý</param>
            <param name="parentId">ID của location cha (0 = lấy tỉnh/thành phố, >0 = lấy con của location đó)</param>
            <returns>Danh sách location dưới dạng cây hierarchical, chỉ lấy location có type Urban hoặc SubUrban</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.SearchMarketing(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm nội dung marketing với SmartTableParam (search, filter, sort, pagination)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.AiController.BlogRequest">
            <summary>
            Tạo bài blog từ brief
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.AiController.SocialPostRequest">
            <summary>
            Tạo bài social media từ brief
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.AiController.ReviewRequest">
            <summary>
            Duyệt nội dung marketing
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.GetPendingReview">
            <summary>
            Lấy danh sách nội dung chờ duyệt
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.GetContent(System.Guid)">
            <summary>
            Lấy chi tiết nội dung theo ID
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Systems.AiController.GenerateImageRequest.ModelName">
            <summary>Mainline model cho Responses API (orchestrator)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Systems.AiController.GenerateImageRequest.UseBrandContext">
            <summary>Tự động gắn brand context (developer instructions + file_ids + vector store)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Systems.AiController.GenerateImageRequest.AssetKeys">
            <summary>Chọn brand assets cụ thể theo key (null = tất cả active)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Systems.AiController.GenerateImageRequest.EnhancePrompt">
            <summary>Tự động viết lại prompt thành prompt tiếng Anh chi tiết trước khi tạo ảnh</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.GenerateImage(Ladaer.BackEnd.Controllers.Systems.AiController.GenerateImageRequest)">
            <summary>
            Tạo ảnh bằng AI, tải về và lưu vào media storage
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.UpdateContentHtml(System.Guid,Ladaer.BackEnd.Controllers.Systems.AiController.UpdateContentHtmlRequest)">
            <summary>
            Cập nhật nội dung HTML của bài viết (sau khi chèn ảnh)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.GetBrandRegistry">
            <summary>
            Lấy brand registry hiện tại
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.AiController.UpdateInstructionsRequest">
            <summary>
            Cập nhật developer instructions
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.UploadBrandAsset(Microsoft.AspNetCore.Http.IFormFile,System.String,System.String,System.String,System.String)">
            <summary>
            Upload brand asset lên OpenAI Files API
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.GetBrandAssets">
            <summary>
            Lấy danh sách brand assets đang active
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.DeleteBrandAsset(System.Int32)">
            <summary>
            Xóa brand asset
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.SyncVectorStore">
            <summary>
            Sync knowledge base lên OpenAI Vector Store
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.GetBrandStatus">
            <summary>
            Trạng thái hiện tại: VectorStoreId đang dùng + danh sách OpenAiFileId của Brand Assets
            Dùng cho trang Kho tài nguyên để highlight tài nguyên đang active
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.AiController.RegisterAssetRequest">
            <summary>
            Đăng ký file đã có trên OpenAI làm Brand Asset (không upload lại)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.AiController.LinkVectorStoreRequest">
            <summary>
            Gắn Vector Store đã có làm Knowledge Base cho Brand Registry
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.CreateProviderClientAsync(System.Int32,System.Boolean)">
            <summary>
            Helper: Lấy provider entity by Id và tạo HttpClient có auth
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.GetVectorStores(System.Int32)">
            <summary>
            Lấy danh sách Vector Stores của 1 provider
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.CreateVectorStore(System.Int32,Ladaer.BackEnd.Controllers.Systems.AiController.CreateVectorStoreRequest)">
            <summary>
            Tạo Vector Store mới cho 1 provider
            POST /v1/vector_stores
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.GetVectorStoreDetail(System.Int32,System.String)">
            <summary>
            Lấy chi tiết 1 Vector Store + files
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.GetUploadedFiles(System.Int32)">
            <summary>
            Lấy danh sách Files đã upload của 1 provider
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.UploadFile(System.Int32,Microsoft.AspNetCore.Http.IFormFile,System.String)">
            <summary>
            Upload file lên OpenAI cho 1 provider
            POST /v1/files (multipart/form-data: file + purpose)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AiController.DeleteFile(System.Int32,System.String)">
            <summary>
            Xóa file trên OpenAI cho 1 provider
            DELETE /v1/files/{fileId}
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.AppConfigController">
            <summary>
            Controller quản lý cấu hình ứng dụng (AppConfig)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AppConfigController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm AppConfig với SmartTable
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Kết quả tìm kiếm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AppConfigController.GetById(System.Int32)">
            <summary>
            Lấy AppConfig theo Id
            </summary>
            <param name="id">Id của AppConfig</param>
            <returns>AppConfig</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AppConfigController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.CreateAppConfigModel)">
            <summary>
            Tạo hoặc cập nhật AppConfig
            </summary>
            <param name="model">Model AppConfig</param>
            <returns>Kết quả thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AppConfigController.Delete(System.Int32)">
            <summary>
            Xóa AppConfig
            </summary>
            <param name="id">Id của AppConfig</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.AppConfigController.ReloadCache">
            <summary>
            Reload cache cho tất cả applications
            </summary>
            <returns>Kết quả reload</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.CacheController">
            <summary>
            API quản lý cache — chỉ Founder mới được phép truy cập.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CacheController.GetStats">
            <summary>
            Lấy thống kê cache: tổng entries, danh sách groups theo prefix, provider đang dùng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CacheController.GetEntries(System.String)">
            <summary>
            Lấy danh sách cache entries, có thể lọc theo prefix.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CacheController.GetValueByKey(System.String)">
            <summary>
            Lấy giá trị đầy đủ của 1 cache entry theo key.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CacheController.RemoveByKey(System.String)">
            <summary>
            Xóa 1 cache entry theo key chính xác.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CacheController.RemoveByPrefix(System.String)">
            <summary>
            Xóa tất cả cache entries có key bắt đầu bằng prefix.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CacheController.ClearAll">
            <summary>
            Xóa toàn bộ cache.
            </summary>
            <remarks>
            Phải gọi <b>hai</b> lớp. <see cref="T:Ladaer.BackEnd.Infrastructures.Caching.ICacheService"/> chỉ xoá được khoá do chính nó ghi (tiền tố
            <c>"AppConfig:"</c> và các nhóm khác), còn <c>Lada.Framework.AppConfigService</c> ghi thẳng vào
            <c>IMemoryCache</c> với tiền tố <c>"AppConfig_"</c> — chính là nhóm khoá mà mọi công tắc
            <c>ContentStore.*</c> đi qua. Thiếu vế thứ hai thì nút này báo "đã xoá" trong khi giá trị cũ vẫn
            sống, và người vận hành kết luận sai là cấu hình không có tác dụng (nợ CS-20).
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.CallPathController">
            <summary>
            Controller để xử lý các hoạt động liên quan đến call path.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CallPathController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Settings.ICallPathService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Systems.CallPathController"/>.
            </summary>
            <param name="callPathService">Dịch vụ xử lý call path.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CallPathController.GetAll(System.String,System.String)">
            <summary>
            Lấy danh sách call path theo version/build. Nếu không truyền, lấy danh sách từ phiên bản mặc định.
            </summary>
            <param name="version">Số phiên bản (optional, ví dụ: 1.0.0)</param>
            <param name="build">Số build (optional, ví dụ: 101)</param>
            <returns>Danh sách call path.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CallPathController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các call path dựa trên các tham số được cung cấp.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CallPathController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CallPathModel)">
            <summary>
            Tạo hoặc cập nhật thông tin call path.
            </summary>
            <param name="callPathModel">Model chứa thông tin call path.</param>
            <returns>Kết quả của hoạt động tạo hoặc cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CallPathController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của một call path dựa trên ID.
            </summary>
            <param name="id">ID của call path.</param>
            <returns>Thông tin chi tiết của call path.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CallPathController.CopyToVersion(Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CopyCallPathRequest)">
            <summary>
            Copy tất cả CallPath từ một version sang một version khác.
            </summary>
            <param name="request">Thông tin version nguồn và version đích.</param>
            <returns>Kết quả của hoạt động copy.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.CallPathVersionController">
            <summary>
            Controller để quản lý các phiên bản đường dẫn (CallPathVersion).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CallPathVersionController.GetAll">
            <summary>
            Lấy tất cả phiên bản (dùng cho dropdown).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CallPathVersionController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm phiên bản theo các tham số.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CallPathVersionController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CallPathVersionModel)">
            <summary>
            Tạo hoặc cập nhật phiên bản.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CallPathVersionController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết phiên bản theo ID.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.CallPathVersionController.Delete(System.Int32)">
            <summary>
            Xóa phiên bản theo ID.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.DocController">
            <summary>
            Controller đọc và duyệt tài liệu API từ thư mục Docs/
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.DocController.GetApiDocs">
            <summary>
            Lấy danh sách tài liệu API trong thư mục Docs
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.DocController.GetDocDetail(System.String)">
            <summary>
            Lấy nội dung chi tiết của một tài liệu API
            </summary>
            <param name="path">Đường dẫn tương đối của file</param>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.EndPointsController">
            <summary>
            Controller để xử lý các hoạt động liên quan tới điểm đầu cuối.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.EndPointsController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Categories.IEndPointsService)">
            <summary>
            Khởi tạo môt instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Systems.EndPointsController"/>.
            </summary>
            <param name="endPointsService">Dịch vụ xử lý điểm đầu cuối.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.EndPointsController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các điểm đầu cuối dựa trên các tham số tìm kiếm.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.EndPointsController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.EndPointsModel)">
            <summary>
            Tạo hoặc cập nhật thông tin điểm đầu cuối.
            </summary>
            <param name="endPointsModel">Model chứa thông tin điểm đầu cuối.</param>
            <returns>Kết quả của hoạt động tạo hoặc cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.EndPointsController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của một điểm đầu cuối dựa trên ID.
            </summary>
            <param name="id">ID của điểm đầu cuối.</param>
            <returns>Thông tin chi tiết của điểm đầu cuối.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.EndPointsController.Delete(System.Int32)">
            <summary>
            Xóa một điểm đầu cuối dựa trên ID.
            </summary>
            <param name="id">ID của điểm đầu cuối.</param>
            <returns>Kết quả của hoạt động xóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.EndPointsController.AutoGenerate">
            <summary>
            Tạo các điểm đầu cuối tự động.
            </summary>
            <returns>Kết quả của hoạt động tạo.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.ErrorReportController.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportModel)">
            <summary>
            Tạo mới báo lỗi (yêu cầu đăng nhập)
            </summary>
            <param name="model">Thông tin báo lỗi</param>
            <returns>Kết quả tạo báo lỗi</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.ErrorReportController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm báo lỗi (dành cho admin)
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Danh sách báo lỗi</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.ErrorReportController.SearchMine(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm báo lỗi do chính người đang đăng nhập gửi.
            Cố ý KHÔNG đòi role: ai gửi được góp ý thì phải theo dõi được góp ý của mình.
            Phạm vi dữ liệu bị chặn ở service bằng UserId lấy từ token, không nhận từ tham số.
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Danh sách báo lỗi của chính người dùng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.ErrorReportController.GetMineById(System.Int32)">
            <summary>
            Lấy chi tiết một báo lỗi do chính người đang đăng nhập gửi.
            </summary>
            <param name="id">ID báo lỗi</param>
            <returns>Chi tiết báo lỗi</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.ErrorReportController.GetById(System.Int32)">
            <summary>
            Lấy chi tiết báo lỗi (dành cho admin)
            </summary>
            <param name="id">ID báo lỗi</param>
            <returns>Chi tiết báo lỗi</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.ErrorReportController.UpdateStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportUpdateModel)">
            <summary>
            Cập nhật trạng thái báo lỗi (dành cho admin)
            </summary>
            <param name="model">Thông tin cập nhật</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.ErrorReportController.Delete(System.Int32)">
            <summary>
            Xóa báo lỗi (dành cho admin)
            </summary>
            <param name="id">ID báo lỗi</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.ErrorReportController.GetByStatus(Lada.Framework.Data.Enums.ErrorReportStatus,System.Int32,System.Int32)">
            <summary>
            Lấy danh sách báo lỗi theo trạng thái (dành cho admin)
            </summary>
            <param name="status">Trạng thái</param>
            <param name="pageIndex">Trang hiện tại</param>
            <param name="pageSize">Kích thước trang</param>
            <returns>Danh sách báo lỗi</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.ErrorReportController.GetNewReports(System.Int32,System.Int32)">
            <summary>
            Lấy danh sách báo lỗi mới (dành cho admin)
            </summary>
            <param name="pageIndex">Trang hiện tại</param>
            <param name="pageSize">Kích thước trang</param>
            <returns>Danh sách báo lỗi mới</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.ErrorReportController.GetInProgressReports(System.Int32,System.Int32)">
            <summary>
            Lấy danh sách báo lỗi đang xử lý (dành cho admin)
            </summary>
            <param name="pageIndex">Trang hiện tại</param>
            <param name="pageSize">Kích thước trang</param>
            <returns>Danh sách báo lỗi đang xử lý</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.ErrorReportController.MarkAsInProgress(System.Int32)">
            <summary>
            Đánh dấu báo lỗi là đang xử lý
            </summary>
            <param name="id">ID báo lỗi</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.ErrorReportController.MarkAsResolved(System.Int32,System.String)">
            <summary>
            Đánh dấu báo lỗi là đã xử lý
            </summary>
            <param name="id">ID báo lỗi</param>
            <param name="adminNote">Ghi chú từ admin</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.ErrorReportController.Close(System.Int32,System.String)">
            <summary>
            Đóng báo lỗi
            </summary>
            <param name="id">ID báo lỗi</param>
            <param name="adminNote">Ghi chú từ admin</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.GoogleMapController">
            <summary>
            Controller để xử lý các hoạt động liên quan tới Google Maps.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.GoogleMapController.#ctor(Lada.Framework.Infrastructures.Services.IGoogleMapService,Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Systems.GoogleMapController"/>.
            </summary>
            <param name="googleMapService">Dịch vụ xử lý Google Maps.</param>
            <param name="locationService">Dịch vụ xử lý địa điểm.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.GoogleMapController.GetLatLngJob">
            <summary>
            Kích hoạt công việc lấy tọa độ (lat, long) của phường/xã.
            </summary>
            <returns>Thông báo kết quả kích hoạt công việc.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.GoogleMapController.GetDistanceJob">
            <summary>
            Kích hoạt công việc lấy khoảng cách của EndPoints.
            </summary>
            <returns>Thông báo kết quả kích hoạt công việc.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.HangfireJobController">
            <summary>
            API xem và thao tác tác vụ nền Hangfire từ SPA quản trị — chỉ Founder,
            cùng mức với CacheController vì đây là công cụ vận hành hệ thống.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.HangfireJobController.GetOverview">
            <summary>
            Số liệu tổng quan: đếm theo trạng thái, server đang chạy, queue.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.HangfireJobController.GetRecurring">
            <summary>
            Danh sách tác vụ định kỳ đã đăng ký.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.HangfireJobController.TriggerRecurring(System.String)">
            <summary>
            Chạy ngay một tác vụ định kỳ, không đợi tới lịch.
            </summary>
            <param name="id">Id tác vụ định kỳ, ví dụ notification-cleanup.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.HangfireJobController.PauseRecurring(System.String)">
            <summary>
            Tạm dừng tác vụ định kỳ trong danh mục: gỡ khỏi lịch, không tự đăng ký lại khi API khởi động.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.HangfireJobController.RegisterRecurring(System.String)">
            <summary>
            Đăng ký (lại) tác vụ định kỳ trong danh mục với lịch mặc định.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.HangfireJobController.RemoveRecurring(System.String)">
            <summary>
            Xoá hẳn tác vụ định kỳ KHÔNG nằm trong danh mục khỏi lịch Hangfire.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.HangfireJobController.GetJobs(System.String,System.Int32,System.Int32)">
            <summary>
            Liệt kê job theo trạng thái (Processing / Scheduled / Enqueued / Succeeded / Failed / Deleted).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.HangfireJobController.GetJobDetail(System.String)">
            <summary>
            Chi tiết một job kèm lịch sử chuyển trạng thái.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.HangfireJobController.Requeue(System.String)">
            <summary>
            Đưa job (thường là job thất bại) trở lại hàng đợi để chạy lại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.HangfireJobController.Delete(System.String)">
            <summary>
            Xoá một job khỏi hàng đợi.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.LocationController">
            <summary>
            Controller để xử lý các hoạt động liên quan tới địa điểm.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.LocationController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService,Lada.Framework.Infrastructures.Services.IGoogleMapService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Systems.LocationController"/>.
            </summary>
            <param name="locationService">Dịch vụ xử lý địa điểm.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.LocationController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các địa điểm dựa trên các tham số được cung cấp.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.LocationController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.LocationModel)">
            <summary>
            Tạo hoặc cập nhật thông tin địa điểm.
            </summary>
            <param name="locationModel">Model chứa thông tin địa điểm.</param>
            <returns>Kết quả của hoạt động tạo hoặc cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.LocationController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của một địa điểm dựa trên ID.
            </summary>
            <param name="id">ID của địa điểm.</param>
            <returns>Thông tin chi tiết của địa điểm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.LocationController.GetFullAddressByWard(System.Int32)">
            <summary>
            Lấy địa chỉ đầy đủ của một phường/xã dựa trên ID.
            </summary>
            <param name="id">ID của phường/xã.</param>
            <returns>Địa chỉ đầy đủ của phường/xã.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.LocationController.Delete(System.Int32)">
            <summary>
            Xóa một địa điểm dựa trên ID.
            </summary>
            <param name="id">ID của địa điểm.</param>
            <returns>Kết quả của hoạt động xóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.LocationController.LocationSuggestion(System.String,Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.SuggestionType,System.Int32,System.Nullable{Lada.Framework.Data.Domains.Categories.LocationLevelType})">
            <summary>
            Gọi API tìm kiếm địa điểm dựa trên từ khóa, loại và ID cha.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="type">Loại địa điểm.</param>
            <param name="parentId">ID cha.</param>
            <returns>Danh sách địa điểm phù hợp.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.LocationController.AddressAutocomplete(System.String)">
            <summary>
            Tìm kiếm địa chỉ hoàn thành dựa trên từ khóa.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <returns>Danh sách địa chỉ phù hợp.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.LocationController.PlaceDetail(System.String)">
            <summary>
            Lấy chi tiết địa điểm dựa trên ID địa điểm.
            </summary>
            <param name="placeId">ID của địa điểm.</param>
            <returns>Chi tiết địa điểm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.LocationController.UpdateCombinedName">
            <summary>
            Kích hoạt công việc cập nhật tên kết hợp (CombinedName).
            </summary>
            <returns>Thông báo kết quả kích hoạt công việc.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.LocationController.ImportFromAntin">
            <summary>
            Import dữ liệu Location ĐVHC mới từ database Antin.
            Import Tỉnh/TP và Phường/Xã 2 cấp, cập nhật MappedWardId cho Location 3 cấp.
            </summary>
            <returns>Kết quả import</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.LocationController.ImportFromExcel(Microsoft.AspNetCore.Http.IFormFile)">
            <summary>
            Import dữ liệu Location 2 cấp từ file Excel.
            File Excel cần có 3 cột: Tỉnh/TP (Mã) | Tên Xã mới | Mã Xã mới
            </summary>
            <param name="file">File Excel upload</param>
            <returns>Kết quả import</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.LocationController.BatchUpdateLatLong(System.Collections.Generic.List{System.Int32})">
            <summary>
            Cập nhật tọa độ lat/long hàng loạt cho các location chưa có tọa độ.
            Sử dụng Google Geocoding API để tự động xác định tọa độ.
            </summary>
            <param name="ids">Danh sách ID location cần cập nhật</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.LocationMappingConfigController">
            <summary>
            Cấu hình chiến lược mapping địa chỉ → LocationId (dùng cho app khách).
            Đọc/ghi một key duy nhất <c>Location.MappingStrategy</c> trong bảng AppConfig.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Controllers.Systems.LocationMappingConfigController.StrategyKey">
            <summary>Key cấu hình trong bảng AppConfig (khớp với Lada.AppBackEnd).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.LocationMappingConfigController.Get">
            <summary>
            Lấy cấu hình chiến lược mapping hiện tại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.LocationMappingConfigController.Save(Ladaer.BackEnd.Controllers.Systems.LocationMappingConfigModel)">
            <summary>
            Lưu cấu hình chiến lược mapping.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.LocationMappingConfigModel">
            <summary>
            DTO cấu hình chiến lược mapping địa chỉ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Systems.LocationMappingConfigModel.Order">
            <summary>Thứ tự chạy các option (1=nearest ward, 2=name-match, 3=Google).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Controllers.Systems.LocationMappingConfigModel.Enabled">
            <summary>Cờ bật/tắt từng option (key = số option).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.MapWardListController">
            <summary>
            Trang Bản đồ tô phường/xã (/ban-do-phuong-xa): danh sách phường/xã tô màu, dùng chung giữa mọi người.
            Đọc đòi <c>MapWardList.View</c>, ghi đòi <c>MapWardList.Manage</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MapWardListController.GetNavPermissions">
            <summary>
            Cờ hiển thị nút của trang cho người đang đăng nhập. Cố ý không đòi role nào: người không có quyền
            vẫn phải hỏi được và nhận toàn <c>false</c> (rule quyen-hien-thi).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MapWardListController.GetLists">
            <summary>Tất cả danh sách tô</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MapWardListController.GetById(System.Int32)">
            <summary>Một danh sách tô kèm phường/xã</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MapWardListController.GetProvinces">
            <summary>Tỉnh/thành bộ 2 cấp kèm số phường/xã — bước chọn tỉnh đầu trang</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MapWardListController.GetWards(System.Int32)">
            <summary>Toàn bộ phường/xã bộ 2 cấp của một tỉnh — 404 khi Id không phải tỉnh bộ 2 cấp</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MapWardListController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Categories.MapWardListModel)">
            <summary>Tạo / sửa danh sách tô — LocationIds thay toàn bộ phường/xã của danh sách</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MapWardListController.Delete(System.Int32)">
            <summary>Xoá mềm danh sách tô</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.MenuController">
            <summary>
            Controller xử lý các hoạt động liên quan đến menu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MenuController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Categories.IMenuService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Systems.MenuController"/>.
            </summary>
            <param name="menuService">Dịch vụ xử lý menu.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MenuController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm các menu dựa trên các tham số được cung cấp.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MenuController.GetMenuList(Lada.Framework.Data.Domains.Categories.AppType)">
            <summary>
            Lấy danh sách menu cho ứng dụng và vai trò.
            </summary>
            <param name="appType">Loại ứng dụng.</param>
            <returns>Danh sách menu.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MenuController.GetAdminTree">
            <summary>
            Lấy cây menu cho quản trị viên.
            </summary>
            <returns>Cây menu.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MenuController.GetTree(Lada.Framework.Data.Domains.Categories.AppType,System.String)">
            <summary>
            Lấy cây menu dựa trên loại ứng dụng và từ khóa tìm kiếm.
            </summary>
            <param name="app">Loại ứng dụng.</param>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <returns>Cây menu.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MenuController.Lock(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.MenuStatusModel)">
            <summary>
            Khóa một menu.
            </summary>
            <param name="model">Model chứa thông tin menu cần khóa.</param>
            <returns>Kết quả của hoạt động khóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MenuController.UnLock(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.MenuStatusModel)">
            <summary>
            Mở khóa một menu.
            </summary>
            <param name="model">Model chứa thông tin menu cần mở khóa.</param>
            <returns>Kết quả của hoạt động mở khóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MenuController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.MenuModel)">
            <summary>
            Tạo hoặc cập nhật thông tin menu.
            </summary>
            <param name="menuModel">Model chứa thông tin menu.</param>
            <returns>Kết quả của hoạt động tạo hoặc cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MenuController.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết của một menu dựa trên ID.
            </summary>
            <param name="id">ID của menu.</param>
            <returns>Thông tin chi tiết của menu.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MenuController.Delete(System.Int32)">
            <summary>
            Xóa một menu dựa trên ID.
            </summary>
            <param name="id">ID của menu.</param>
            <returns>Kết quả của hoạt động xóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MenuController.GetAppList">
            <summary>
            Lấy danh sách các ứng dụng.
            </summary>
            <returns>Danh sách các ứng dụng.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.MobileAppConfigController">
            <summary>
            Cấu hình màn hình chặn truy cập bằng điện thoại của app khách hàng (Lada.App):
            link tải app, ảnh QR và nội dung thông báo. Lưu ở các khoá <c>MobileApp.*</c> trong AppConfig.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MobileAppConfigController.Get">
            <summary>
            Lấy cấu hình hiện tại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.MobileAppConfigController.Save(Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.MobileAppGateModel)">
            <summary>
            Lưu cấu hình.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.NotificationAdminController">
            <summary>
            Controller quản trị thông báo (Admin).
            Quản lý categories, gửi broadcast, xem lịch sử.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationAdminController.GetCategories">
            <summary>
            Lấy danh sách loại thông báo
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationAdminController.SearchCategories(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm loại thông báo (phân trang, lọc) cho SmartTable
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationAdminController.CreateCategory(Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.NotificationCategoryModel)">
            <summary>
            Tạo loại thông báo mới
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationAdminController.UpdateCategory(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.NotificationCategoryModel)">
            <summary>
            Cập nhật loại thông báo
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationAdminController.DeleteCategory(System.Int32)">
            <summary>
            Xóa (mềm) loại thông báo.
            Không xóa cứng vì Notification.CategoryId là FK non-null tham chiếu category.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationAdminController.SendNotification(Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.SendNotificationModel)">
            <summary>
            Gửi thông báo (Admin manual send)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationAdminController.GetHistory(System.Int32,System.Int32,System.String)">
            <summary>
            Xem lịch sử thông báo đã gửi
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.NotificationController">
            <summary>
            Controller quản lý thông báo cho người dùng.
            Xem, đánh dấu đã đọc, xóa, cấu hình preferences.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationController.GetNotifications(Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.NotificationFilter)">
            <summary>
            Lấy danh sách thông báo của user hiện tại (phân trang)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationController.GetUnreadCount">
            <summary>
            Lấy số thông báo chưa đọc
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationController.MarkAsRead(System.Guid)">
            <summary>
            Đánh dấu 1 thông báo đã đọc
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationController.MarkAllRead">
            <summary>
            Đánh dấu tất cả thông báo đã đọc
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationController.Delete(System.Guid)">
            <summary>
            Xóa (archive) 1 thông báo
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationController.GetPreferences">
            <summary>
            Lấy cấu hình thông báo của user
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationController.UpdatePreferences(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.UpdatePreferenceModel})">
            <summary>
            Cập nhật cấu hình thông báo
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationController.RegisterDeviceToken(Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.RegisterDeviceTokenModel)">
            <summary>
            Đăng ký device token cho push notification
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.NotificationController.RemoveDeviceToken(System.Int32)">
            <summary>
            Xóa device token
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Systems.WarehouseController">
            <summary>
            Controller xử lý các yêu cầu liên quan đến kho hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.WarehouseController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService,Ladaer.BackEnd.Infrastructures.Services.Business.IWarehouseService)">
            <summary>
            Khởi tạo một thể hiện mới của lớp <see cref="T:Ladaer.BackEnd.Controllers.Systems.WarehouseController"/>.
            </summary>
            <param name="userService">Dịch vụ người dùng.</param>
            <param name="warehouseService">Dịch vụ kho hàng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.WarehouseController.Inbound(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Warehouses.InboundModel)">
            <summary>
            Xử lý yêu cầu nhập kho cho một đơn hàng.
            </summary>
            <param name="model">Mô hình chứa thông tin đơn hàng.</param>
            <returns>Kết quả của quá trình nhập kho.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.WarehouseController.SearchDrivers(System.String,System.Int32,System.Int32)">
            <summary>
            Tìm kiếm danh sách tài xế theo từ khóa và phân trang.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm tài xế.</param>
            <param name="pageNumber">Số trang cho phân trang.</param>
            <param name="pageSize">Kích thước trang cho phân trang.</param>
            <returns>Danh sách các tài xế phù hợp với từ khóa tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Systems.WarehouseController.GetInboundOrdersByDriversAsync(System.Int32,System.Int32,System.Int32)">
            <summary>
            Lấy danh sách đơn hàng cần inbound của một tài xế.
            </summary>
            <param name="userId">Id của tài xế.</param>
            <param name="pageNumber">Số trang.</param>
            <param name="pageSize">Số bản ghi / trang.</param>
            <returns>Danh sách các đơn hàng cần inbound.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.CourseController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Training.ICourseService,Ladaer.BackEnd.Infrastructures.Services.Training.ISectionService,Ladaer.BackEnd.Infrastructures.Services.Training.ILessonService)">
            <summary>
            Khởi tạo CourseController.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.CourseController.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm khóa học.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.CourseController.GetAll">
            <summary>
            Lấy tất cả khóa học đang hoạt động (cho Learner View).
            Kết quả được filter theo Permission của user hiện tại.
            Founder thấy tất cả.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.CourseController.GetById(System.Int32)">
            <summary>
            Lấy chi tiết khóa học.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.CourseController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Training.CourseModel)">
            <summary>
            Tạo hoặc cập nhật khóa học.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.CourseController.Delete(System.Int32)">
            <summary>
            Xóa khóa học.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.CourseController.GetCurriculum(System.Int32)">
            <summary>
            Lấy toàn bộ curriculum (sections + standalone lessons) theo GlobalOrder.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.CourseController.SaveCurriculumOrder(System.Int32,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Training.CurriculumOrderRequest})">
            <summary>
            Lưu thứ tự curriculum sau khi kéo thả.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.CourseController.GetCoursePermissions(System.Int32)">
            <summary>
            Lấy danh sách PermissionIds được gán cho khóa học.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.CourseController.UpdateCoursePermissions(Ladaer.BackEnd.Controllers.Training.UpdateCoursePermissionsRequest)">
            <summary>
            Cập nhật danh sách Permission cho khóa học.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Controllers.Training.UpdateCoursePermissionsRequest">
            <summary>
            Request model cho cập nhật Permission của khóa học.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.LessonController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Training.ILessonService,Ladaer.BackEnd.Infrastructures.Services.Training.IMediaStorageService)">
            <summary>
            Khởi tạo LessonController.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.LessonController.GetBySectionId(System.Int32)">
            <summary>Lấy danh sách bài giảng của section.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.LessonController.GetByCourseId(System.Int32)">
            <summary>Lấy tất cả bài giảng của khóa học (theo GlobalOrder).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.LessonController.GetStandaloneByCourseId(System.Int32)">
            <summary>Lấy bài giảng độc lập (không thuộc chương nào) của khóa học.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.LessonController.GetById(System.Int32)">
            <summary>Lấy chi tiết bài giảng (admin).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.LessonController.GetDetail(System.Int32)">
            <summary>Lấy chi tiết bài giảng kèm media (learner view).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.LessonController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Training.LessonModel)">
            <summary>
            Tạo hoặc cập nhật bài giảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.LessonController.Delete(System.Int32)">
            <summary>
            Xóa bài giảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.LessonController.Reorder(System.Int32,System.Collections.Generic.List{System.Int32})">
            <summary>
            Sắp xếp lại thứ tự bài giảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.LessonController.ReorderGlobal(System.Int32,System.Collections.Generic.List{System.Int32})">
            <summary>
            Sắp xếp lại thứ tự toàn bộ bài giảng (GlobalOrder) trong khóa học.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.LessonController.UploadMedia(System.Int32,Microsoft.AspNetCore.Http.IFormFile,System.String,System.Int32)">
            <summary>
            Upload media cho bài giảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.LessonController.GetMedia(System.Int32)">
            <summary>
            Lấy danh sách media của bài giảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.LessonController.DeleteMedia(System.Int32)">
            <summary>
            Xóa media.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.LessonController.ReorderMedia(System.Int32,System.Collections.Generic.List{System.Int32})">
            <summary>
            Sắp xếp lại thứ tự media.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.SectionController.#ctor(Ladaer.BackEnd.Infrastructures.Services.Training.ISectionService)">
            <summary>
            Khởi tạo SectionController.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.SectionController.GetByCourseId(System.Int32)">
            <summary>
            Lấy danh sách sections của khóa học.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.SectionController.GetById(System.Int32)">
            <summary>
            Lấy chi tiết section.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.SectionController.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Training.SectionModel)">
            <summary>
            Tạo hoặc cập nhật section.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.SectionController.Delete(System.Int32)">
            <summary>
            Xóa section.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Controllers.Training.SectionController.Reorder(System.Int32,System.Collections.Generic.List{System.Int32})">
            <summary>
            Sắp xếp lại thứ tự sections.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings">
            <summary>
            Section <c>Analytics</c> trong appsettings — MCP tra cứu số liệu vận hành (docs/plan-mcp-tra-cuu-so-lieu.md §1, §3.1).
            Endpoint <c>/analytics</c> dùng chung host, issuer OAuth, trang đăng nhập/đồng ý và DCR với MCP kho nội dung
            (<see cref="T:Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreMcpSettings"/>); khác PRM, chỉ dẫn server, bộ tool và role.
            </summary>
            <remarks>
            <para>
            <b>Fail-fast có điều kiện</b> (quyết định kỹ thuật GĐ A, plan §7): Production + <see cref="P:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.Enabled"/> = true mà thiếu
            <c>ConnectionStrings:AnalyticsConnection</c> hoặc <see cref="P:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.CodeHashKey"/> → dừng khởi động. Production mà công tắc
            còn TẮT thì chỉ cảnh báo: không tool nào chạy, không job nào nạp, không mã nào được băm — dừng cả API vì một tính năng
            đang tắt chỉ biến một lần deploy vá lỗi khác thành sự cố. Bật công tắc cần khởi động lại, nên lúc đó fail-fast vẫn bắt.
            </para>
            <para>
            Môi trường khác thiếu khoá thì dùng giá trị tạm + cảnh báo (như khoá OpenIddict) để máy dev không vỡ.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.Enabled">
            <summary>Công tắc tổng. TẮT (mặc định): tool trả UNAVAILABLE, job nạp đêm không chạy.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.CodeHashKey">
            <summary>Khoá HMAC của mã băm KH-/NV-/LX-/XE- — base64 của ≥ 32 byte (<c>openssl rand -base64 32</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.Path">
            <summary>
            Đường dẫn endpoint MCP số liệu trên API — nơi DUY NHẤT khai chuỗi này (gate, rate limit, PRM, resource OAuth đều
            đọc từ đây qua <c>McpSurfaceRegistry</c>). Phải là đường dẫn ngang hàng với <c>/mcp</c>, không lồng dưới nó.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.McpPath">
            <summary>Đường dẫn đã chuẩn hoá: một dấu / đầu, không dấu / cuối.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.ReadConnectionString">
            <summary>Connection string đọc schema analytics: AnalyticsConnection, hoặc LadaConnection khi dev thiếu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.MainConnectionString">
            <summary>Connection string chính (ghi AnalyticsCallLog, job nạp đọc dbo).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.UsesFallbackConnection">
            <summary>true khi đang đọc bằng LadaConnection (không có login chỉ đọc) — chỉ chấp nhận ở dev.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.CodeHashKeyBytes">
            <summary>Khoá HMAC đã giải mã.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.UsesTemporaryHashKey">
            <summary>true khi dùng khoá tạm sinh lúc khởi động — mã băm đổi sau mỗi lần khởi động lại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.StartupWarnings">
            <summary>Cảnh báo lúc đăng ký service — log khi pipeline dựng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.Load(Microsoft.Extensions.Configuration.IConfiguration,Microsoft.Extensions.Hosting.IHostEnvironment)">
            <summary>Đọc section, giải khoá, chọn connection và áp luật fail-fast.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.Resolve(System.String,System.String,System.Boolean)">
            <summary>Tách khỏi <see cref="M:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.Load(Microsoft.Extensions.Configuration.IConfiguration,Microsoft.Extensions.Hosting.IHostEnvironment)"/> để test luật fail-fast không cần IConfiguration thật.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreMcpSettings">
            <summary>
            Section <c>ContentStore</c> trong appsettings — cấu hình mức triển khai của MCP + OAuth (GĐ C).
            Những thứ đổi được lúc vận hành (công tắc, whitelist IP, ngưỡng rate limit, allowlist redirect)
            nằm ở AppConfig trong DB, không ở đây.
            </summary>
            <remarks>
            <c>McpPublicUrl</c> phải ở appsettings chứ không phải AppConfig vì OpenIddict cần issuer lúc khởi động
            (trước khi có DB) và PRM <c>resource</c> phải bằng đúng URL người dùng nhập vào connector (plan §7.3).
            Dev thử qua tunnel thì đổi giá trị này trong appsettings.json cục bộ (gitignore) rồi khởi động lại.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreMcpSettings.McpPublicUrl">
            <summary>URL MCP công khai — mặc định theo quyết định §7.3: https://mcp.ladaexpress.com/mcp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreMcpSettings.StartupWarnings">
            <summary>Cảnh báo phát hiện lúc đăng ký service (khoá tạm…) — log khi pipeline dựng, vì lúc đăng ký chưa có ILogger.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreMcpSettings.McpPublicUri">
            <summary>URI MCP đã chuẩn hoá (tuyệt đối, không dấu / cuối).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreMcpSettings.McpResource">
            <summary>Chuỗi resource đúng nguyên văn để so với URL người dùng nhập (bỏ dấu / cuối).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreMcpSettings.Issuer">
            <summary>Issuer OAuth = origin của URL MCP (https://mcp.ladaexpress.com).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreMcpSettings.McpPath">
            <summary>Đường dẫn endpoint MCP trên API (thường "/mcp").</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreOAuthSettings">
            <summary>Khoá và tuỳ chọn của authorization server OpenIddict.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreOAuthSettings.SigningKeyPem">
            <summary>
            Khoá RSA riêng (PEM, PKCS#8 hoặc PKCS#1) để ký access token. OpenIddict bắt buộc khoá ký bất đối xứng.
            Thiếu → dùng khoá tạm sinh lúc khởi động (token mất hiệu lực khi khởi động lại) và log cảnh báo.
            Tạo: <c>openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreOAuthSettings.EncryptionKey">
            <summary>
            Khoá đối xứng (base64, ≥ 32 byte) mã hoá access token / mã uỷ quyền / refresh token.
            Thiếu → khoá tạm + cảnh báo. Tạo: <c>openssl rand -base64 32</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreOAuthSettings.AllowInsecureHttp">
            <summary>Cho phép endpoint OAuth chạy qua HTTP thường — CHỈ dev/loopback. Production phải false.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreOAuthSettings.AccessTokenMinutes">
            <summary>Thời hạn access token (phút). Mặc định 60.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreOAuthSettings.RefreshTokenDays">
            <summary>Thời hạn refresh token (ngày). Mặc định 14.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.AppSettings.RateLimitingSettings">
            <summary>
            Ngưỡng rate limit đọc từ mục <c>RateLimiting</c> của appsettings. Thiếu mục nào thì dùng mặc định ở đây.
            </summary>
            <remarks>
            <para>
            <b>Vì sao tách theo user và theo IP (2026-10-16):</b> bản cũ chỉ có một ngưỡng toàn cục 100 request/phút/IP.
            Cả văn phòng đi ra Internet bằng <b>một</b> IP công cộng (NAT), nên vài chục nhân viên dùng SPA cùng lúc
            chia nhau đúng 100 request đó — mỗi lần mở trang SPA đã bắn 10–30 lời gọi, cộng thêm header thăm dò chat
            và hiện diện mỗi 60 giây trên mọi tab — và cứ vài phút lại có người nhận 429 "Quá nhiều yêu cầu" như bị khoá.
            Nay request <b>đã đăng nhập</b> tính hạn mức theo <b>từng user</b> (<see cref="P:Ladaer.BackEnd.Infrastructures.AppSettings.RateLimitingSettings.GlobalPerUserPerMinute"/>),
            chỉ request <b>chưa đăng nhập</b> mới tính theo IP (<see cref="P:Ladaer.BackEnd.Infrastructures.AppSettings.RateLimitingSettings.GlobalPerIpPerMinute"/>).
            </para>
            <para>
            <b>Login theo IP vẫn giữ</b> vì lúc đó chưa biết user là ai, nhưng nới từ 5 lên <see cref="P:Ladaer.BackEnd.Infrastructures.AppSettings.RateLimitingSettings.LoginPerIpPerMinute"/>:
            token SPA sống 16 ngày nên cả văn phòng thường hết hạn cùng một đợt và đăng nhập lại dồn vào vài phút.
            Chống dò mật khẩu <i>một</i> tài khoản vẫn do Identity lockout lo (5 lần sai → khoá 5 phút, theo tài khoản,
            không phụ thuộc IP); ngưỡng IP ở đây chỉ chặn rải mật khẩu qua nhiều tài khoản.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.AppSettings.RateLimitingSettings.SectionName">
            <summary>Tên mục cấu hình trong appsettings.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.RateLimitingSettings.GlobalPerUserPerMinute">
            <summary>
            Giới hạn toàn cục cho request <b>đã đăng nhập</b>: số request / phút / <b>user</b> (mọi IP cộng lại).
            Mặc định 600 — một người dùng thật không giữ 10 request/giây suốt một phút; vượt ngưỡng này gần như
            chắc chắn là tab lặp vô hạn hoặc script.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.RateLimitingSettings.GlobalPerIpPerMinute">
            <summary>
            Giới hạn toàn cục cho request <b>chưa đăng nhập</b> (hoặc token hỏng/hết hạn): số request / phút / IP.
            Mặc định 100 — giữ nguyên ngưỡng cũ vì lưu lượng chưa đăng nhập từ một IP vốn rất ít (đăng nhập, báo lỗi).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.RateLimitingSettings.LoginPerIpPerMinute">
            <summary>
            Endpoint đăng nhập (SPA, app lái xe, trang đăng nhập OAuth): số request / phút / IP. Mặc định 30.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.AppSettings.RateLimitingSettings.AnonymousPerIpPerMinute">
            <summary>
            Policy <c>anonymous</c> cho endpoint công khai ít dùng (báo lỗi, đăng ký client MCP, callback OAuth kênh chat):
            số request / phút / IP. Mặc định 10.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Authorization.HangfireAuthorizationFilter">
            <summary>
            Chỉ cho phép truy cập Hangfire Dashboard khi đã đăng nhập
            và có role Founder hoặc Admin.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Authorization.ServerRoleAuthorizationHandler">
            <summary>
            Custom Authorization Handler: xác thực role từ DB thay vì JWT token.
            Gộp luôn logic Founder bypass.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Caching.CacheKeys">
            <summary>
            Constants cho cache keys. Dùng prefix để nhóm và hỗ trợ invalidation theo nhóm.
            Format: "Group:SubKey" — ví dụ "UserRoles:123"
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Caching.CacheKeys.UserRoles">
            <summary>Danh sách roles của user. Format: UserRoles:{userId}</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Caching.CacheKeys.AppConfig">
            <summary>Giá trị cấu hình hệ thống. Format: AppConfig:{key}</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Caching.CacheKeys.TTL.UserRoles">
            <summary>Roles: 15 phút — cân bằng giữa giảm tải DB và đảm bảo quyền cập nhật kịp thời</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Caching.CacheKeys.TTL.AppConfig">
            <summary>AppConfig: 1 giờ — cấu hình hệ thống, invalidate khi thay đổi</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Caching.CacheSettings">
            <summary>
            Cấu hình cache provider. Đọc từ appsettings section "CacheSettings".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Caching.CacheSettings.Provider">
            <summary>
            Provider: "Memory" (default) hoặc "Redis"
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Caching.CacheSettings.RedisConnectionString">
            <summary>
            Connection string cho Redis (chỉ cần khi Provider = "Redis").
            Ví dụ: "localhost:6379" hoặc "redis-server:6379,password=xxx,ssl=true"
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Caching.CacheSettings.RedisInstanceName">
            <summary>
            Prefix cho tất cả Redis keys, giúp phân biệt giữa các ứng dụng dùng chung Redis.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Caching.ICacheService">
            <summary>
            Abstraction layer cho cache operations.
            Cho phép swap implementation (MemoryCache → Redis) mà không ảnh hưởng business logic.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Caching.ICacheService.Get``1(System.String)">
            <summary>Lấy giá trị từ cache, trả về default nếu không tìm thấy</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Caching.ICacheService.GetOrCreateAsync``1(System.String,System.Func{System.Threading.Tasks.Task{``0}},System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},Microsoft.Extensions.Caching.Memory.CacheItemPriority)">
            <summary>Lấy từ cache hoặc tạo mới nếu chưa có (cache-aside pattern)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Caching.ICacheService.Set``1(System.String,``0,System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},Microsoft.Extensions.Caching.Memory.CacheItemPriority)">
            <summary>Đặt giá trị vào cache</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Caching.ICacheService.Remove(System.String)">
            <summary>Xóa một cache entry theo key</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Caching.ICacheService.RemoveByPrefix(System.String)">
            <summary>Xóa tất cả cache entries có key bắt đầu bằng prefix</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Caching.ICacheService.GetRawValue(System.String)">
            <summary>Lấy giá trị raw (object) từ cache theo key, dùng cho admin inspection</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Caching.ICacheService.GetAllKeys">
            <summary>Lấy tất cả cache keys đang được track</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Caching.ICacheService.Clear">
            <summary>Xóa toàn bộ cache</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Caching.MemoryCacheService">
            <summary>
            Implementation dùng IMemoryCache, wrap thêm key tracking để hỗ trợ RemoveByPrefix.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Caching.RedisCacheService">
            <summary>
            Redis implementation của ICacheService.
            Dùng StackExchange.Redis, serialize/deserialize qua System.Text.Json.
            Hỗ trợ key tracking bằng SCAN (không dùng KEYS * để tránh block).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DbContextFactory.LadaDbContextFactory">
            <summary>
            Factory để tạo LadaDbContext cho design-time operations (migrations, scaffolding, etc.)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.AutoMapperConfig.Mapper">
            <summary>
            Mapper
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.AutoMapperConfig.MapperConfiguration">
            <summary>
            Mapper configuration
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.AutoMapperConfig.Init">
            <summary>
            Init
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Categories.MapWardListItem">
            <summary>
            Dòng danh sách tô ở panel trái trang Bản đồ tô phường/xã
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Categories.MapWardListModel">
            <summary>
            Danh sách tô kèm phường/xã. Lưu: gửi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Categories.MapWardListModel.LocationIds"/>; đọc: trả <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Categories.MapWardListModel.Wards"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Categories.MapWardListModel.LocationIds">
            <summary>
            Id phường/xã bộ 2 cấp — chỉ dùng khi lưu. Lưu là thay TOÀN BỘ danh sách phường bằng tập này.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Categories.MapWardListModel.Wards">
            <summary>
            Phường/xã trong danh sách — chỉ dùng khi đọc
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Categories.MapProvinceItem">
            <summary>
            Một tỉnh/thành bộ 2 cấp ở bước chọn tỉnh. <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Categories.MapProvinceItem.Code"/> (2 số) = <c>provinceCode</c> trong file ranh giới.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Categories.MapWardItem">
            <summary>
            Một phường/xã bộ 2 cấp. <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Categories.MapWardItem.Code"/> là mã hành chính 5 số — khoá ghép với ranh giới trên bản đồ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Categories.MapWardItem.Prefix">
            <summary>
            "Phường" / "Xã"; rỗng với đặc khu (chữ "Đặc khu" nằm sẵn trong Name)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Dashboards.DashboardLayoutItem">
            <summary>
            Toàn bộ bố cục dashboard của user: các zone theo thứ tự, mỗi zone chứa widget instance
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Dashboards.DashboardWidgetInstanceItem">
            <summary>
            Một widget đã nằm trên dashboard — Settings là JSON đã merge DefaultSettings + cài đặt riêng của user
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Dashboards.AddWidgetModel.ZoneId">
            <summary>Zone đích; null = zone đầu tiên (tự tạo "Tổng quan" nếu user chưa có zone nào)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Dashboards.UpdateWidgetSettingsModel.Id">
            <summary>Id của UserDashboardWidget</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Dashboards.UpdateWidgetSettingsModel.Settings">
            <summary>JSON settings — server chỉ giữ các khoá có UserEditable=true trong SettingsSchema</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Dashboards.AddWidgetResult.Id">
            <summary>Id của UserDashboardWidget vừa tạo</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Dashboards.WidgetDataResult">
            <summary>
            Kết quả data của một widget — Data đúng envelope theo Type (kpi/chart/list/...)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Dashboards.SaveLayoutModel">
            <summary>
            Lưu toàn bộ bố cục dashboard của user — zone/widget không có mặt trong model sẽ bị xoá mềm.
            Id = 0 nghĩa là zone/widget mới tạo.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Dashboards.WidgetAdminItem">
            <summary>
            Dòng danh sách catalog trên trang quản trị widget
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Dashboards.WidgetAdminModel">
            <summary>
            Form tạo/sửa widget catalog — Code chỉ đặt lúc tạo, sửa sẽ bị bỏ qua
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Dashboards.PermissionOptionItem">
            <summary>
            Nhóm quyền cho multi-select trên form admin
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Dashboards.WidgetLibraryItem">
            <summary>
            Một widget trong thư viện mà user hiện tại được dùng (server đã lọc theo nhóm quyền)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderAgencyScopeInfo">
            <summary>
            Trả lời của <c>GET api/Order/agency-scope</c>: người đang đăng nhập xem được màn "Đơn hàng bưu cục" không,
            của bưu cục nào, kèm option cho bộ lọc trạng thái.
            </summary>
            <remarks>
            Endpoint không đòi role (rule quyen-hien-thi) nên option trạng thái đi kèm ở đây — mượn
            <c>PrepareOrderListFilter</c> (role <c>Order.Search</c>) là để chủ bưu cục ăn 403 ngay khi mở trang.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderAgencyScopeInfo.CanView">
            <summary>Có role và đã gắn bưu cục — chỉ khi này màn mới nạp bảng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderAgencyScopeInfo.HasRole">
            <summary>Có role xem đơn bưu cục (hoặc Founder).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderAgencyScopeInfo.AgencyId">
            <summary>Bưu cục của người xem, 0 = chưa gắn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderAgencyScopeInfo.AgencyName">
            <summary>Tên bưu cục của người xem.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderAgencyScopeInfo.StatusOptions">
            <summary>Danh sách trạng thái đơn hàng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderAgencyScopeInfo.PhysicalStatusOptions">
            <summary>Danh sách trạng thái vật lý.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderListFilter">
            <summary>
            Dữ liệu bộ lọc danh sách đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderListFilter.StatusOptions">
            <summary>
            Danh sách trạng thái đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderListFilter.PhysicalStatusOptions">
            <summary>
            Danh sách trạng thái vật lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderListFilter.PayFeeTypeOptions">
            <summary>
            Danh sách phương thức thanh toán phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderListFilter.CustomerOptions">
            <summary>
            Danh sách khách hàng tương ứng filter (nếu truyền CustomerId)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsAccountItem">
            <summary>
            DTO trả về cho danh sách tài khoản quảng cáo đã đồng bộ từ nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsAccountItem.AdsConnectionId">
            <summary>Kết nối đã lấy tài khoản này về</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsAccountItem.AdsConnectionName">
            <summary>Tên kết nối để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsAccountItem.ExternalId">
            <summary>ID tài khoản bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsAccountItem.CurrencyCode">
            <summary>Mã tiền tệ của tài khoản — hiển thị chi phí theo mã này, không giả định VND</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsAccountItem.IsManager">
            <summary>Là tài khoản quản lý (MCC) — không tạo chiến dịch trực tiếp trên tài khoản này</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsAccountItem.IsTestAccount">
            <summary>Là tài khoản test của nền tảng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsAdItem">
            <summary>
            Một quảng cáo cụ thể trong nhóm quảng cáo.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsAdItem.ExternalId">
            <summary>Id quảng cáo bên nền tảng — null nghĩa là chưa đẩy lên</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsAdItem.AdType">
            <summary>Loại quảng cáo của nền tảng (Google AdType: RESPONSIVE_SEARCH_AD…)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsAdItem.ApprovalStatus">
            <summary>Trạng thái duyệt thô của nền tảng (APPROVED, DISAPPROVED…)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsAdItem.ApprovalStatusStr">
            <summary>
            Trạng thái duyệt bằng tiếng Việt, tính ở backend để mọi nơi hiển thị giống nhau.
            Giá trị nền tảng chưa biết thì giữ nguyên chuỗi gốc — không đoán thành "Đã duyệt".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsAdItem.AdsCreativeId">
            <summary>
            Mẫu quảng cáo trong LADA. <c>null</c> nghĩa là quảng cáo này được <b>đồng bộ về từ nền
            tảng</b> chứ không do LADA soạn — dữ liệu chỉ đọc, không phải lỗi thiếu dữ liệu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsAdItem.IsManagedByLada">
            <summary>Đúng khi quảng cáo do LADA soạn và đẩy lên (có mẫu quảng cáo)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsAdItem.Metrics">
            <summary>
            Số liệu gộp trong kỳ, <c>null</c> khi chưa đồng bộ số liệu cấp quảng cáo.
            Để null thay vì các số 0: "chưa có dữ liệu" khác hẳn "có dữ liệu và bằng 0".
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupDetailItem">
            <summary>
            Chi tiết một nhóm quảng cáo — dữ liệu đầu trang cho trang nhóm quảng cáo.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupDetailItem.IsManagerAccount">
            <summary>Tài khoản quản lý (MCC) — không chứa dữ liệu quảng cáo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupDetailItem.IsGroupPublished">
            <summary>Nhóm đã có mặt trên nền tảng chưa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupDetailItem.IsCampaignPublished">
            <summary>Chiến dịch đã có mặt trên nền tảng chưa</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignItem">
            <summary>
            DTO chiến dịch cho danh sách.
            Chi phí / ngân sách luôn đi kèm <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignItem.CurrencyCode"/> — không giả định VND khi hiển thị.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignItem.AdsAccountName">
            <summary>Tên tài khoản quảng cáo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignItem.ExternalId">
            <summary>ID bên nền tảng — null nghĩa là chưa đẩy lên</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignItem.OutOfSyncDetailJson">
            <summary>Chi tiết các trường đang lệch với nền tảng (khi SyncStatus = OutOfSync)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignItem.GroupCount">
            <summary>Số nhóm quảng cáo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignItem.Metrics">
            <summary>
            Số liệu gộp trong khoảng ngày đang lọc (<c>FromDate</c>/<c>ToDate</c> của
            <c>search</c>) — cột số liệu của bảng chiến dịch (plan cải tổ giao diện quảng cáo §3.6).
            <c>null</c> khi không truyền khoảng ngày, hoặc chiến dịch chưa có dòng số liệu nào trong
            khoảng đó — giao diện hiện "—", không hiện 0.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignMetricsItem">
            <summary>
            Số liệu gộp của một chiến dịch cho bảng danh sách. Cố ý là bản rút gọn của
            <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricSummaryItem"/>: không mang <c>Daily</c> (25 dòng × 30 ngày là 750 bản ghi
            thừa cho mỗi trang) và không mang các chỉ số bảng không hiện.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignMetricsItem.Ctr">
            <summary>Tỷ lệ nhấp (%) = Clicks / Impressions, tính từ tổng của khoảng ngày</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignMetricsItem.Cpc">
            <summary>Chi phí mỗi lần nhấp = Cost / Clicks</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignMetricsItem.Cpa">
            <summary>Chi phí mỗi chuyển đổi = Cost / Conversions; 0 khi chưa có chuyển đổi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignMetricsItem.CurrencyCode">
            <summary>Mã tiền tệ của dòng — mỗi dòng hiện theo mã riêng, không giả định cả trang cùng mã</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignMetricsItem.IsMixedCurrency">
            <summary>Một chiến dịch có số liệu ở nhiều mã tiền tệ (không nên xảy ra, nhưng phải nói thật nếu có)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignMetricsItem.FromSummary(Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricSummaryItem)">
            <summary>Rút gọn từ bản tổng hợp của <c>AdsMetricAggregator</c> — cùng một phép tính với thẻ KPI</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignDetailItem">
            <summary>
            Chi tiết chiến dịch: thông tin chiến dịch + nhóm + số liệu tổng hợp.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignDetailItem.Campaign">
            <summary>Thông tin chiến dịch</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignDetailItem.Groups">
            <summary>Danh sách nhóm quảng cáo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignDetailItem.Summary">
            <summary>Số liệu tổng hợp trong khoảng ngày đang xem (null nếu chưa có dữ liệu)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignDetailItem.CanFetchKeywords">
            <summary>
            Nền tảng đọc được từ khoá hay không. UI ẩn hẳn tab "Từ khoá" khi <c>false</c>:
            tab rỗng đọc thành "chưa cấu hình gì", trong khi thật ra nền tảng không có khái niệm
            từ khoá (VD Facebook / TikTok nhắm theo đối tượng, không theo từ khoá).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignDetailItem.CanEditKeywords">
            <summary>Sửa được từ khoá trên nền tảng hay không (thao tác tiêu tiền)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignDetailItem.SupportsNegativeKeywords">
            <summary>Nền tảng có khái niệm từ khoá phủ định</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignDetailItem.SupportsCampaignLevelNegativeKeywords">
            <summary>
            Có từ khoá phủ định <b>cấp chiến dịch</b> hay không. Tách khỏi
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignDetailItem.SupportsNegativeKeywords"/> vì đây chính là thứ quyết định tab trên trang
            chiến dịch — nền tảng chỉ có phủ định cấp nhóm thì tab này vô nghĩa.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsConnectionItem">
            <summary>
            DTO trả về cho danh sách và chi tiết kết nối nền tảng quảng cáo.
            Mọi thông tin mật đều đã được che (abcd***wxyz) — tuyệt đối không trả giá trị gốc ra API.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsConnectionItem.Name">
            <summary>Tên hiển thị của kết nối</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsConnectionItem.Platform">
            <summary>Nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsConnectionItem.PlatformStr">
            <summary>Tên nền tảng để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsConnectionItem.Status">
            <summary>Trạng thái kết nối</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsConnectionItem.StatusStr">
            <summary>Tên trạng thái để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsConnectionItem.ClientId">
            <summary>OAuth Client ID — không phải secret, trả nguyên</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsConnectionItem.MaskedClientSecret">
            <summary>Client Secret đã che</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsConnectionItem.MaskedDeveloperToken">
            <summary>Developer token đã che</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsConnectionItem.LoginCustomerId">
            <summary>ID tài khoản quản lý (MCC)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsConnectionItem.HasRefreshToken">
            <summary>Đã có refresh token hay chưa — UI dùng để biết có cần bấm "Cấp quyền" không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsConnectionItem.AccessTokenExpiresAt">
            <summary>Thời điểm access token hết hạn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsConnectionItem.AccountCount">
            <summary>Số tài khoản quảng cáo đã đồng bộ về</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeItem">
            <summary>
            Mẫu quảng cáo trả về cho danh sách và form.
            Headline / description trả về dạng mảng đã parse — frontend không phải tự đọc JSON.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeItem.Headlines">
            <summary>Danh sách tiêu đề</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeItem.Descriptions">
            <summary>Danh sách mô tả</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeItem.MarketingContentId">
            <summary>Nội dung AI Marketing đã dùng làm nguồn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeItem.PostId">
            <summary>Bài viết CMS đã dùng làm nguồn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeItem.UsageCount">
            <summary>Số quảng cáo đang dùng mẫu này — mẫu đã dùng thì không cho xoá</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeValidationItem">
            <summary>
            Kết quả kiểm tra mẫu quảng cáo theo giới hạn của nền tảng.
            Frontend dùng để hiện cảnh báo ngay trên form, không đợi Google trả lỗi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeValidationItem.IsValid">
            <summary>Mẫu đã đủ điều kiện đẩy lên nền tảng chưa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeValidationItem.Errors">
            <summary>Danh sách lỗi phải sửa mới publish được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeValidationItem.Warnings">
            <summary>Danh sách cảnh báo — vẫn publish được nhưng nên xem lại</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeSuggestionItem">
            <summary>
            Gợi ý mẫu quảng cáo sinh ra từ một nội dung nguồn (AI Marketing / bài CMS).
            Text vượt giới hạn ký tự được trả kèm bản rút gọn đề xuất —
            người dùng tự quyết, hệ thống không cắt cụt âm thầm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeSuggestionItem.Name">
            <summary>Tên mẫu gợi ý</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeSuggestionItem.Headlines">
            <summary>Các tiêu đề gợi ý</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeSuggestionItem.Descriptions">
            <summary>Các mô tả gợi ý</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeSuggestionItem.Limits">
            <summary>Giới hạn của nền tảng đích — form đếm ký tự theo object này</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeSuggestionItem.Notes">
            <summary>Ghi chú cho người dùng (tiếng Việt)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsTextSuggestion">
            <summary>
            Một đoạn text gợi ý kèm thông tin về giới hạn ký tự.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsTextSuggestion.OriginalText">
            <summary>Text gốc lấy từ nội dung nguồn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsTextSuggestion.SuggestedText">
            <summary>Bản đề xuất đã rút gọn cho vừa giới hạn (bằng text gốc nếu đã vừa)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsTextSuggestion.OriginalLength">
            <summary>Độ dài text gốc</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsTextSuggestion.MaxLength">
            <summary>Giới hạn ký tự của nền tảng cho loại text này</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsTextSuggestion.IsTruncated">
            <summary>Text gốc vượt giới hạn — người dùng cần xem lại bản rút gọn</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem">
            <summary>
            Nhóm quảng cáo trả về cho danh sách và chi tiết chiến dịch.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem.AdsCampaignName">
            <summary>
            Tên chiến dịch cha. Do service điền cho <b>trang hiện tại</b> (AutoMapper không map được),
            nên <c>null</c> ở các đường không điền. Trang "Nhóm quảng cáo" toàn tài khoản không có
            ngữ cảnh chiến dịch nào cả — không có cột này thì 149 dòng nhóm không biết thuộc về đâu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem.BiddingStrategy">
            <summary>
            Chiến lược đặt giá của chiến dịch cha — quyết định giá thầu nhóm có tác dụng hay không
            (plan §3.5). Điền cùng lúc với <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem.AdsCampaignName"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem.AdsAccountName">
            <summary>Tên tài khoản quảng cáo. Điền cùng lúc với <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem.AdsCampaignName"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem.ExternalId">
            <summary>Id nhóm bên nền tảng — null nghĩa là chưa đẩy lên</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem.CpcBid">
            <summary>Giá thầu CPC tối đa theo đơn vị tiền tệ của tài khoản</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem.GroupType">
            <summary>Loại nhóm của nền tảng (Google AdGroupType)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem.AdCount">
            <summary>
            Số quảng cáo trong nhóm. Do service đếm và gán, AutoMapper không map được
            (entity không có sẵn số này) nên mặc định 0 khi gọi qua đường không đếm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem.KeywordCount">
            <summary>Số từ khoá nhắm mục tiêu trong nhóm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem.NegativeKeywordCount">
            <summary>Số từ khoá phủ định của riêng nhóm (không tính phủ định cấp chiến dịch)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem">
            <summary>
            Một <b>loại</b> việc cần xử lý đã gộp — một dòng của panel "Việc cần xử lý" (plan §3.4).
            <para>
            Phân loại và đặt tiêu đề làm ở backend: giao diện chỉ hiện <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem.Title"/> và đổi nút theo
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem.Action"/>, không parse JSON lệch. <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem.Count"/> đã <b>trừ</b> các mục bị bỏ qua
            còn hạn; <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem.DismissedCount"/> là phần bị ẩn, để hiện "đã bỏ qua N · Hiện lại".
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem.EntityType">
            <summary>Loại bản ghi của mọi mục trong nhóm — cần khi gọi bỏ qua</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem.ActionStr">
            <summary>Nhãn nút hành động chính</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem.Title">
            <summary>Tiêu đề dòng, đã kèm số đếm — ví dụ "80 chiến dịch có khung giờ chạy trên Google mà LADA chưa nhập"</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem.Hint">
            <summary>Một câu nói hành động chính làm gì / có tốn quota không, để người bấm không phải đoán</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem.Count">
            <summary>Số mục đang hiện (sau khi trừ bỏ qua)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem.DismissedCount">
            <summary>Số mục đang bị bỏ qua còn hạn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem.EntityIds">
            <summary>
            Id của mọi mục đang hiện (tối đa 500) — giao diện dùng cho hành động hàng loạt và bỏ qua cả
            nhóm mà không cần tải đủ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem.Items"/>. Vượt trần thì <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem.EntityIdsTruncated"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem.Items">
            <summary>Chi tiết từng mục, tối đa 200 — quá thì giao diện mở bộ lọc bảng thay vì cuộn</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueEntryItem">
            <summary>Một mục trong nhóm — gắn với đúng một bản ghi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueEntryItem.EntityId">
            <summary>Id bản ghi dạng chuỗi (Guid chiến dịch, int tài khoản / kết nối, mã cố định mức hệ thống)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueEntryItem.Detail">
            <summary>Tóm tắt nội dung việc, đủ để quyết mà không cần mở chi tiết</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueEntryItem.Since">
            <summary>Việc có từ lúc nào (lần đánh dấu / đồng bộ gần nhất)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueEntryItem.ParentId">
            <summary>Id bản ghi cha khi hành động cần tới nó — tài khoản chậm đồng bộ mang Id kết nối</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordItem">
            <summary>
            Một từ khoá (thường hoặc phủ định) trả về cho danh sách và chi tiết.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordItem.AdsGroupId">
            <summary>Nhóm chứa từ khoá — null với từ khoá phủ định cấp chiến dịch</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordItem.ExternalId">
            <summary>Id criterion bên nền tảng — null nghĩa là chưa đẩy lên</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordItem.KindStr">
            <summary>"Phủ định" hoặc "Nhắm mục tiêu" — tính ở backend để mọi nơi hiển thị giống nhau</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordItem.DisplayText">
            <summary>
            Nội dung kèm ký hiệu kiểu khớp theo đúng cách Google Ads hiển thị:
            <c>[chính xác]</c>, <c>"cụm từ"</c>, còn khớp rộng thì để trần.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordItem.CpcBid">
            <summary>Giá thầu CPC riêng — null nghĩa là dùng giá thầu của nhóm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordItem.CpcBidStr">
            <summary>"theo nhóm" khi không đặt giá thầu riêng, để bảng không có ô trống mơ hồ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordItem.ApprovalStatus">
            <summary>Trạng thái duyệt thô của nền tảng (APPROVED, DISAPPROVED…)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordItem.QualityScore">
            <summary>Điểm chất lượng 1–10; null nghĩa là nền tảng chưa đủ dữ liệu để tính</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordItem.Metrics">
            <summary>
            Số liệu gộp trong kỳ, <c>null</c> khi chưa đồng bộ số liệu cho từ khoá này.
            Cố ý để null thay vì trả về các số 0: "chưa có dữ liệu" khác hẳn "có dữ liệu và bằng 0".
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordContextResult">
            <summary>
            Bối cảnh của một phạm vi từ khoá (một chiến dịch hoặc một nhóm) — <b>không kèm danh sách</b>.
            <para>
            Đây là thứ UI cần để quyết định hiện/ẩn nút và hiện cảnh báo: năng lực nền tảng, trạng thái
            publish, có thay đổi chưa đẩy hay không, và số lượng từng loại. Tách khỏi danh sách vì
            danh sách phải phân trang (một nhóm có thể tới hàng nghìn từ khoá) trong khi mấy con số này
            tính bằng một câu đếm gộp, không cần đọc dòng nào về bộ nhớ.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordContextResult.AdsGroupId">
            <summary>Nhóm đang xem — null khi đang xem ở cấp chiến dịch</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordContextResult.IsCampaignPublished">
            <summary>Chiến dịch đã có mặt trên nền tảng chưa — chưa thì không đẩy được từ khoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordContextResult.IsGroupPublished">
            <summary>Nhóm đã có mặt trên nền tảng chưa (chỉ có nghĩa khi xem ở cấp nhóm)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordContextResult.IsManagerAccount">
            <summary>Tài khoản quản lý (MCC) không chứa từ khoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordContextResult.SupportsValidateOnly">
            <summary>Nền tảng có dry-run hay không — không có thì nút "Xem trước" phải ẩn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordContextResult.MaxKeywordsPerGroup">
            <summary>Giới hạn số từ khoá mỗi nhóm của nền tảng; 0 = không rõ giới hạn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordContextResult.HasPendingChanges">
            <summary>Có dòng nào chưa khớp nền tảng (nháp hoặc đã sửa trong LADA)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordContextResult.SharedSetNote">
            <summary>
            Ghi chú cố định về danh sách phủ định dùng chung (shared set) mà LADA không đọc.
            Phải hiện lên UI: người dùng không được tưởng danh sách ở đây là đầy đủ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordContextResult.KeywordCount">
            <summary>Số từ khoá nhắm mục tiêu trong phạm vi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordContextResult.NegativeKeywordCount">
            <summary>
            Số từ khoá phủ định <b>của chính phạm vi đang xem</b>: phủ định cấp chiến dịch khi xem
            theo chiến dịch, phủ định của riêng nhóm khi xem theo nhóm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordContextResult.GroupLevelNegativeKeywordCount">
            <summary>
            Số từ khoá phủ định thuộc <b>các nhóm bên trong</b>, chỉ có nghĩa khi xem ở cấp chiến
            dịch. Đếm riêng vì phạm vi ảnh hưởng khác hẳn: phủ định cấp chiến dịch áp cho mọi nhóm,
            phủ định của nhóm thì không — gộp một số sẽ khiến người dùng hiểu sai sức ảnh hưởng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordViewResult">
            <summary>
            Bối cảnh kèm <b>toàn bộ</b> danh sách từ khoá của một phạm vi.
            <para>
            Chỉ dùng cho luồng đẩy lên nền tảng (<c>apply</c>), nơi bắt buộc phải có đủ mọi dòng để
            tính diff. Màn hình danh sách <b>không</b> dùng cái này — nó gọi <c>search</c> phân trang
            cộng với <c>context</c>, vì một nhóm có thể có hàng nghìn từ khoá.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordViewResult.Keywords">
            <summary>Từ khoá thường (nhắm mục tiêu) — luôn cấp nhóm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsKeywordViewResult.NegativeKeywords">
            <summary>Từ khoá phủ định trong phạm vi đang xem</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricDailyItem">
            <summary>
            Một dòng số liệu theo ngày.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricDailyItem.EntityId">
            <summary>Id bản ghi canonical tương ứng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricDailyItem.CurrencyCode">
            <summary>Mã tiền tệ của chi phí — hiển thị theo mã này, không quy đổi</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricSummaryItem">
            <summary>
            Số liệu tổng hợp trong một khoảng ngày.
            CTR / CPC / CPA được tính lại từ tổng, không lấy trung bình của trung bình
            (trung bình của CTR từng ngày cho ra số sai khi lượng hiển thị các ngày lệch nhau).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricSummaryItem.Ctr">
            <summary>Tỷ lệ nhấp (%) = Clicks / Impressions</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricSummaryItem.Cpc">
            <summary>Chi phí mỗi lần nhấp = Cost / Clicks</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricSummaryItem.Cpa">
            <summary>Chi phí mỗi chuyển đổi = Cost / Conversions</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricSummaryItem.Roas">
            <summary>Tỷ lệ doanh thu trên chi phí = ConversionValue / Cost</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricSummaryItem.IsMixedCurrency">
            <summary>
            Đúng khi số liệu được gộp từ nhiều tài khoản dùng mã tiền tệ khác nhau.
            Lúc đó <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricSummaryItem.Cost"/> là tổng của các đơn vị tiền khác nhau nên KHÔNG có nghĩa
            về mặt tiền tệ — UI phải cảnh báo thay vì hiển thị như một số tiền bình thường.
            Hệ thống cố tình không quy đổi vì không có nguồn tỷ giá đáng tin tại thời điểm chi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricSummaryItem.Daily">
            <summary>Số liệu từng ngày để vẽ biểu đồ</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricOverviewItem">
            <summary>
            Số liệu tổng quan toàn hệ thống kèm kỳ trước để so sánh.
            Kỳ trước dài đúng bằng kỳ hiện tại và nằm liền sát phía trước, nên hai kỳ so được với nhau.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricOverviewItem.Current">
            <summary>Số liệu kỳ đang xem. Null khi kỳ này chưa có dữ liệu nào.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricOverviewItem.Previous">
            <summary>Số liệu kỳ liền trước. Null khi kỳ trước chưa có dữ liệu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricOverviewItem.AccountCount">
            <summary>Số tài khoản quảng cáo có phát sinh số liệu trong kỳ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricOverviewItem.CampaignCount">
            <summary>Số chiến dịch có phát sinh số liệu trong kỳ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricOverviewItem.LastSyncedAt">
            <summary>Lần đồng bộ số liệu gần nhất — để người dùng biết số đang xem mới hay cũ</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricStatusItem">
            <summary>
            Số liệu quảng cáo đã về tới đâu — mốc cho thanh ngữ cảnh của phân hệ (plan cải tổ giao diện
            quảng cáo §3.1-M1). Không phụ thuộc khoảng ngày đang xem: người dùng chọn "Tháng này" khi số
            liệu dừng từ tháng trước vẫn phải thấy "số liệu đến 18/08".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricStatusItem.LatestDate">
            <summary>Ngày mới nhất có dòng số liệu cấp chiến dịch. Null = chưa đồng bộ số liệu lần nào.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricStatusItem.LastSyncedAt">
            <summary>Lần đồng bộ số liệu gần nhất (theo dòng số liệu, không theo log)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricTimeSeriesItem">
            <summary>
            Một mốc thời gian trong chuỗi số liệu (ngày / tuần / tháng).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricTimeSeriesItem.Date">
            <summary>Ngày đầu của mốc — dùng để sắp thứ tự</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricTimeSeriesItem.Label">
            <summary>Nhãn hiển thị trên trục hoành (VD "05/08", "Tuần 32", "08/2026")</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricTimeSeriesItem.Ctr">
            <summary>Tỷ lệ nhấp (%) tính lại từ tổng của mốc</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricTimeSeriesItem.Cpc">
            <summary>Chi phí mỗi lần nhấp tính lại từ tổng của mốc</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricPlatformItem">
            <summary>
            Số liệu gộp theo một nền tảng quảng cáo.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricPlatformItem.IsMixedCurrency">
            <summary>Đúng khi nền tảng này có nhiều tài khoản khác mã tiền tệ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsMetricPlatformItem.CostShare">
            <summary>Tỷ trọng chi phí trên tổng toàn kỳ (%) — để vẽ donut không phải tự tính ở frontend</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsTopCampaignItem">
            <summary>
            Một dòng trong bảng xếp hạng chiến dịch theo số liệu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsTopCampaignItem.CampaignId">
            <summary>Id canonical của chiến dịch — dùng để link sang trang chi tiết</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsTopCampaignItem.Status">
            <summary>Trạng thái chiến dịch tại thời điểm xem (không phải trạng thái trong kỳ)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem">
            <summary>
            Thông tin hiển thị trong hộp thoại xác nhận trước khi đẩy chiến dịch lên nền tảng.
            Mục đích là bắt người dùng đọc đúng những con số sẽ làm phát sinh chi phí —
            không phải hộp thoại "Bạn có chắc không?" chung chung.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem.AdsAccountName">
            <summary>Tên tài khoản quảng cáo sẽ bị trừ tiền</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem.ExternalAccountId">
            <summary>ID tài khoản bên nền tảng — để người dùng đối chiếu với Google Ads</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem.IsTestAccount">
            <summary>Tài khoản test của nền tảng thì không tiêu tiền thật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem.DailyBudget">
            <summary>Ngân sách/ngày theo đơn vị tiền tệ của tài khoản</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem.CurrencyCode">
            <summary>Mã tiền tệ của tài khoản — không quy đổi sang VND</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem.RunningDays">
            <summary>Số ngày chạy dự kiến; null nghĩa là chạy vô thời hạn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem.EstimatedMaxCost">
            <summary>
            Ước tính chi phí tối đa = ngân sách/ngày × số ngày chạy.
            Null khi chưa có ngày kết thúc — chạy vô thời hạn thì không có trần chi phí.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem.GroupCount">
            <summary>Số nhóm quảng cáo sẽ được tạo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem.AdCount">
            <summary>Số quảng cáo sẽ được tạo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem.KeywordCount">
            <summary>Số từ khoá sẽ được tạo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem.CreatedStatusStr">
            <summary>Trạng thái chiến dịch sau khi tạo (luôn là Tạm dừng)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem.Errors">
            <summary>Lỗi phải sửa mới đẩy lên được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem.Warnings">
            <summary>Cảnh báo — vẫn đẩy lên được nhưng nên xem lại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem.CanPublish">
            <summary>Đủ điều kiện đẩy lên nền tảng chưa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsPublishPreviewItem.SupportsValidateOnly">
            <summary>Nền tảng có hỗ trợ kiểm tra trước khi đẩy (dry-run) không</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsScheduleItem">
            <summary>
            Một khung giờ chạy quảng cáo trả về cho UI.
            <para>
            Các chuỗi hiển thị (<see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsScheduleItem.DayOfWeekStr"/>, <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsScheduleItem.TimeRangeStr"/>,
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsScheduleItem.BidModifierPercentStr"/>) được tính ở backend để mọi nơi hiển thị giống nhau —
            frontend không phải tự suy ra, nhất là phần đổi hệ số sang phần trăm (chỗ rất dễ nhầm).
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsScheduleItem.ExternalId">
            <summary>Id criterion bên nền tảng — null nghĩa là chưa đẩy lên</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsScheduleItem.DayOfWeekStr">
            <summary>Thứ trong tuần bằng tiếng Việt (Thứ Hai … Chủ Nhật)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsScheduleItem.TimeRangeStr">
            <summary>Khoảng giờ đã format sẵn, ví dụ "08:00 – 17:00"</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsScheduleItem.BidModifier">
            <summary>
            Hệ số điều chỉnh giá thầu theo đúng dạng của Google (1.2 = +20%).
            null = không điều chỉnh.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsScheduleItem.BidModifierPercentStr">
            <summary>
            Hệ số giá thầu đã đổi sang phần trăm để hiển thị:
            "+20%", "-50%", "—" khi null, "-100%" khi hệ số = 0.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsSyncLogItem">
            <summary>
            Một dòng log gọi nền tảng quảng cáo — màn hình debug chính của module.
            Nội dung request/response đã được scrub credential ở tầng service trước khi lưu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsSyncLogItem.PlatformErrorCode">
            <summary>Mã lỗi gốc của nền tảng — giữ nguyên để tra tài liệu Google</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.AiProviderItem">
            <summary>
            DTO trả về cho danh sách và chi tiết của AI Provider.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.MarketingContentItem">
            <summary>
            DTO trả về cho danh sách và chi tiết nội dung marketing AI.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.MarketingContentItem.Title">
            <summary>Tiêu đề nội dung</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.MarketingContentItem.ContentType">
            <summary>Loại nội dung: blog, social_post</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.MarketingContentItem.Brief">
            <summary>Brief gốc từ user</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.MarketingContentItem.Status">
            <summary>Trạng thái workflow (enum)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.MarketingContentItem.StatusStr">
            <summary>Trạng thái dưới dạng chuỗi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.MarketingContentItem.PublishPlatform">
            <summary>Platform đăng: facebook, zalo, instagram</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.MarketingContentItem.Content">
            <summary>Nội dung đầy đủ (HTML hoặc plain text)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.MarketingContentItem.MetaDescription">
            <summary>Mô tả SEO (chỉ có ở blog)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.MarketingContentItem.ImageUrl">
            <summary>URL ảnh AI tạo (nếu có)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.MarketingContentItem.ReviewNote">
            <summary>Ghi chú khi duyệt / từ chối</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.MarketingContentItem.ReviewedAt">
            <summary>Thời gian duyệt</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.MarketingContentItem.PublishedAt">
            <summary>Thời gian publish</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.MarketingContentItem.CreatedTime">
            <summary>Thời gian tạo</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.AI.PromptTemplateItem">
            <summary>
            DTO trả về cho danh sách và chi tiết của Prompt Template.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.AppConfig.AppConfigItem">
            <summary>
            Item cho AppConfig list/search
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AppConfig.AppConfigItem.Key">
            <summary>
            Key của AppConfig
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AppConfig.AppConfigItem.Value">
            <summary>
            Value của AppConfig
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.AppConfig.AppConfigItem.Description">
            <summary>
            Description của AppConfig
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.AddressCoordItem">
            <summary>
            Toạ độ của một địa chỉ đơn hàng, trả về sau khi geocode.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.AddressCoordItem.Id">
            <summary>
            Id của OrderAddress
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.AddressCoordItem.Lat">
            <summary>
            Vĩ độ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.AddressCoordItem.Long">
            <summary>
            Kinh độ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.AddressCoordItem.CoordSource">
            <summary>
            Nguồn toạ độ: 0 = chưa có, 1 = chính xác, 2 = gần đúng (tâm đơn vị hành chính)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployTypeConfig">
            <summary>
            Cấu hình cho từng loại triển khai (Strategy Pattern)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployTypeConfig.ValidStatuses">
            <summary>
            Các trạng thái đơn hàng hợp lệ cho loại triển khai
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployTypeConfig.ValidPhysicalStatuses">
            <summary>
            Các trạng thái vật lý hợp lệ cho loại triển khai
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployTypeConfig.DisplayAddressType">
            <summary>
            Loại địa chỉ hiển thị trên location tree
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployTypeConfig.TargetPhysicalStatus">
            <summary>
            Trạng thái vật lý sau khi gán nhân viên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployTypeConfig.TrackAction">
            <summary>
            Loại hành động ghi lịch sử
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployTypeConfig.TrackMessageTemplate">
            <summary>
            Template lời nhắn track: "{updater} {message} {user}"
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployTypeConfig.FilterByCurrentAgency">
            <summary>
            Nếu true, filter đơn hàng theo ops.AgencyId (đơn đang ở kho nào)
            Nếu false, filter theo ExpectAgencyPickupId hoặc ward.AgencyId
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployTypeConfig.ExcludeSameAgencyDelivery">
            <summary>
            Nếu true, loại trừ đơn có ExpectAgencyDeliveryId = currentAgencyId
            Dùng cho Transit: chỉ lấy đơn chuyển sang bưu cục khác
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployTypeConfig.RequiredDirection">
            <summary>
            Filter theo OrderDirection nếu có giá trị
            Dùng cho Return (ToReturn) và Delivery (ToDelivery)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployTypeConfig.RequireMatchingReturnAgency">
            <summary>
            Nếu true, chỉ lấy đơn có ExpectAgencyReturnId = currentAgencyId
            Dùng cho Return: chỉ trả về đơn thuộc bưu cục hoàn dự kiến
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployTypeConfig.RequireMatchingDeliveryAgency">
            <summary>
            Nếu true, chỉ lấy đơn có ExpectAgencyDeliveryId = currentAgencyId
            Dùng cho Delivery: chỉ lấy đơn thuộc bưu cục phát dự kiến
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployConfigFactory">
            <summary>
            Factory cung cấp cấu hình cho từng loại triển khai
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployConfigFactory.Get(Lada.Framework.Data.Enums.DeployType)">
            <summary>
            Lấy cấu hình theo loại triển khai
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployLocationItem">
            <summary>
            Dữ liệu về vị trí và số lượng đơn triển khai
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployMonitorItem.UserId">
            <summary>
            Id của lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployMonitorItem.UserName">
            <summary>
            Tên đăng nhập của lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployMonitorItem.FullName">
            <summary>
            Họ và tên của lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployMonitorItem.PhoneNumber">
            <summary>
            SĐT của lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployMonitorItem.AssignedPickup">
            <summary>
            Số lượng đơn hàng đã gán pickup
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployMonitorItem.PickingUp">
            <summary>
            Số lượng đơn hàng đang lấy
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployMonitorItem.PickedUp">
            <summary>
            Số lượng đơn hàng đã lấy
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployMonitorItem.AssignedDelivery">
            <summary>
            Số lượng đơn hàng đã gán giao
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployMonitorItem.Delivering">
            <summary>
            Số lượng đơn hàng đang giao
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.DeployMonitorItem.Delivered">
            <summary>
            Số lượng đơn hàng đã giao
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Deploy.ReturnAgencyOptionItem">
            <summary>
            Một lựa chọn "Bên phát hoàn" ở hộp Trả về (Ví v2 plan §3.8.1) — chỉ chi nhánh LADA đang hoạt động;
            bưu cục đã lấy hàng là lựa chọn mặc định (không nằm trong danh sách).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Operations.OpsOrderItem.Code">
            <summary>
            Mã vận đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Operations.OpsOrderItem.Note">
            <summary>
            Ghi chú đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Operations.OpsOrderItem.SaleId">
            <summary>
            Đơn hàng của sale nào
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Operations.OpsOrderItem.RouteName">
            <summary>
            Tuyến
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Operations.OpsOrderItem.Medias">
            <summary>
            Toàn bộ ảnh đã chụp cho đơn (lấy / giao / trả / kho), bất kể ai chụp. Điền ở
            <c>DriverAppOrderService.GetById</c> và <c>SearchActiveOrders</c> (thẻ đơn hiện ảnh để lái xe
            phân biệt hàng); các danh sách khác để rỗng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Operations.OpsOrderItem.RequiresCollectedAmount">
            <summary>
            App lái xe phải hiện ô "Số tiền đã thu" và gửi <c>CollectedAmount</c> khi lấy đơn này (lái xe bưu cục nhượng quyền bật ví, đơn
            Ví ghi GỬI-TRẢ). Máy chủ quyết bằng <c>OrderPaymentRules.DecidePickupCollect</c>; chỉ điền cho đơn đang đi lấy ở
            <c>DriverAppOrderService</c>, các danh sách khác để mặc định.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Operations.OpsOrderItem.SuggestedCollectedAmount">
            <summary>Số điền sẵn trong ô (số đã ghi trên đơn → cước thu người gửi → cước tạm tính).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Operations.OpsOrderItem.MaxCollectedAmount">
            <summary>Số tối đa máy chủ nhận (150 % cước tạm tính).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Operations.OpsOrderItem.PickupCollectNote">
            <summary>Câu hiện dưới số tiền: gợi ý / tối đa, hoặc vì sao không thu cước khi lấy; null = không hiện.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem">
            <summary>
            Đối tượng đại diện cho một mục đơn hàng nhập kho.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.Id">
            <summary>
            Mã đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.Code">
            <summary>
            Mã code của đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.Note">
            <summary>
            Ghi chú của đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.Status">
            <summary>
            Trạng thái của đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.StatusStr">
            <summary>
            Tên trạng thái
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.PhysicalStatus">
            <summary>
            Trạng thái vật lý của đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.PhysicalStatusStr">
            <summary>
            Tên trạng thái vật lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.StatusContent">
            <summary>
            Nội dung trạng thái của đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.OrderDirection">
            <summary>
            Hướng của đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.PicId">
            <summary>
            ID của người phụ trách.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.PicUserName">
            <summary>
            Tên người phụ trách.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.PickupNote">
            <summary>
            Ghi chú khi lấy hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.DeliveryNote">
            <summary>
            Ghi chú khi giao hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.ChargeWeight">
            <summary>
            Trọng lượng tính phí.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.DeclaredWeightGram">
            <summary>
            Σ cân kiện (gram, Σ <c>OrderPackage.SubTotalWeight</c>) — cân máy chủ dùng chốt cước khi không có cân bàn. Hộp nhập kho hiện
            làm "Cân khai" (V-49: <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.ChargeWeight"/> = 0 ở 100 % đơn nên dòng cân khai từng trống).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.CollectAmount">
            <summary>
            Số tiền thu hộ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.CodIncludeFee">
            <summary>
            Phí bao gồm COD.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.PayFeeType">
            <summary>
            Loại phí thanh toán.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.Fee">
            <summary>
            Phí.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.Discount">
            <summary>
            Giảm giá.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.CodFee">
            <summary>
            Phí COD.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.TotalFee">
            <summary>
            Tổng phí.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.SourceFee">
            <summary>
            Phí nguồn.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.DestFee">
            <summary>
            Phí đích.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.ReturnFee">
            <summary>
            Phí trả lại.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.InsuranceFee">
            <summary>
            Phí bảo hiểm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.SaleId">
            <summary>
            Đơn hàng của sale nào
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.MediaFiles">
            <summary>
            Danh sách tệp phương tiện.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.InboundOrderItem.OrderPackages">
            <summary>
            Danh sách sản phẩm
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.MediaItem">
            <summary>
            Đối tượng đại diện cho một mục phương tiện trong kho.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.MediaItem.OrderId">
            <summary>
            Id đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.MediaItem.Path">
            <summary>
            Đường dẫn hệ thống của mục phương tiện.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.MediaItem.AltText">
            <summary>
            Văn bản thay thế cho mục phương tiện.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.MediaItem.Caption">
            <summary>
            Chú thích cho mục phương tiện.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.OrderAddressItem">
            <summary>
            Lớp đại diện cho thông tin địa chỉ trong đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.OrderAddressItem.OrderId">
            <summary>
            ID của đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.OrderAddressItem.Name">
            <summary>
            Tên của người nhận.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.OrderAddressItem.PhoneNumber1">
            <summary>
            Số điện thoại 1 của người nhận.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.OrderAddressItem.Address1">
            <summary>
            Địa chỉ 1 của người nhận.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.OrderAddressItem.CityName">
            <summary>
            Tên thành phố.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.OrderAddressItem.DistrictName">
            <summary>
            Tên quận/huyện.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.OrderAddressItem.WardName">
            <summary>
            Tên phường/xã.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.OrderAddressItem.AddressType">
            <summary>
            Loại địa chỉ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.OrderAddressItem.AddressTypeStr">
            <summary>
            Loại địa chỉ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.OrderAddressItem.FullAddress">
            <summary>
            Địa chỉ đầy đủ
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.OrderPackageItem">
            <summary>
            Lớp đại diện cho thông tin gói hàng trong đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.OrderPackageItem.OrderId">
            <summary>
            ID của đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.OrderPackageItem.Name">
            <summary>
            Tên của gói hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Warehouse.OrderPackageItem.Quantity">
            <summary>
            Số lượng của gói hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.AgencyItem.Code">
            <summary>
            Mã đại lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.AgencyItem.Name">
            <summary>
            Tên chi nhánh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.AgencyItem.Description">
            <summary>
            Mô tả chi nhánh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.AgencyItem.ParentId">
            <summary>
            Đại lý cha
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.AgencyItem.RepresentativeId">
            <summary>
            Người đại diện pháp lý (người của đại lý)
            Nếu là phòng ban của LADA thì giá trị là 0
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.AgencyItem.ManagerName">
            <summary>
            Tên cán bộ quản lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.AgencyItem.CreatedTime">
            <summary>
            Ngày tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.AgencyItem.UpdatedTime">
            <summary>
            Ngày cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.AgencyItem.Status">
            <summary>
            Trạng thái Agency
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.AgencyTreeItem.Label">
            <summary>Tên hiển thị dạng cây: có tiền tố <c>|---</c> theo cấp — dùng cho dropdown phẳng cũ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.AgencyTreeItem.Name">
            <summary>Tên chi nhánh thuần (không tiền tố) — <c>AgencyTreeSelect</c> đọc trường này</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.AgencyTreeItem.ParentId">
            <summary>Chi nhánh cha (0 = gốc) — để client dựng lại cây từ danh sách phẳng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.EndPointsItem">
            <summary>
            Đối tượng đại diện cho điểm đầu và điểm cuối.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.EndPointsItem.StartId">
            <summary>
            Id của phường/xã gửi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.EndPointsItem.EndId">
            <summary>
            Id của phường/xã giao.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.EndPointsItem.Start">
            <summary>
            Tên phường/xã gửi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.EndPointsItem.StartDistrict">
            <summary>
            Tên quận/huyện gửi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.EndPointsItem.StartCity">
            <summary>
            Tên thành phố gửi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.EndPointsItem.End">
            <summary>
            Tên phường/xã giao.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.EndPointsItem.EndDistrict">
            <summary>
            Tên quận/huyện giao.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.EndPointsItem.EndCity">
            <summary>
            Tên thành phố giao.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.EndPointsItem.Distance">
            <summary>
            Khoảng cách đầu cuối (tính bằng mét).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.EndPointsItem.DistanceText">
            <summary>
            Văn bản hiển thị khoảng cách.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.EndPointsItem.LevelType">
            <summary>
            Loại cấp hành chính (2 cấp / 3 cấp).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationItem.ParentId">
            <summary>
            Danh mục cha
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationItem.Level">
            <summary>
            1: Tỉnh / thành phố, 2: Quận / huyện, 3: Phường / xã
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationItem.Type">
            <summary>
            Vùng phủ: Nội thành, ngoại thành, không cung cấp
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationItem.Surcharge">
            <summary>
            Phụ phí khu vực (VND). Hiện trên danh sách để soát được phường nào đã đặt phụ phí.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationItem.LevelType">
            <summary>
            Phân loại: 2 cấp (mới) hoặc 3 cấp (cũ)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationTreeItem">
            <summary>
            Item hiển thị location dưới dạng cây (hierarchical)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationTreeItem.Id">
            <summary>
            ID của location
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationTreeItem.Name">
            <summary>
            Tên location
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationTreeItem.FullName">
            <summary>
            Tên đầy đủ (bao gồm cả tên cha)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationTreeItem.Level">
            <summary>
            Cấp độ (1: Tỉnh/Thành phố, 2: Quận/Huyện, 3: Phường/Xã)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationTreeItem.ParentId">
            <summary>
            ID của location cha
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationTreeItem.Type">
            <summary>
            Loại vùng phủ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationTreeItem.Prefix">
            <summary>
            Tiền tố (Thành phố, Tỉnh, Quận, Huyện, Phường, Xã)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationTreeItem.DisplayOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationTreeItem.Children">
            <summary>
            Danh sách location con (Quận/Huyện hoặc Phường/Xã)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationTreeItem.HasChildren">
            <summary>
            Có location con hay không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationTreeItem.ChildrenCount">
            <summary>
            Số lượng location con (dựa trên Children đã load)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationTreeItem.AvailableChildrenCount">
            <summary>
            Số lượng location con có thể load (chưa được assign)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem">
            <summary>
            Đối tượng đại diện cho mục menu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.Label">
            <summary>
            Nhãn của mục menu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.Kind">
            <summary>
            Loại của mục menu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.Url">
            <summary>
            URL của mục menu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.IconClass">
            <summary>
            Lớp biểu tượng của mục menu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.ParentId">
            <summary>
            Id của mục menu cha.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.ParentName">
            <summary>
            Tên của mục menu cha.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.Status">
            <summary>
            Trạng thái của mục menu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.StatusStr">
            <summary>
            Chuỗi trạng thái của mục menu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.AllowRoles">
            <summary>
            Các vai trò được phép truy cập mục menu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.AppName">
            <summary>
            Tên ứng dụng của mục menu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.DisplayOrder">
            <summary>
            Thứ tự hiển thị của mục menu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.MenuLevel">
            <summary>
            Cấp độ của mục menu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.CreatedTime">
            <summary>
            Thời gian tạo mục menu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.UpdatedTime">
            <summary>
            Thời gian cập nhật mục menu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.CreatedBy">
            <summary>
            Người tạo mục menu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.MenuItem.UpdatedBy">
            <summary>
            Người cập nhật mục menu.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.SugLocationItem">
            <summary>
            Suggestion Location Item
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.BlockProfileItem">
            <summary>
            Bộ khối của một vật chủ — <c>GET api/Topic/BlockProfile</c> (topic theo tên hệ thống) và
            <c>GET api/Product/BlockProfile</c> (trang dịch vụ). Editor FE đọc từ đây, KHÔNG chép danh sách loại khối/icon
            (plan nhượng quyền website §3.3). <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.BlockProfileItem.Enabled"/> = false thì không hiện tab "Khối nội dung" và không gửi khối.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.BlockProfileItem.SystemName">
            <summary>Khoá vật chủ (<c>Product</c>, <c>FranchiseLanding</c>…); rỗng khi không có bộ khối.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.BlockProfileItem.Label">
            <summary>Tên đọc được của vật chủ, vd. "trang nhượng quyền".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.BlockProfileItem.CountRules">
            <summary>Luật số lượng lúc lưu (editor kiểm trước khi gửi).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.BlockProfileItem.PublishCountRules">
            <summary>
            Luật số lượng lúc xuất bản — có thể chặt hơn lúc lưu (trang nhượng quyền: đúng 1 khối Mở đầu). FE dùng để báo
            trước khi bấm Xuất bản; máy chủ vẫn kiểm lại.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.BlockProfileItem.Icons">
            <summary>Bộ icon cố định skin của vật chủ vẽ được. Payload lưu <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.BlockIconOptionItem.Value"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.BlockProfileItem.From(Lada.Framework.Data.Domains.Cms.BlockHostProfile)">
            <summary>Hồ sơ máy chủ → bản FE đọc; <paramref name="profile"/> null = vật chủ không có bộ khối.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.BlockTypeOptionItem.Value">
            <summary>Giá trị int của <c>ProductBlockType</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.BlockTypeOptionItem.Name">
            <summary>Tên enum (<c>Hero</c>, <c>LeadForm</c>…).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.BlockIconOptionItem.Value">
            <summary>Chuỗi ghi vào <c>items[].icon</c> của payload — dạng vật chủ này lưu (khoá hoặc class FA).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.BlockIconOptionItem.Svg">
            <summary>Thân SVG viewBox 0 0 24 24 — hằng trong code server, FE in xem trước được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.CategoryItem.ParentId">
            <summary>
            Danh mục cha
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.CategoryItem.IsFeatured">
            <summary>
            Là danh mục nổi bật hay không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.CategoryItem.ContentType">
            <summary>
            Loại danh mục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.CategoryItem.Icon">
            <summary>
            Mã icon Material (chỉ dùng cho ContentType = GoodsType)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.CategoryItem.ContentCategoryCode">
            <summary>
            Mã nhánh nội dung cấp 2 (A1, B3, F2...) của kho nội dung AI.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.GoodsCategoryConfigItem">
            <summary>
            Item hiển thị cấu hình tính giá của danh mục hàng hóa
            (dùng cho trang quản trị, form lên đơn và app khách)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.GoodsCategoryConfigItem.CategoryName">
            <summary>
            Tên danh mục hàng hóa
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.GoodsCategoryConfigItem.PricingModeName">
            <summary>
            Mô tả tiếng Việt của cách áp giá
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.GoodsCategoryConfigItem.AttributeCount">
            <summary>
            Số thuộc tính đang dùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.GoodsCategoryConfigItem.Attributes">
            <summary>
            Danh sách thuộc tính động kèm lựa chọn
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.GoodsCategoryAttributeItem">
            <summary>
            Item hiển thị thuộc tính động của danh mục hàng hóa
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.GoodsCategoryAttributeItem.AttributeTypeName">
            <summary>
            Mô tả tiếng Việt của kiểu thuộc tính
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.GoodsCategoryAttributeItem.IsPriceAxis">
            <summary>
            Thuộc tính này có phải trục cột của bảng giá riêng theo tuyến không
            </summary>
            <remarks>
            Trước GĐ 2 field này không có trong Item, nên trang quản trị <b>không đọc được</b> cờ đã bật —
            mở form ra rồi bấm Lưu là cờ tắt trở lại, im lặng đưa cả danh mục về nhánh tính theo trọng lượng.
            Đây là một nửa của nợ N4; nửa còn lại là chiều ghi ở <c>GoodsCategoryAttributeModel</c>.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.GoodsAttributeOptionItem">
            <summary>
            Item hiển thị lựa chọn kèm giá
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.GoodsAttributeOptionItem.Weight">
            <summary>
            Trọng lượng quy ước khi chọn lựa chọn này (kg), 0 = không khai.
            Form lên đơn cộng số này của các lựa chọn để ra cân của kiện.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.PostAgencyOption">
            <summary>
            Một dòng của ô "Bưu cục liên quan" trên form Bài viết (<c>GET api/Post/AgencyOptions</c>). Tập dòng trùng đúng tập
            chi nhánh mà bước lưu bài chấp nhận (<c>CmsOptionalLink.IsLinkableAgency</c>).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.PostAgencyOption.Id">
            <summary>Id bưu cục (<c>Agency.Id</c>) — giá trị gửi lên ở <c>PostModel.AgencyId</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.PostAgencyOption.Code">
            <summary>Mã bưu cục.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.PostAgencyOption.Name">
            <summary>Tên bưu cục trong cây tổ chức (<c>Agency.Name</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.PostAgencyOption.DisplayName">
            <summary>Tên hiển thị công khai (<c>AgencyProfile.DisplayName</c>); null nếu bưu cục chưa có hồ sơ hoặc hồ sơ đã xoá.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.PostAgencyOption.PublishStatus">
            <summary>
            Trạng thái công bố của hồ sơ (<c>AgencyPublishStatus</c>: 1 Nháp, 2 Đang công bố, 3 Tạm ngưng, 4 Đã đóng);
            null nếu chưa có hồ sơ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.PostItem.Title">
            <summary>
            Tiêu đề bài viết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.PostItem.ShortDescription">
            <summary>
            Mô tả ngắn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.PostItem.Status">
            <summary>
            Trạng thái bài viết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.PostItem.CreatedTime">
            <summary>
            Thời gian tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.PostItem.CreatedBy">
            <summary>
            Thời gian cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductItem.Thumbnail">
            <summary>
            Ảnh đại diện
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductItem.Name">
            <summary>
            Tên dịch vụ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductItem.ShortDescription">
            <summary>
            Mô tả ngắn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductItem.IsFeatured">
            <summary>
            Là sản phẩm nổi bật hay không?
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductItem.CreatedTime">
            <summary>
            Thời gian tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductItem.CreatedBy">
            <summary>
            Thời gian cập nhật
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductRouteCityOptions">
            <summary>
            Nguồn cho hai ô "Tỉnh đi / Tỉnh đến" của form Dịch vụ (<c>GET api/Product/RouteCityOptions</c>):
            danh sách tỉnh bộ 2 cấp kèm gợi ý đoán từ tên trang.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductRouteCityOptions.Provinces">
            <summary>Tỉnh bộ 2 cấp (Level 1, <c>LevelType = TwoLevel</c>) chưa xoá, sắp theo tên — đúng tập mà bước lưu chấp nhận.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductRouteCityOptions.SuggestedFromCityId">
            <summary>Id tỉnh đi gợi ý (bộ 2 cấp); null nếu không đoán được hoặc tỉnh đoán được là tỉnh cũ đã sáp nhập.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductRouteCityOptions.SuggestedToCityId">
            <summary>Id tỉnh đến gợi ý (bộ 2 cấp); null như <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductRouteCityOptions.SuggestedFromCityId"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductRouteCityOptions.GuessedFrom">
            <summary>
            Tên tỉnh đi đoán thô từ tên trang, có thể thuộc bộ 3 cấp cũ ("Hải Dương") — còn đó cả khi không map được sang
            bộ 2 cấp, để giao diện nói được "đoán ra Hải Dương nhưng đó là tỉnh cũ, hãy chọn tay".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductRouteCityOptions.GuessedTo">
            <summary>Tên tỉnh đến đoán thô, như <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductRouteCityOptions.GuessedFrom"/>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductProvinceOption">
            <summary>Một tỉnh bộ 2 cấp trong ô chọn tỉnh đi/đến.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductProvinceOption.Id">
            <summary>Id tỉnh bộ 2 cấp (<c>Location.Id</c>) — giá trị gửi lên <c>ProductModel.RouteFromCityId/RouteToCityId</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductProvinceOption.Name">
            <summary>Tên đầy đủ kèm tiền tố hành chính, ví dụ "Thành phố Hà Nội".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.TopicItem.SystemName">
            <summary>
            Tên hệ thống
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.TopicItem.Title">
            <summary>
            Gets or sets the title
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.TopicItem.Description">
            <summary>
            Gets or sets the body
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.TopicItem.TOC">
            <summary>
            Table of Content
            Từ thẻ H3 => H6
            Tự sinh trong khi thêm mới / cập nhật bài viết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.TopicItem.CreatedTime">
            <summary>
            Thời gian tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.TopicItem.CreatedBy">
            <summary>
            Thời gian cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.UrlRecordItem.Slug">
            <summary>
            Gets or sets the slug
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.UrlRecordItem.EntityName">
            <summary>
            Tên thực thể và cũng là tên controller luôn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.UrlRecordItem.EntityIdInt">
            <summary>
            Id của thực thể
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.UrlRedirectItem">
            <summary>Một dòng trên bảng danh sách luật chuyển hướng URL.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.UrlRedirectItem.HitCount">
            <summary>
            Số lượt request đã đi qua luật. <b>Đọc kèm <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.UrlRedirectItem.DaysActive"/></b>, xem ghi chú ở đó.
            </summary>
            <remarks>
            <b>Là số xấp xỉ, nghiêng về THIẾU.</b> Website cộng dồn trong bộ nhớ rồi mới ghi xuống,
            nhiều nhất một lần mỗi phút cho mỗi luật — nên phần chưa kịp ghi sẽ mất khi tiến trình khởi
            động lại, và ngưỡng "một lần mỗi phút" là <b>theo từng tiến trình web</b>, không phải theo cả
            website. Ghi ở đây chứ không chỉ ở entity, vì DTO là hợp đồng mà mọi client đọc.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.UrlRedirectItem.LastHitAt">
            <summary>Lần gần nhất có request đi qua; <c>null</c> = chưa ghi nhận lượt nào.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.UrlRedirectItem.DaysActive">
            <summary>
            Số ngày trọn vẹn luật đã tồn tại, tính từ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.UrlRedirectItem.CreatedTime"/>.
            </summary>
            <remarks>
            <b>Có mặt để giao diện không in ra một con số nói dối.</b> Một luật vừa tạo xong và một luật
            đã nằm đó ba tháng mà không ai gọi tới đều hiện <c>HitCount = 0</c> — hai tình trạng khác
            nhau hoàn toàn: cái đầu là <i>chưa biết gì</i>, cái sau là <i>đã đo và không ai vào</i>. Tính
            ở máy chủ thay vì để giao diện tự trừ ngày, để hai bên không bao giờ nói lệch nhau vì lệch
            múi giờ hay lệch đồng hồ máy khách.
            <para>
            <c>null</c> khi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.UrlRedirectItem.CreatedTime"/> rỗng (dữ liệu cũ chưa có mốc tạo) — lúc đó cũng
            không kết luận được gì về <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.UrlRedirectItem.HitCount"/>.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.UrlRedirectItem.ConflictsWithSitemap">
            <summary>
            Đường dẫn cũ này có còn đang được khai trong sitemap hay không — <b>ba trạng thái</b>.
            </summary>
            <remarks>
            <para>
            <c>true</c> là một mâu thuẫn cần sửa, không phải thông tin phụ: sitemap nói "hãy vào đọc
            trang này" trong khi máy chủ trả 301 "trang này đã chuyển đi", và công cụ tìm kiếm ghi nhận
            nó thành lỗi chứ không tự chọn giúp bên nào (bài học GEO-12).
            </para>
            <para>
            <c>false</c> = đã kiểm và không còn. <c>null</c> = <b>chưa kết luận được</b> — chỉ kiểm được
            một trong hai nguồn, vì hàng tồn kho sitemap (<c>SearchUrl</c>) còn rỗng. Sitemap sinh từ bảy
            nguồn, mà hơn mười đường dẫn tĩnh (<c>/</c>, <c>/gioi-thieu</c>, <c>/lien-he</c>,
            <c>/bang-gia</c>…) và toàn bộ trang bưu cục <c>/mang-luoi/{slug}</c> không đi qua
            <c>UrlRecord</c>, nên soi mỗi <c>UrlRecord</c> rồi trả <c>false</c> là nói về một nhóm chưa
            kiểm.
            </para>
            <para>
            <b><c>true</c> KHÔNG có nghĩa "có người bật lại cờ".</b> Có ít nhất bốn đường dẫn tới nó:
            luật được lưu ở trạng thái tắt (khi đó tầng lưu cố ý không chạm cờ sitemap), một
            <c>UrlRecord</c> cùng slug được tạo <b>sau</b>, bước tắt cờ hỏng mà luật vẫn vào bảng, hoặc
            URL vào sitemap từ một nguồn khác <c>UrlRecord</c>. Luật đang tắt luôn cho <c>false</c> vì
            nó không trả 301 nên không có mâu thuẫn nào.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentStyleBaseItem">
            <summary>Một phiên bản khối STYLE BASE / DO NOT dùng chung.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentStyleBaseItem.ImageCount">
            <summary>Số ảnh đang trỏ tới phiên bản này — để người sửa biết mình đang đụng vào bao nhiêu ảnh.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentImageFrameItem">
            <summary>Một khuôn ảnh trong từ điển khuôn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentImageReferenceItem">
            <summary>Một ảnh tham chiếu thương hiệu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentImageKitSnapshot">
            <summary>
            Ảnh chụp toàn bộ bộ công cụ ảnh dùng để ghép prompt và hiện hướng dẫn. Nạp một lần cho mỗi
            lời gọi chi tiết bài — ba bảng này đều là danh mục nhỏ (dưới trăm dòng), không phân trang.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentArticleItem">
            <summary>Dòng danh sách bài (list_articles / Search) — rút gọn, không có thân bài.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentImageItem">
            <summary>Một dòng bộ ảnh đã lưu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentImageItem.FullPromptEn">
            <summary>
            Prompt đã ghép sẵn khối STYLE BASE + phần riêng + DO NOT — thứ người tạo ảnh dán thẳng vào
            công cụ AI. Null khi ảnh không có prompt (dựng tay / chụp thật / không ảnh) hoặc khi chưa
            cấu hình khối chung; service điền, không map từ entity.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentImageItem.StyleBaseMissing">
            <summary>Có prompt riêng nhưng không tìm được khối STYLE BASE nào áp dụng — giao diện phải nói ra.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentImageItem.StyleBaseCodeUsed">
            <summary>Mã phiên bản khối thương hiệu ĐÃ dùng để ghép — để người đọc đối chiếu được bản nào đang chạy.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentImageItem.FrameName">
            <summary>Tên tiếng Việt của khuôn (từ ContentImageFrame), ví dụ "Bảng số".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentImageItem.FrameDescription">
            <summary>Mô tả khuôn đủ để người chưa từng làm vẫn dựng được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentImageItem.FrameTemplateUrl">
            <summary>Link mẫu dựng sẵn của khuôn (Canva…), nếu có.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentImageItem.FrameIsManual">
            <summary>Khuôn này dựng tay, không có prompt AI.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentAuthorItem">
            <summary>Một tác giả / người kiểm tra.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentAuthorItem.ArticleCount">
            <summary>Số bài đang đứng tên tác giả — để không xoá nhầm người còn bài.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentRunLogItem">
            <summary>Một lượt chạy nháp bài.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentServicePageItem">
            <summary>
            Một trang dịch vụ đang chạy trên website (<c>list_service_pages</c>) — trợ lý AI đặt link nội bộ
            theo danh sách này thay vì bịa URL.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentServicePageItem.UrlPath">
            <summary>Đường dẫn công khai, đã có dấu "/" đầu: <c>/dich-vu/xe-tai-ghep-ha-noi-thanh-hoa</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentServicePageItem.Label">
            <summary>Tên trang hiển thị (Product.Name).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentServicePageItem.RouteFrom">
            <summary>Tỉnh đầu suy được từ tên trang; null nếu không suy được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentServicePageItem.ProductType">
            <summary>Giá trị thô cột Product.ProductType (dữ liệu có cả giá trị 0 không nằm trong enum).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentServicePageItem.Kind">
            <summary>Loại trang đọc được: "Hàng hóa chung", "Xe đạp, xe máy", hoặc "Chưa phân loại".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentTopicItem">
            <summary>Một đề bài trong hàng đợi.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentArticleVersionItem">
            <summary>
            Một dòng lịch sử phiên bản bài — thanh bên màn chi tiết. Cố ý KHÔNG mang theo
            <c>BodyMarkdown</c>/<c>BriefJson</c>/<c>SelfScoreJson</c>: bài dài vài chục KB, mà danh sách chỉ cần
            "ai đổi, lúc nào, ghi chú gì". Xem lại nội dung một bản cũ là việc của giai đoạn sau.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentArticleVersionItem.ChangedBy">
            <summary>Tên người/trợ lý tạo bản này (<c>ContentArticleVersion.ChangedBy</c>).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem">
            <summary>
            CallLog Item - DTO cho hiển thị danh sách cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.Id">
            <summary>
            Identity
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.HistoryID">
            <summary>
            Call number - mỗi cuộc gọi có một số, nội bộ của 3CX
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.CallID">
            <summary>
            Call ID - định danh duy nhất của cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.Duration">
            <summary>
            Thời gian cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.TimeStart">
            <summary>
            Thời gian bắt đầu cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.TimeAnswered">
            <summary>
            Thời gian trả lời
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.TimeEnd">
            <summary>
            Thời gian kết thúc cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.ReasonTerminated">
            <summary>
            Lý do cuộc gọi bị chấm dứt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.FromNo">
            <summary>
            Số điện thoại nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.ToNo">
            <summary>
            Số điện thoại đích
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.DialNo">
            <summary>
            Số được quay
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.FinalNumber">
            <summary>
            Số cuối cùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.BillCost">
            <summary>
            Chi phí của cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.BillName">
            <summary>
            Tên tỷ lệ của biến thể thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.FromType">
            <summary>
            Loại nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.ToType">
            <summary>
            Loại đích
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.FromDispName">
            <summary>
            Tên hiển thị nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.ToDispName">
            <summary>
            Tên hiển thị đích
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.FinalDN">
            <summary>
            Distinguished name cuối cùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.FinalDispName">
            <summary>
            Tên hiển thị cuối cùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.IsMissedCall">
            <summary>
            Cuộc gọi nhỡ (FinalDN = GRP0000)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.CallType">
            <summary>
            Loại cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.LeadStatus">
            <summary>
            Trạng thái Lead
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.LeadStatusStr">
            <summary>
            Trạng thái Lead dạng string
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.StatusContent">
            <summary>
            Nội dung trạng thái
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.CreatedTime">
            <summary>
            Thời gian tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.UpdatedTime">
            <summary>
            Thời gian cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.CreatedByUserName">
            <summary>
            Người tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.UpdatedByUserName">
            <summary>
            Người cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.UserId">
            <summary>
            ID của user được mapping từ FinalDN
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CallLogItem.UserName">
            <summary>
            Tên user được mapping từ FinalDN
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerActivityItem">
            <summary>
            Một khách hàng kèm trạng thái hoạt động tại một thời điểm — kết quả
            <c>sp_GetActiveCustomersBySale</c>.
            </summary>
            <remarks>
            "Hoạt động" theo định nghĩa plan §7.4: có ít nhất một đơn tạo trong cửa sổ trượt 3 tháng và
            đơn đó đã giao thành công.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerActivityItem.CustomerId">
            <summary>ID khách hàng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerActivityItem.SaleId">
            <summary>Sale đang phụ trách (<c>Customer.ManagerId</c>)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerActivityItem.CustomerName">
            <summary>Tên khách hàng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerActivityItem.PhoneNumber">
            <summary>Số điện thoại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerActivityItem.UserName">
            <summary>Tên đăng nhập của tài khoản khách (rỗng nếu chưa có tài khoản)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerActivityItem.DeliveredOrderCount">
            <summary>Số đơn đã giao thành công trong cửa sổ 3 tháng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerActivityItem.LastDeliveryDate">
            <summary>Lần giao thành công gần nhất trong cửa sổ; null nếu không có đơn nào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerActivityItem.IsActive">
            <summary>Có đang hoạt động tại thời điểm chốt không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerAddressItem.Lat">
            <summary>
            Vĩ độ điểm đã ghim. 0 nghĩa là địa chỉ chưa được định vị.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerAddressItem.Long">
            <summary>
            Kinh độ điểm đã ghim. 0 nghĩa là địa chỉ chưa được định vị.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem">
            <summary>
            Item hiển thị thông tin tài khoản ngân hàng của khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem.AccountNumber">
            <summary>
            Số tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem.MaskedAccountNumber">
            <summary>
            Số tài khoản đã che (****1234)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem.AccountHolderName">
            <summary>
            Tên chủ tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem.BankCode">
            <summary>
            Mã ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem.BankName">
            <summary>
            Tên ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem.BranchName">
            <summary>
            Tên chi nhánh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem.BranchAddress">
            <summary>
            Địa chỉ chi nhánh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem.IsDefault">
            <summary>
            Có phải tài khoản mặc định
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem.DisplayInfo">
            <summary>
            Thông tin hiển thị đầy đủ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem.CanUseForTransfer">
            <summary>
            Có thể sử dụng để chuyển tiền không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem.CanEdit">
            <summary>
            Có thể chỉnh sửa không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerBankAccountItem.CanDelete">
            <summary>
            Có thể xóa không
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerCoManagerItem">
            <summary>
            Thông tin một sale đồng quản lý khách hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerComplaintItem">
            <summary>
            Dòng khiếu nại của khách hàng trên danh sách xử lý phía nhân viên.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerComplaintItem.Code">
            <summary>
            Mã khiếu nại hiển thị cho khách (KN + Id)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerComplaintItem.OrderId">
            <summary>
            Đơn hàng liên quan (không bắt buộc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerComplaintItem.Content">
            <summary>
            Nội dung khiếu nại của khách
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerComplaintItem.Status">
            <summary>
            Trạng thái: Draft → Processing → Resolved / Cancelled
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerComplaintItem.StaffResponse">
            <summary>
            Phản hồi của nhân viên xử lý (khách xem được qua app)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerComplaintDetailItem">
            <summary>
            Chi tiết khiếu nại kèm ảnh đính kèm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerComplaintDetailItem.Images">
            <summary>
            URL ảnh đính kèm (đã là URL tuyệt đối, lưu sẵn khi khách upload)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.ManagerChangeRequestItem">
            <summary>
            Dòng yêu cầu đổi nhân viên phụ trách trên danh sách duyệt phía nhân viên.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.ManagerChangeRequestItem.CurrentManagerId">
            <summary>
            Nhân viên phụ trách tại thời điểm khách gửi yêu cầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.ManagerChangeRequestItem.Reason">
            <summary>
            Lý do khách muốn đổi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.ManagerChangeRequestItem.Status">
            <summary>
            Trạng thái: Pending → Approved / Rejected
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerItem.FullName">
            <summary>
            Họ và tên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerItem.PhoneNumber">
            <summary>
            Số điện thoại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerItem.Address">
            <summary>
            Địa chỉ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerItem.Email">
            <summary>
            Địa chỉ email
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerItem.ZaloContact">
            <summary>
            Liên hệ zalo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerItem.FacebookContact">
            <summary>
            Liên hệ zalo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.CustomerItem.UseCustomPriceList">
            <summary>
            Khách có bảng giá riêng hay không — xem <c>CustomerModel.UseCustomPriceList</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.LeadItem.Id">
            <summary>
            Identity
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.LeadItem.FullName">
            <summary>
            Họ và tên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.LeadItem.PhoneNumber">
            <summary>
            Số điện thoại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.LeadItem.Message">
            <summary>
            Thông tin cần hỗ trợ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.LeadItem.SourcePath">
            <summary>
            Đường dẫn gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.LeadItem.CreatedTime">
            <summary>
            Ngày tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.LeadItem.CreatedTimeDisplay">
            <summary>
            Ngày tạo hiển thị (dd/MM/yyyy HH:mm)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.LeadItem.UpdatedTime">
            <summary>
            Ngày cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.LeadItem.UpdatedTimeDisplay">
            <summary>
            Ngày cập nhật hiển thị (dd/MM/yyyy HH:mm)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.LeadItem.PicId">
            <summary>
            Người phụ trách
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.LeadItem.PicUserName">
            <summary>
            Tên đăng nhập người phụ trách
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.LeadItem.LeadStatus">
            <summary>
            Trạng thái Lead
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.LeadItem.StatusContent">
            <summary>
            Nội dung trạng thái
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.VatInfoItem">
            <summary>
            Item thông tin xuất hóa đơn VAT của khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.VatInfoItem.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.VatInfoItem.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.VatInfoItem.TaxCode">
            <summary>
            Mã số thuế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.VatInfoItem.CompanyName">
            <summary>
            Tên công ty/cá nhân
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.VatInfoItem.Address">
            <summary>
            Địa chỉ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.VatInfoItem.InvoiceEmail">
            <summary>
            Email nhận hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.VatInfoItem.ContactName">
            <summary>
            Người liên hệ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.VatInfoItem.ContactPhone">
            <summary>
            Điện thoại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.VatInfoItem.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.VatInfoItem.IsDefault">
            <summary>
            Mặc định (chỉ có 1 record mặc định cho mỗi khách hàng)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.VatInfoItem.UpdatedDate">
            <summary>
            Ngày cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Crm.VatInfoItem.UpdatedBy">
            <summary>
            Người cập nhật
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem">
            <summary>
            Item chứa thông tin đơn hàng tài chính của lái xe cho search có phân trang
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.OrderId">
            <summary>
            ID của đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.OrderCode">
            <summary>
            Mã đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.PartnerCode">
            <summary>
            Mã đối tác
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.SourceFee">
            <summary>
            Số tiền cước lấy hàng (SourceFee) của đơn này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.DestFee">
            <summary>
            Số tiền cước giao hàng (DestFee) của đơn này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.CollectAmount">
            <summary>
            Số tiền thu hộ (COD) của đơn này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.TotalAmount">
            <summary>
            Tổng số tiền của đơn này mà driver đang cầm
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.Status">
            <summary>
            Trạng thái đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.StatusStr">
            <summary>
            Trạng thái đơn hàng dạng string
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.PhysicalStatus">
            <summary>
            Trạng thái vật lý đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.PhysicalStatusStr">
            <summary>
            Trạng thái vật lý dạng string
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.PayFeeType">
            <summary>
            Loại thanh toán cước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.PayFeeTypeStr">
            <summary>
            Loại thanh toán cước dạng string
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.CreatedDate">
            <summary>
            Ngày tạo đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.CreatedDateStr">
            <summary>
            Ngày tạo đơn hàng dạng string
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.Note">
            <summary>
            Ghi chú đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.PicUserName">
            <summary>
            Tên người phụ trách (PIC)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.RouteName">
            <summary>
            Tên tuyến đường
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.SourceAddress">
            <summary>
            Địa chỉ lấy hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.DestAddress">
            <summary>
            Địa chỉ giao hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.CashierType">
            <summary>
            Loại tiền mà driver đang cầm cho đơn này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.IsOriginalCashier">
            <summary>
            Driver có phải là người thu tiền ban đầu không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.CollectedTime">
            <summary>
            Thời gian thu tiền lần đầu (nếu driver là người thu ban đầu)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.CollectedTimeStr">
            <summary>
            Thời gian thu tiền lần đầu dạng string
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.SourceWardId">
            <summary>
            WardId của địa chỉ lấy hàng (dùng nội bộ để enrich)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.DestWardId">
            <summary>
            WardId của địa chỉ giao hàng (dùng nội bộ để enrich)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.ContactName">
            <summary>
            Tên người liên hệ (tùy theo loại phí thu)
            - Thu phí nguồn: Tên người gửi
            - Thu phí đích/COD: Tên người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.ContactPhone">
            <summary>
            Số điện thoại liên hệ (tùy theo loại phí thu)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.ContactAddress">
            <summary>
            Địa chỉ liên hệ (tùy theo loại phí thu)
            - Thu phí nguồn: Địa chỉ gửi hàng
            - Thu phí đích/COD: Địa chỉ giao hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.AddressType">
            <summary>
            Loại địa chỉ hiển thị (Source/Dest)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem.DepositStatus">
            <summary>
            Trạng thái nộp tiền của lái xe cho đơn này
            "Chưa nộp" - Lái xe đang cầm tiền
            "Đã nộp" - Lái xe đã nộp tiền về
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailAccountItem">
            <summary>
            Item tài khoản gửi email (trả về UI).
            KHÔNG bao giờ trả về giá trị secret thật — chỉ cờ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailAccountItem.HasPassword"/>/<see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailAccountItem.HasSecretKey"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailAccountItem.ProviderTypeDisplay">
            <summary>Nhãn hiển thị của loại nhà cung cấp (SMTP/SES/Mock).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailAccountItem.HasPassword">
            <summary>Đã cấu hình mật khẩu SMTP hay chưa (không lộ giá trị).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailAccountItem.HasSecretKey">
            <summary>Đã cấu hình secret key SES hay chưa (không lộ giá trị).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogItem">
            <summary>
            Item nhật ký gửi email (chỉ đọc, hiển thị trên trang giám sát).
            KHÔNG chứa nội dung mã OTP / body — chỉ metadata.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogItem.EmailAccountId">
            <summary>Tài khoản gửi đã dùng (nếu có).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogItem.EmailAccountName">
            <summary>Tên tài khoản gửi (join từ EmailAccount).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogItem.ProviderUsed">
            <summary>Kênh thực tế đã gửi: smtp / ses / mock.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogItem.ToEmail">
            <summary>Email người nhận.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogItem.Subject">
            <summary>Tiêu đề email.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogItem.Purpose">
            <summary>Loại email (đăng ký OTP / khác).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogItem.PurposeDisplay">
            <summary>Mô tả loại email.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogItem.Status">
            <summary>Trạng thái gửi (1=thành công, 2=thất bại).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogItem.StatusDisplay">
            <summary>Mô tả trạng thái.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogItem.ErrorMessage">
            <summary>Thông báo lỗi (khi thất bại).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogItem.DurationMs">
            <summary>Thời gian gửi (ms).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogItem.SentAt">
            <summary>Thời điểm gửi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogItem.SentAtDisplay">
            <summary>Hiển thị thời điểm gửi.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogSummaryItem">
            <summary>
            Báo cáo tổng hợp gửi email trong một khoảng thời gian (cho SummaryCard).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogSummaryItem.Total">
            <summary>Tổng số email đã gửi (mọi trạng thái).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogSummaryItem.SuccessCount">
            <summary>Số gửi thành công.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogSummaryItem.FailedCount">
            <summary>Số gửi thất bại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogSummaryItem.SuccessRate">
            <summary>Tỷ lệ thành công (%), làm tròn 1 chữ số.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportItem">
            <summary>
            Item hiển thị thông tin báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportItem.Url">
            <summary>
            URL trang web xảy ra lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportItem.ErrorDescription">
            <summary>
            Nội dung mô tả lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportItem.Status">
            <summary>
            Trạng thái xử lý báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportItem.StatusDisplay">
            <summary>
            Tên trạng thái hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportItem.AdminNote">
            <summary>
            Ghi chú từ admin khi xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportItem.ReportedByUserId">
            <summary>
            ID người dùng báo lỗi (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportItem.ReporterName">
            <summary>
            Tên người báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportItem.ReporterEmail">
            <summary>
            Email người báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportItem.ReporterPhone">
            <summary>
            Số điện thoại người báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportItem.BrowserInfo">
            <summary>
            Thông tin trình duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportItem.DeviceInfo">
            <summary>
            Thông tin thiết bị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportItem.MediaItems">
            <summary>
            Danh sách hình ảnh lỗi
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportMediaItem">
            <summary>
            Item hiển thị thông tin media báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportMediaItem.ErrorReportId">
            <summary>
            ID báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportMediaItem.ImageUrl">
            <summary>
            URL hiển thị hình ảnh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportMediaItem.OriginalFileName">
            <summary>
            Tên file gốc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportMediaItem.FileSize">
            <summary>
            Kích thước file (bytes)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportMediaItem.FileSizeDisplay">
            <summary>
            Kích thước file hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportMediaItem.ContentType">
            <summary>
            Loại file
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportMediaItem.Description">
            <summary>
            Mô tả hình ảnh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.ErrorReports.ErrorReportMediaItem.DisplayOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankAccountItem">
            <summary>
            DTO Item cho tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankAccountItem.AccountName">
            <summary>
            Tên tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankAccountItem.AccountNumber">
            <summary>
            Số tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankAccountItem.CurrentBalance">
            <summary>
            Số dư hiện tại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankAccountItem.TransactionCount">
            <summary>
            Số lượng giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankAccountItem.LastTransactionDate">
            <summary>
            Ngày giao dịch cuối cùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankAccountItem.ManagerUserName">
            <summary>
            Tên người quản lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankAccountItem.ManagerFullName">
            <summary>
            Họ tên người quản lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankAccountItem.LastBalanceUpdate">
            <summary>
            Ngày cập nhật số dư cuối cùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankAccountItem.CanCollectCod">
            <summary>
            Tài khoản có thể thu hộ COD (tài khoản nhận cước)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem">
            <summary>
            DTO Item cho import sao kê ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.BankAccountId">
            <summary>
            ID tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.BankAccountName">
            <summary>
            Tên tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.BankAccountNumber">
            <summary>
            Số tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.BankName">
            <summary>
            Tên ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.BankCode">
            <summary>
            Mã ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.OriginalFileName">
            <summary>
            Tên file gốc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.FileSize">
            <summary>
            Kích thước file (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.TotalRows">
            <summary>
            Tổng số dòng trong file
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.ProcessedRows">
            <summary>
            Số dòng xử lý thành công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.ErrorRows">
            <summary>
            Số dòng lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.SkippedRows">
            <summary>
            Số dòng bỏ qua
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.DuplicateRows">
            <summary>
            Số dòng trùng lặp
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.ImportStatus">
            <summary>
            Trạng thái import
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.ErrorMessage">
            <summary>
            Thông báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.DataFromDate">
            <summary>
            Ngày bắt đầu của dữ liệu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.DataToDate">
            <summary>
            Ngày kết thúc của dữ liệu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.OverwriteExisting">
            <summary>
            Có ghi đè dữ liệu trùng lặp không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.ProcessStartTime">
            <summary>
            Thời gian bắt đầu xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.ProcessEndTime">
            <summary>
            Thời gian kết thúc xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.ProcessDuration">
            <summary>
            Thời gian xử lý (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.ImportedByUserName">
            <summary>
            Tên người thực hiện import
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankStatementImportItem.SuccessRate">
            <summary>
            Tỷ lệ thành công (%)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem">
            <summary>
            DTO Item cho giao dịch ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.BankAccountId">
            <summary>
            ID tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.TransactionCode">
            <summary>
            Mã giao dịch từ ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.TransactionDate">
            <summary>
            Ngày giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.CreditAmount">
            <summary>
            Số tiền ghi có (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.DebitAmount">
            <summary>
            Số tiền ghi nợ (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.Balance">
            <summary>
            Số dư sau giao dịch (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.Description">
            <summary>
            Nội dung giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.DetailedTime">
            <summary>
            Thời gian giao dịch chi tiết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.ProcessStatus">
            <summary>
            Trạng thái xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.TransactionType">
            <summary>
            Loại giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.ReferenceNumber">
            <summary>
            Mã tham chiếu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.CounterpartyName">
            <summary>
            Tên người gửi/nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.CounterpartyAccount">
            <summary>
            Số tài khoản người gửi/nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.CounterpartyBank">
            <summary>
            Ngân hàng của người gửi/nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.BankAccountName">
            <summary>
            Tên tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.BankAccountNumber">
            <summary>
            Số tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.ImportId">
            <summary>
            ID import (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.ImportRowNumber">
            <summary>
            Số dòng trong file import
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.ProcessNote">
            <summary>
            Ghi chú xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.BankTransactionItem.DisplayOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowLineItem">
            <summary>
            Một dòng dữ liệu trong báo cáo Cash Flow (VD: "Thu cước", "Đối soát COD")
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowLineItem.Label">
            <summary>
            Nhãn hiển thị (VD: "Thu cước vận chuyển")
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowLineItem.Category">
            <summary>
            Phân loại (Fee, COD, OPEX, Loan, FuelCard, Other)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowLineItem.AmountByPeriod">
            <summary>
            Số tiền theo từng kỳ (key = ngày hoặc tuần)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowLineItem.TotalAmount">
            <summary>
            Tổng số tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowLineItem.Percentage">
            <summary>
            Phần trăm trên tổng Inflow hoặc Outflow
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowReportResult">
            <summary>
            Kết quả báo cáo Cash Flow Dashboard
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowReportResult.PeriodColumns">
            <summary>
            Danh sách cột kỳ (ngày: "2026-04-01" hoặc tuần: "W14")
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowReportResult.Inflows">
            <summary>
            Các dòng tiền vào
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowReportResult.Outflows">
            <summary>
            Các dòng tiền ra
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowReportResult.TotalInflowByPeriod">
            <summary>
            Tổng Inflow theo từng kỳ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowReportResult.TotalOutflowByPeriod">
            <summary>
            Tổng Outflow theo từng kỳ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowReportResult.NetCashFlowByPeriod">
            <summary>
            Dòng tiền ròng theo từng kỳ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowReportResult.GrandTotalInflow">
            <summary>
            Tổng dòng tiền vào
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowReportResult.GrandTotalOutflow">
            <summary>
            Tổng dòng tiền ra
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowReportResult.GrandNetCashFlow">
            <summary>
            Dòng tiền ròng = Inflow - Outflow
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowOrderDetailItem">
            <summary>
            Một dòng chi tiết đơn hàng trong drill-down Thu cước / Thu COD
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowOrderDetailItem.ReconciliationCode">
            <summary>Mã phiếu đối soát (nếu có)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashFlowInflowDetailResult">
            <summary>
            Kết quả drill-down danh sách đơn theo kỳ / loại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashierBalanceItem.EarliestCollectedTime">
            <summary>
            Thời gian thu tiền sớm nhất trong các đơn đang cầm (từ SP)
            Dùng để tính deadline nộp tiền thay cho LastPaymentTime
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashierBalanceItem.LastPaymentTime">
            <summary>
            Thời gian nộp tiền gần nhất (từ UserPreference, giữ lại để tham khảo)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashierBalanceItem.ViolationCountThisMonth">
            <summary>
            Số lần vi phạm nộp tiền trong tháng hiện tại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashierBalanceItem.IsOverdue">
            <summary>
            Đang quá hạn nộp tiền (quá 10h sáng hôm sau)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashierBalanceItem.CurrentPenaltyAmount">
            <summary>
            Mức phạt hiện tại theo cấu hình AutoPenaltyLevel (VND)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CashierBalanceItem.PenaltyDescription">
            <summary>
            Mô tả hình thức xử lý (Nhắc nhở / Phạt 100k / ...)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlRowItem">
            <summary>
            Model cho một dòng trong báo cáo kiểm soát chi phí (dạng cây danh mục)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlRowItem.CategoryId">
            <summary>
            ID danh mục chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlRowItem.CategoryName">
            <summary>
            Tên danh mục chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlRowItem.RowNumber">
            <summary>
            Mã số thứ tự hiển thị (ví dụ: "1", "1.1", "1.1.1")
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlRowItem.ParentId">
            <summary>
            ID danh mục cha (null nếu là danh mục gốc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlRowItem.DailyTotals">
            <summary>
            Tổng tiền theo từng ngày: Key = "yyyy-MM-dd", Value = số tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlRowItem.TotalSum">
            <summary>
            Tổng cộng toàn bộ các ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlRowItem.AveragePerDay">
            <summary>
            Trung bình tiền/ngày (TotalSum / số ngày trong khoảng lọc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlRowItem.Percentage">
            <summary>
            Tỷ lệ phần trăm trên tổng toàn bộ chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlRowItem.Children">
            <summary>
            Danh sách danh mục con
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlReportResult">
            <summary>
            Kết quả trả về của báo cáo kiểm soát chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlReportResult.DateColumns">
            <summary>
            Danh sách các ngày trong khoảng báo cáo (yyyy-MM-dd)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlReportResult.Rows">
            <summary>
            Danh sách dòng dữ liệu dạng cây
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlReportResult.GrandDailyTotals">
            <summary>
            Tổng tiền theo từng ngày (dòng tổng cuối cùng)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlReportResult.GrandTotal">
            <summary>
            Tổng tiền toàn bộ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlReportResult.GrandAveragePerDay">
            <summary>
            Trung bình/ngày toàn bộ
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem">
            <summary>
            Item tóm tắt đối soát theo khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.CustomerPhone">
            <summary>
            Số điện thoại khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.CustomerEmail">
            <summary>
            Email khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.PendingOrderCount">
            <summary>
            Số lượng đơn hàng cần đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.PendingCodAmount">
            <summary>
            Tổng tiền COD cần đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.EstimatedFeeAmount">
            <summary>
            Tổng phí dự kiến trừ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.EstimatedReconciliationAmount">
            <summary>
            Tổng tiền đối soát dự kiến (tính theo logic PayFeeType)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.EstimatedNetAmount">
            <summary>
            Số tiền dự kiến chuyển (sử dụng logic mới)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.OldestOrderDate">
            <summary>
            Ngày đơn hàng cũ nhất chưa đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.LatestOrderDate">
            <summary>
            Ngày đơn hàng mới nhất chưa đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.CompletedReconciliationCount">
            <summary>
            Số lượng đối soát đã tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.CompletedReconciliationAmount">
            <summary>
            Tổng tiền đã đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.HasDefaultBankAccount">
            <summary>
            Có tài khoản ngân hàng mặc định không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.DefaultBankAccountInfo">
            <summary>
            Thông tin tài khoản ngân hàng mặc định
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.CanCreateReconciliation">
            <summary>
            Có thể tạo đối soát không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.CanConfirm">
            <summary>
            Có quyền duyệt đối soát không (Reconciliation.Confirm hoặc Founder)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.CanTransfer">
            <summary>
            Có quyền cập nhật chuyển tiền đối soát không (Reconciliation.Transfer hoặc Founder)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.Priority">
            <summary>
            Mức độ ưu tiên (dựa trên số tiền và thời gian)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.PriorityStr">
            <summary>
            Mức độ ưu tiên dạng string
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CustomerReconciliationSummaryItem.PriorityColor">
            <summary>
            Màu sắc hiển thị theo mức độ ưu tiên
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationPriority">
            <summary>
            Mức độ ưu tiên đối soát
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.DriverTransferSlipItem">
            <summary>
            Item cho danh sách phiếu chuyển tiền (Search result)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.DriverTransferSlipDetailModel">
            <summary>
            Chi tiết phiếu chuyển tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.DriverTransferSlipDetailModel.Orders">
            <summary>
            Danh sách đơn hàng trong phiếu
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.DriverTransferSlipOrderItem">
            <summary>
            Đơn hàng trong phiếu chuyển tiền
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.DriverTransferSlipSummary">
            <summary>
            Tóm tắt phiếu đang chờ duyệt (embed trong DriverFinModel cho mobile)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.DriverTransferSlipResult">
            <summary>
            Kết quả tạo/duyệt/từ chối phiếu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseHistoryItem.ExpenseId">
            <summary>
            ID của chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseHistoryItem.OldStatus">
            <summary>
            Trạng thái trước khi thay đổi (null nếu là tạo mới)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseHistoryItem.OldStatusDisplay">
            <summary>
            Tên trạng thái cũ (hiển thị)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseHistoryItem.NewStatus">
            <summary>
            Trạng thái sau khi thay đổi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseHistoryItem.NewStatusDisplay">
            <summary>
            Tên trạng thái mới (hiển thị)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseHistoryItem.ActionByUserName">
            <summary>
            Tên người thực hiện hành động
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseHistoryItem.Reason">
            <summary>
            Lý do từ chối (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseHistoryItem.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.Description">
            <summary>
            Mô tả chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.Note">
            <summary>
            Ghi chú cho chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.Amount">
            <summary>
            Số tiền chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.ExpenseCategoryId">
            <summary>
            Danh mục chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.Status">
            <summary>
            Trạng thái chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.PaymentMethod">
            <summary>
            Phương thức thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.ApprovedBy">
            <summary>
            UserId của người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.ApprovedByUserName">
            <summary>
            Tên người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.RejectReason">
            <summary>
            Lý do từ chối (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.CanApprove">
            <summary>
            Có được phép duyệt chi phí này không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.CanReject">
            <summary>
            Có được phép từ chối chi phí này không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.CanMarkAsPaid">
            <summary>
            Có được phép đánh dấu đã thanh toán không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.UserBankAccountId">
            <summary>
            ID tài khoản ngân hàng nhận tiền (chỉ để reference)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.UserBankAccountInfo">
            <summary>
            Thông tin tài khoản ngân hàng nhận tiền (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.BankAccountNumber">
            <summary>
            Số tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.BankAccountHolderName">
            <summary>
            Tên chủ tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.BankCode">
            <summary>
            Mã ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.BankName">
            <summary>
            Tên ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.BankBranchName">
            <summary>
            Tên chi nhánh ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem.Histories">
            <summary>
            Danh sách lịch sử thay đổi trạng thái
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.FuelCardStatementItem">
            <summary>
            DTO hiển thị kỳ sao kê thẻ xăng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.VehicleLoanItem">
            <summary>
            DTO hiển thị hợp đồng vay xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.VehicleLoanItem.InterestRateDescription">
            <summary>
            Mô tả tóm tắt giai đoạn lãi suất, VD: "8.5% (T1-12), 12.5% (T13-15)"
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.VehicleLoanItem.HasSettlement">
            <summary>Có tất toán hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.VehicleLoanItem.SettlementStatus">
            <summary>Trạng thái tất toán (0=Processing, 1=Completed, 2=Cancelled)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.VehicleLoanItem.SettlementTotalAmount">
            <summary>Tổng tiền tất toán</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.VehicleLoanItem.SettlementPaidAmount">
            <summary>Tổng tiền đã thanh toán (Expense status = Paid)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.VehicleLoanItem.SettlementPendingAmount">
            <summary>Tổng tiền chờ duyệt/chờ thanh toán</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.VehicleLoanItem.SettlementApprovalProgress">
            <summary>Số phí đã duyệt / tổng phí</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.LoanRepaymentScheduleItem">
            <summary>
            DTO hiển thị lịch trả nợ kỳ
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.LoanSettlementItem">
            <summary>
            DTO hiển thị thông tin tất toán khoản vay
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.LoanSettlementFeeItem">
            <summary>
            DTO hiển thị khoản phí tất toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.LoanSettlementFeeItem.ExpenseStatus">
            <summary>
            Trạng thái Expense liên kết (0=Pending, 1=Approved, 2=Rejected, 3=Paid)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem">
            <summary>
            MA TRẬN giá theo loại hàng để hiển thị: tuyến (hàng) × lựa chọn thuộc tính trục (cột).
            </summary>
            <remarks>
            <para>
            <b>Vì sao trả lưới đầy đủ chứ không chỉ các dòng giá đang có.</b> Người quản trị cần thấy ô nào
            CHƯA khai giá thì mới biết phải khai — trả về danh sách dòng <c>Price</c> thô thì ô trống đơn giản
            là không xuất hiện, và một tuyến bị bỏ quên trông y hệt một tuyến không tồn tại. Ô trống chính là
            thứ phải nhìn thấy: đơn đi tuyến đó với option đó sẽ báo "chưa có giá".
            </para>
            <para>
            <b><see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.HasPriceTable"/> và <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.PricingMode"/> là HAI thứ khác nhau, đừng gộp.</b>
            Engine chọn trục bằng DỮ LIỆU (<c>EXISTS(Price WHERE GoodsCategoryId = C AND IsDeleted = 0)</c>),
            không bằng mode. Danh mục khai mode <c>RoutePriceList</c> mà chưa có ô giá nào vẫn tính theo trọng
            lượng. Trả cả hai để UI nói được đúng sự thật đó thay vì tin vào mode.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.GoodsCategoryId">
            <summary>
            Danh mục hàng hóa của bảng giá này.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.CategoryName">
            <summary>
            Tên danh mục — để dựng tiêu đề và câu cảnh báo.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.PricingMode">
            <summary>
            Cách áp giá đang khai trong cấu hình danh mục.
            </summary>
            <remarks>
            ⚠️ <see cref="F:Lada.Framework.Data.Enums.GoodsPricingMode.FixedPrice"/> <b>triệt tiêu cước tuyến</b>;
            <see cref="F:Lada.Framework.Data.Enums.GoodsPricingMode.RoutePriceList"/> chỉ đổi cách tra, cước tuyến VẪN thu. Đây là hai
            công tắc riêng, UI không được gộp làm một.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.HasPriceTable">
            <summary>
            Danh mục có thật sự đang đi theo nhánh bảng giá riêng hay không — trả lời theo DỮ LIỆU.
            </summary>
            <remarks>
            <c>false</c> trong khi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.PricingMode"/> là <c>RoutePriceList</c> nghĩa là mode đã khai
            nhưng chưa có ô giá nào ⇒ đơn vẫn tính theo trọng lượng. UI phải nói rõ điều này.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.PriceAxisAttributeId">
            <summary>
            Thuộc tính trục giá (<c>IsPriceAxis = 1</c>) của danh mục. <c>null</c> = chưa khai trục.
            </summary>
            <remarks>
            Chưa khai trục thì không dựng được cột nào — ma trận trả về rỗng kèm
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.Message"/> giải thích, chứ không trả lưới trống không lý do.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.PriceAxisAttributeName">
            <summary>
            Tên thuộc tính trục — nhãn của trục cột trên lưới.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.PriceType">
            <summary>
            Loại giá của các ô đang có. Ô ma trận bình thường là <see cref="F:Lada.Framework.Data.Enums.PriceType.FixPrice"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.CellCount">
            <summary>
            Số ô đã khai giá — dùng cảnh báo trước khi xoá ô cuối cùng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.Columns">
            <summary>
            Cột của ma trận: các lựa chọn của thuộc tính trục.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.Rows">
            <summary>
            Hàng của ma trận: các tuyến.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.Message">
            <summary>
            Lời giải thích khi ma trận rỗng (chưa khai trục, trục không có lựa chọn nào...).
            Chuỗi rỗng khi bình thường.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceMatrixColumnItem">
            <summary>
            Một CỘT của ma trận — một lựa chọn của thuộc tính trục.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceMatrixColumnItem.OptionId">
            <summary>
            <c>GoodsAttributeOption.Id</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceMatrixColumnItem.Label">
            <summary>
            Nhãn hiển thị của lựa chọn.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceMatrixRowItem">
            <summary>
            Một HÀNG của ma trận — một tuyến kèm đủ ô theo mọi cột.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceMatrixRowItem.RouteRange">
            <summary>
            Khoảng cách của tuyến, hiển thị dạng "0 - 30 km".
            </summary>
            <remarks>
            ⚠️ DB lưu khoảng cách bằng MÉT, chuỗi này đã quy sang km. Đừng đọc số trong chuỗi rồi tính tiếp.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceMatrixRowItem.Cells">
            <summary>
            Ô giá theo đúng thứ tự cột của <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceMatrixItem.Columns"/>.
            Luôn đủ số ô — ô chưa khai giá vẫn có mặt với <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceMatrixCellItem.DaKhoiTao"/> = false.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceMatrixCellItem">
            <summary>
            Một Ô của ma trận.
            </summary>
            <remarks>
            <b>Ba trạng thái, đừng gộp còn hai.</b> <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceMatrixCellItem.DaKhoiTao"/> = false là <b>chưa có dòng giá</b> ⇒
            đơn đi ô này sẽ báo "chưa có giá cho tuyến". <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceMatrixCellItem.DaKhoiTao"/> = true với
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceMatrixCellItem.Value"/> = 0 là <b>đã khởi tạo, khai giá 0</b> ⇒ đơn ra cước 0 đồng, hoàn toàn khác. Nhìn
            mỗi <c>Value</c> thì hai trạng thái này trông giống hệt nhau, và đó chính là chỗ người quản trị
            tưởng đã khai xong.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceMatrixCellItem.Id">
            <summary>
            Id dòng <c>Price</c>. <c>0</c> = ô trống, chưa có dòng nào trong DB.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceMatrixCellItem.Value">
            <summary>
            Giá của ô. Chỉ có nghĩa khi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceMatrixCellItem.DaKhoiTao"/> = true.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceMatrixCellItem.DaKhoiTao">
            <summary>
            Ô đã có dòng giá trong DB hay chưa.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceTableItem">
            <summary>
            Một danh mục hàng hóa ĐÃ có bảng giá riêng — để trang danh sách đánh dấu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceTableItem.CellCount">
            <summary>
            Số ô giá đang có (đã lọc <c>IsDeleted</c>). Luôn &gt; 0 vì danh mục 0 ô không nằm trong danh sách này.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceTableItem.RouteCount">
            <summary>
            Số tuyến đã có ít nhất một ô giá — để thấy bảng còn thiếu tuyến nào.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.GoodsCategoryPriceTableItem.PricingMode">
            <summary>
            Cách áp giá đang khai trong cấu hình. Lệch với thực tế (có ô giá) là chuyện đáng hiện lên UI.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeHistoryItem.IncomeId">
            <summary>
            ID của doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeHistoryItem.Status">
            <summary>
            Trạng thái doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeHistoryItem.Reason">
            <summary>
            Lý do từ chối (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeHistoryItem.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeHistoryItem.ActionByUserName">
            <summary>
            Tên người thực hiện hành động
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeItem.Description">
            <summary>
            Mô tả doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeItem.Note">
            <summary>
            Ghi chú cho doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeItem.Amount">
            <summary>
            Số tiền doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeItem.IncomeCategoryId">
            <summary>
            Danh mục doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeItem.Status">
            <summary>
            Trạng thái doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeItem.ApprovedBy">
            <summary>
            UserId của người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeItem.ApprovedByUserName">
            <summary>
            Tên người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeItem.RejectReason">
            <summary>
            Lý do từ chối (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeItem.CanApprove">
            <summary>
            Có được phép duyệt doanh thu này không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeItem.CanReject">
            <summary>
            Có được phép từ chối doanh thu này không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeItem.CanMarkAsReceived">
            <summary>
            Có được phép đánh dấu đã nhận tiền không
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceScopeItem">
            <summary>
            Một PHẠM VI bảng giá của khách hàng — bộ ba <c>(CustomerId, GoodsCategoryId, PriceType)</c>.
            </summary>
            <remarks>
            <para>
            Đây là đơn vị định danh bảng giá của v2. <c>GoodsCategoryId = null</c> là bảng giá CHUNG theo
            khoảng trọng lượng; có giá trị là bảng giá riêng của một loại hàng.
            </para>
            <para>
            <b>Cờ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceScopeItem.IsInherited"/> là thứ đáng đọc nhất ở đây.</b> Nó nói phạm vi này khách
            <i>chưa khai dòng nào</i> và đang ăn theo bảng giá mặc định (QĐ-2). Danh sách cố tình liệt kê cả
            phạm vi đi mượn chứ không chỉ phạm vi khách sở hữu: người quản trị cần thấy "khách này đang tính
            tiền bằng bảng của ai" ngay trên màn hình, thay vì phải suy ra bằng cách không thấy dòng nào.
            </para>
            <para>
            ⚠️ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceScopeItem.RowCount"/> của phạm vi đi mượn là số dòng của <b>bảng mặc định</b>, không phải của
            khách. Hiện nó như số dòng của khách sẽ khiến người dùng tưởng mình đã khai giá riêng rồi.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceScopeItem.CustomerId">
            <summary>Khách sở hữu phạm vi đang xét — luôn là khách được hỏi, kể cả khi đi mượn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceScopeItem.GoodsCategoryId">
            <summary>Loại hàng của bảng giá. <c>null</c> = bảng giá chung theo khoảng trọng lượng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceScopeItem.GoodsCategoryName">
            <summary>Tên loại hàng để hiện lên UI. Rỗng khi là bảng giá chung.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceScopeItem.PriceType">
            <summary>Loại giá của bảng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceScopeItem.RowCount">
            <summary>Số dòng giá đang có trong phạm vi. Xem cảnh báo ở phần chú thích của lớp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceScopeItem.IsInherited">
            <summary>
            <c>true</c> = khách trống hẳn phạm vi này và đang dùng bảng giá mặc định.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem">
            <summary>
            Đơn hàng có thể đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.Code">
            <summary>
            Mã đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.PartnerCode">
            <summary>
            Mã đối tác
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.CodAmount">
            <summary>
            Tiền COD
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.ServiceFee">
            <summary>
            Phí dịch vụ (có thể trừ vào COD)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.ReconciliationAmount">
            <summary>
            Tiền đối soát dựa trên PayFeeType
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.NetAmount">
            <summary>
            Tiền thực tế = ReconciliationAmount (đã tính theo logic PayFeeType)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.CodStage">
            <summary>
            Trạng thái COD
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.CodStageStr">
            <summary>
            Trạng thái COD dạng string
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.OrderStatus">
            <summary>
            Trạng thái đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.OrderStatusStr">
            <summary>
            Trạng thái đơn hàng dạng string
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.DeliveredDate">
            <summary>
            Ngày giao hàng thành công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.CodCollectedDate">
            <summary>
            Ngày thu COD
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.ChargeWeight">
            <summary>
            Trọng lượng tính cước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.ShippingFee">
            <summary>
            Cước vận chuyển
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.DeliveryAddress">
            <summary>
            Địa chỉ giao hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.ReceiverName">
            <summary>
            Tên người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.ReceiverPhone">
            <summary>
            Số điện thoại người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.Note">
            <summary>
            Ghi chú đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.IsSelected">
            <summary>
            Có được chọn để đối soát không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliableOrderItem.CanReconcile">
            <summary>
            Có thể đối soát không (CodStage = Head)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem">
            <summary>
            Item hiển thị trong danh sách đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.Code">
            <summary>
            Mã đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.CustomerPhone">
            <summary>
            Số điện thoại khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.FromDate">
            <summary>
            Từ ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.ToDate">
            <summary>
            Đến ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.TransferDate">
            <summary>
            Ngày chuyển tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.TotalCodAmount">
            <summary>
            Tổng tiền COD
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.TotalFeeAmount">
            <summary>
            Tổng phí trừ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.NetAmount">
            <summary>
            Số tiền thực chuyển
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.OrderCount">
            <summary>
            Số lượng đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.Status">
            <summary>
            Trạng thái
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.StatusStr">
            <summary>
            Trạng thái dạng string
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.Type">
            <summary>
            Loại phiếu đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.TypeStr">
            <summary>
            Loại phiếu đối soát dạng string
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.VatInfoId">
            <summary>
            ID thông tin xuất hóa đơn VAT
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.VatCompanyName">
            <summary>
            Tên công ty xuất hóa đơn VAT
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.CreatedByUsername">
            <summary>
            Người tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.ApprovedByUsername">
            <summary>
            Người phê duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.TransferredByUsername">
            <summary>
            Người chuyển tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.CanEdit">
            <summary>
            Có thể chỉnh sửa không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.CanConfirm">
            <summary>
            Có thể xác nhận không (chỉ check status)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.CanTransfer">
            <summary>
            Có thể chuyển tiền không (chỉ check status)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.CanCancel">
            <summary>
            Có thể hủy không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.HasConfirmPermission">
            <summary>
            User có quyền duyệt đối soát không (Reconciliation.Confirm hoặc Founder)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.HasTransferPermission">
            <summary>
            User có quyền cập nhật chuyển tiền đối soát không (Reconciliation.Transfer hoặc Founder)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.CanConfirmWithPermission">
            <summary>
            Có thể xác nhận không (kết hợp cả status và quyền)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationItem.CanTransferWithPermission">
            <summary>
            Có thể chuyển tiền không (kết hợp cả status và quyền)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem">
            <summary>
            Item đơn hàng trong đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem.ReconciliationId">
            <summary>
            ID đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem.OrderId">
            <summary>
            ID đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem.OrderCode">
            <summary>
            Mã đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem.PartnerCode">
            <summary>
            Mã đối tác
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem.CodAmount">
            <summary>
            Tiền COD
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem.FeeAmount">
            <summary>
            Phí trừ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem.NetAmount">
            <summary>
            Tiền thực tế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem.DeliveredDate">
            <summary>
            Ngày giao hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem.CodCollectedDate">
            <summary>
            Ngày thu COD
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem.ChargeWeight">
            <summary>
            Trọng lượng tính cước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem.ShippingFee">
            <summary>
            Cước vận chuyển
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem.DeliveryAddress">
            <summary>
            Địa chỉ giao hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem.ReceiverName">
            <summary>
            Tên người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem.ReceiverPhone">
            <summary>
            Số điện thoại người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ReconciliationOrderItem.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.RouteItem">
            <summary>
            Đối tượng đại diện cho tuyến đường.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.RouteItem.Name">
            <summary>
            Tên tuyến.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.RouteItem.Description">
            <summary>
            Mô tả tuyến.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.RouteItem.DistanceMin">
            <summary>
            Khoảng cách tối thiểu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.RouteItem.DistanceMax">
            <summary>
            Khoảng cách tối đa.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.RouteItem.DisplayOrder">
            <summary>
            Thứ tự hiển thị.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.Id">
            <summary>
            ID giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.Description">
            <summary>
            Mô tả giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.Note">
            <summary>
            Ghi chú cho giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.Amount">
            <summary>
            Số tiền giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.CashAmount">
            <summary>
            Số tiền mặt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.TransferAmount">
            <summary>
            Số tiền chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.TransactionType">
            <summary>
            Loại giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.TransactionTypeName">
            <summary>
            Tên loại giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.TransactionDirection">
            <summary>
            Hướng giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.TransactionDirectionName">
            <summary>
            Tên hướng giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.TransactionDate">
            <summary>
            Ngày giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.WalletId">
            <summary>
            ID ví nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.WalletOwnerName">
            <summary>
            Tên chủ ví nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.RelatedWalletId">
            <summary>
            ID ví đích (nullable)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.RelatedWalletOwnerName">
            <summary>
            Tên chủ ví đích
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.OrderCount">
            <summary>
            Số lượng đơn hàng liên kết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.OrderCodes">
            <summary>
            Danh sách mã đơn hàng (để hiển thị preview)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.TotalCodAmount">
            <summary>
            Tổng tiền COD từ các đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.TotalSourceFeeAmount">
            <summary>
            Tổng cước nguồn từ các đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.TotalDestFeeAmount">
            <summary>
            Tổng cước đích từ các đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.Status">
            <summary>
            Trạng thái giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.StatusName">
            <summary>
            Tên trạng thái giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.FormattedAmount">
            <summary>
            Số tiền hiển thị với dấu (+/-) để phân biệt thu/chi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.FormattedAmountWithCurrency">
            <summary>
            Số tiền hiển thị với định dạng tiền tệ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.AmountColor">
            <summary>
            Màu sắc để hiển thị (xanh cho thu, đỏ cho chi)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.TransactionIcon">
            <summary>
            Icon để hiển thị loại giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.FromUserName">
            <summary>
            Tên người gửi/nhận tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.FromUserPhone">
            <summary>
            Số điện thoại người gửi/nhận tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.FromUserFullName">
            <summary>
            Tên đầy đủ người gửi/nhận tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.BalanceAfterTransaction">
            <summary>
            Số dư ví sau giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.FormattedBalance">
            <summary>
            Số dư ví hiển thị với định dạng tiền tệ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.IsIncome">
            <summary>
            Có phải giao dịch thu tiền không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.IsOutcome">
            <summary>
            Có phải giao dịch chi tiền không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionItem.ShortDescription">
            <summary>
            Mô tả ngắn gọn cho giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.TransactionId">
            <summary>
            ID giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.OrderId">
            <summary>
            ID đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.OrderCode">
            <summary>
            Mã đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.PartnerCode">
            <summary>
            Mã đối tác
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.OrderNote">
            <summary>
            Ghi chú đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.CodAmount">
            <summary>
            Số tiền COD trong giao dịch này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.SourceFeeAmount">
            <summary>
            Cước nguồn trong giao dịch này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.DestFeeAmount">
            <summary>
            Cước đích trong giao dịch này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.TotalAmount">
            <summary>
            Tổng tiền từ đơn hàng này trong giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.SenderName">
            <summary>
            Tên người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.SenderAddress">
            <summary>
            Địa chỉ người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.SenderPhone">
            <summary>
            Số điện thoại người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.ReceiverName">
            <summary>
            Tên người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.ReceiverAddress">
            <summary>
            Địa chỉ người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.ReceiverPhone">
            <summary>
            Số điện thoại người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.ChargeWeight">
            <summary>
            Trọng lượng tính cước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.OrderCodAmount">
            <summary>
            Tổng tiền COD của đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.OrderFee">
            <summary>
            Cước chính của đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.OrderTotalFee">
            <summary>
            Tổng cước của đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.PayFeeType">
            <summary>
            Loại thanh toán cước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.PayFeeTypeName">
            <summary>
            Tên loại thanh toán cước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.OrderStatus">
            <summary>
            Trạng thái đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.OrderStatusName">
            <summary>
            Tên trạng thái đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.OrderCreatedTime">
            <summary>
            Ngày tạo đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.TransactionOrderItem.OrderUpdatedTime">
            <summary>
            Ngày cập nhật đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.WalletItem.Balance">
            <summary>
            Số dư hiện tại
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.BankItem">
            <summary>
            Item cho hiển thị danh sách ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.BankItem.FullName">
            <summary>
            Tên đầy đủ ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.BankItem.BrandName">
            <summary>
            Tên thương hiệu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.BankItem.BankCode">
            <summary>
            Mã ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.BankItem.DisplayOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.BankItem.CreatedBy">
            <summary>
            Người tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.BankItem.UpdatedBy">
            <summary>
            Người cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.BankItem.CreatedTime">
            <summary>
            Thời gian tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.BankItem.UpdatedTime">
            <summary>
            Thời gian cập nhật
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.BankOptionItem">
            <summary>
            Model cho option select ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.BankOptionItem.Id">
            <summary>
            ID ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.BankOptionItem.BrandName">
            <summary>
            Tên thương hiệu ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.BankOptionItem.FullName">
            <summary>
            Tên đầy đủ ngân hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem">
            <summary>
            DTO hiển thị danh sách phiếu đối soát khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.Code">
            <summary>
            Mã phiếu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.CustomerPhone">
            <summary>
            Số điện thoại khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.Type">
            <summary>
            Loại phiếu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.TypeName">
            <summary>
            Tên loại phiếu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.Status">
            <summary>
            Trạng thái
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.StatusName">
            <summary>
            Tên trạng thái
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.TotalCodAmount">
            <summary>
            Tổng tiền thu hộ COD
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.TotalFeeAmount">
            <summary>
            Tổng phí vận chuyển
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.FinalAmount">
            <summary>
            Số tiền cuối cùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.ReturnFeeDebtOffsetAmount">
            <summary>Tổng nợ cước đơn hoàn đã cấn vào phiếu (Ví v2 E13 — V-37).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.OrderCount">
            <summary>
            Số lượng đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.CreatedByUserName">
            <summary>
            Người tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.CreatedTime">
            <summary>
            Thời gian tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.ApprovedByUsername">
            <summary>
            Người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.ApprovedTime">
            <summary>
            Thời gian duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.CompletedByUsername">
            <summary>
            Người hoàn thành
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.CompletedTime">
            <summary>
            Thời gian hoàn thành
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.InternalNote">
            <summary>
            Ghi chú nội bộ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.PaymentMethod">
            <summary>
            Phương thức thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.TransactionCode">
            <summary>
            Mã giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.ProofImageUrl">
            <summary>
            Link ảnh chứng từ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.CustomerBankAccountId">
            <summary>
            ID tài khoản ngân hàng khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.BankAccountNumber">
            <summary>
            Số tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.BankAccountHolderName">
            <summary>
            Tên chủ tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.BankCode">
            <summary>
            Mã ngân hàng (VCB, TCB, VTB, etc.)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.BankName">
            <summary>
            Tên ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.BankBranchName">
            <summary>
            Tên chi nhánh ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.BankBranchAddress">
            <summary>
            Địa chỉ chi nhánh ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.BankAccountDisplay">
            <summary>
            Thông tin hiển thị đầy đủ của tài khoản nhận tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.HasTaxInvoice">
            <summary>
            Phiếu có hóa đơn hay không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.TaxInvoiceStatus">
            <summary>
            Trạng thái hóa đơn (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipItem.TaxInvoiceStatusName">
            <summary>
            Tên trạng thái hóa đơn
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipDetailItem">
            <summary>
            DTO chi tiết đơn hàng trong phiếu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipDetailItem.ReturnFeeDebtOffsetAmount">
            <summary>Nợ cước đơn hoàn cấn vào đơn này (Ví v2 E13 — V-37); 0 = không cấn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipDetailItem.FranchiseExcluded">
            <summary>
            Danh sách đơn có thể đối soát (V-35): đơn do bưu cục nhượng quyền bán mà không phải COD giao thành công — cước khách trả thẳng
            bưu cục, không đối soát với LADA; lập phiếu sẽ bị từ chối nên màn không cho chọn.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationLogItem">
            <summary>
            DTO lịch sử thao tác
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem">
            <summary>
            DTO item cho tổng hợp khách hàng cần tạo hóa đơn thanh toán chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.CustomerPhone">
            <summary>
            Số điện thoại khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.CustomerCode">
            <summary>
            Mã khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.CustomerEmail">
            <summary>
            Email khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.CustomerAddress">
            <summary>
            Địa chỉ khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.PendingOrderCount">
            <summary>
            Số đơn hàng chưa thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.CodOrderCount">
            <summary>
            Số đơn COD chưa đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.BankTransferOrderCount">
            <summary>
            Số đơn chuyển khoản chưa thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.TotalCodAmount">
            <summary>
            Tổng tiền COD chưa đối soát (VNĐ)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.TotalCodFee">
            <summary>
            Tổng cước của các đơn COD (VNĐ)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.TotalTransferFee">
            <summary>
            Tổng tiền chuyển khoản chưa thanh toán (VNĐ)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.EstimatedNetAmount">
            <summary>
            Số tiền ước tính cần trả khách = TotalCodAmount - TotalCodFee - TotalTransferFee (VNĐ)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.EstimatedNetAmountFormatted">
            <summary>
            Số tiền ước tính đã format (VD: "25,500,000 ₫")
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.OldestOrderDate">
            <summary>
            Ngày đơn hàng cũ nhất chưa thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.LatestOrderDate">
            <summary>
            Ngày đơn hàng mới nhất chưa thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.DaysFromOldest">
            <summary>
            Số ngày từ đơn hàng cũ nhất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.PriorityLevel">
            <summary>
            Mức độ ưu tiên dựa trên số ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.ManagerId">
            <summary>
            ID người quản lý khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.ManagerName">
            <summary>
            Tên người quản lý khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.BankAccountNumber">
            <summary>
            Thông tin ngân hàng khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.BankAccountHolderName">
            <summary>
            Tên chủ tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.BankName">
            <summary>
            Tên ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerTransferPaymentSummaryItem.CanCreateBill">
            <summary>
            Có thể tạo hóa đơn không (dựa trên quyền và số đơn hàng)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem">
            <summary>
            Item hiển thị thông tin danh mục chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem.Code">
            <summary>
            Tên danh mục chi phí
            </summary>
            <summary>
            Mã danh mục chi phí chuẩn hóa theo TT133
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem.Description">
            <summary>
            Mô tả danh mục chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem.DisplayOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem.ParentId">
            <summary>
            ID của danh mục cha (null nếu là danh mục gốc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem.ParentName">
            <summary>
            Tên danh mục cha
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem.ApprovedBy">
            <summary>
            ID người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem.ApprovedByUserName">
            <summary>
            Tên người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem.AccountCode">
            <summary>
            Mã tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem.Children">
            <summary>
            Danh sách danh mục con
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem.Level">
            <summary>
            Cấp độ trong cây phân cấp (0 = gốc, 1 = con, 2 = cháu, ...)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem.IsDeleted">
            <summary>
            Trạng thái xóa
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.IncomeCategoryItem">
            <summary>
            Item hiển thị thông tin danh mục doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.IncomeCategoryItem.Name">
            <summary>
            Tên danh mục doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.IncomeCategoryItem.Description">
            <summary>
            Mô tả danh mục doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.IncomeCategoryItem.DisplayOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.IncomeCategoryItem.ParentId">
            <summary>
            ID của danh mục cha (null nếu là danh mục gốc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.IncomeCategoryItem.ParentName">
            <summary>
            Tên danh mục cha
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.IncomeCategoryItem.ApprovedBy">
            <summary>
            ID người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.IncomeCategoryItem.ApprovedByUserName">
            <summary>
            Tên người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.IncomeCategoryItem.Children">
            <summary>
            Danh sách danh mục con
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.IncomeCategoryItem.Level">
            <summary>
            Cấp độ trong cây phân cấp (0 = gốc, 1 = con, 2 = cháu, ...)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.IncomeCategoryItem.IsDeleted">
            <summary>
            Trạng thái xóa
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem">
            <summary>
            Item hóa đơn thuế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.CustomerReconciliationSlipId">
            <summary>
            ID phiếu đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.ReconciliationSlipCode">
            <summary>
            Mã phiếu đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.VatInfoId">
            <summary>
            ID thông tin VAT
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.TaxCode">
            <summary>
            Mã số thuế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.CompanyName">
            <summary>
            Tên công ty
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.Address">
            <summary>
            Địa chỉ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.InvoiceEmail">
            <summary>
            Email nhận hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.InvoiceNumber">
            <summary>
            Số hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.InvoiceDate">
            <summary>
            Ngày xuất hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.Status">
            <summary>
            Trạng thái
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.StatusName">
            <summary>
            Tên trạng thái
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.TotalAmount">
            <summary>
            Tổng tiền trước thuế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.VatAmount">
            <summary>
            Tiền thuế VAT
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.TotalAmountIncludingVat">
            <summary>
            Tổng tiền sau thuế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.VatRate">
            <summary>
            Thuế suất (%)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.PdfUrl">
            <summary>
            URL file PDF hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.CanUpdate">
            <summary>
            User có quyền cập nhật trạng thái không (Founder hoặc TaxInvoice.Update)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TaxInvoiceItem.CanDelete">
            <summary>
            Có thể xóa không (chỉ khi NotIssued hoặc Draft)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem">
            <summary>
            DTO item cho việc xuất Excel thông tin đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.OrderId">
            <summary>
            ID đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.OrderCode">
            <summary>
            Mã đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.PartnerCode">
            <summary>
            Mã đối tác
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.Note">
            <summary>
            Ghi chú đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.SaleId">
            <summary>
            ID Sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.SaleName">
            <summary>
            Tên Sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.SenderName">
            <summary>
            Tên người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.SenderAddress">
            <summary>
            Địa chỉ người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.SenderPhone">
            <summary>
            Số điện thoại người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.ReceiverName">
            <summary>
            Tên người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.ReceiverAddress">
            <summary>
            Địa chỉ người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.ReceiverPhone">
            <summary>
            Số điện thoại người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.OrderStatus">
            <summary>
            Trạng thái đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.OrderPhysicalStatus">
            <summary>
            Trạng thái vật lý đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.ChargeWeight">
            <summary>
            Khối lượng tính cước (gram)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.ChargeWeightKg">
            <summary>
            Khối lượng tính cước (kg) - hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.Fee">
            <summary>
            Cước phí vận chuyển
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.FeeFormatted">
            <summary>
            Cước phí vận chuyển (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.CodFee">
            <summary>
            Phí COD
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.CodFeeFormatted">
            <summary>
            Phí COD (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.PickupSubFee">
            <summary>
            Phí lấy hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.PickupSubFeeFormatted">
            <summary>
            Phí lấy hàng (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.DeliverySubFee">
            <summary>
            Phí giao hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.DeliverySubFeeFormatted">
            <summary>
            Phí giao hàng (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.Discount">
            <summary>
            Giảm giá
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.DiscountFormatted">
            <summary>
            Giảm giá (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.TotalFee">
            <summary>
            Tổng cước phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.TotalFeeFormatted">
            <summary>
            Tổng cước phí (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.PayFeeType">
            <summary>
            Loại thanh toán cước phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.CollectAmount">
            <summary>
            Số tiền thu hộ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.CollectAmountFormatted">
            <summary>
            Số tiền thu hộ (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.CodIncludeFee">
            <summary>
            COD có bao gồm cước phí không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.CodStage">
            <summary>
            Trạng thái thu COD
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.TransferFeeAmount">
            <summary>
            Số tiền TransferFee
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.TransferFeeAmountFormatted">
            <summary>
            Số tiền TransferFee (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.TransferFeeStage">
            <summary>
            Trạng thái TransferFee
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.SourceFee">
            <summary>
            Cước phí nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.SourceFeeFormatted">
            <summary>
            Cước phí nguồn (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.SourceFeeStage">
            <summary>
            Trạng thái cước phí nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.DestFee">
            <summary>
            Cước phí đích
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.DestFeeFormatted">
            <summary>
            Cước phí đích (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.DestFeeStage">
            <summary>
            Trạng thái cước phí đích
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.ReconciliationAmount">
            <summary>
            Số tiền đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.ReconciliationAmountFormatted">
            <summary>
            Số tiền đối soát (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.OrderCreatedTime">
            <summary>
            Thời gian tạo đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.OrderCreatedTimeFormatted">
            <summary>
            Thời gian tạo đơn hàng (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.PickupTime">
            <summary>
            Thời gian lấy hàng thành công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.PickupTimeFormatted">
            <summary>
            Thời gian lấy hàng thành công (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.DeliveryTime">
            <summary>
            Thời gian giao hàng thành công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.DeliveryTimeFormatted">
            <summary>
            Thời gian giao hàng thành công (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.TotalPackages">
            <summary>
            Tổng số kiện
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.TotalWeight">
            <summary>
            Tổng khối lượng (gram)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.TotalWeightKg">
            <summary>
            Tổng khối lượng (kg) - hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem.PackageContent">
            <summary>
            Nội dung hàng hóa
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem">
            <summary>
            DTO item cho hiển thị danh sách hóa đơn thanh toán chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.Code">
            <summary>
            Mã hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.CustomerPhone">
            <summary>
            Số điện thoại khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.FromDate">
            <summary>
            Từ ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.ToDate">
            <summary>
            Đến ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.TotalAmount">
            <summary>
            Tổng tiền TransferFee
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.TotalAmountFormatted">
            <summary>
            Tổng tiền TransferFee (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.OrderCount">
            <summary>
            Số đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.Status">
            <summary>
            Trạng thái hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.StatusName">
            <summary>
            Tên trạng thái hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.Priority">
            <summary>
            Mức độ ưu tiên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.PriorityName">
            <summary>
            Tên mức độ ưu tiên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.CreatedByUserName">
            <summary>
            Người tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.CreatedTime">
            <summary>
            Thời gian tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.ApprovedBy">
            <summary>
            ID người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.ApprovedByUsername">
            <summary>
            Người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.ApprovedDate">
            <summary>
            Ngày duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.TransferInfo">
            <summary>
            Thông tin chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.CompanyBankAccountNumber">
            <summary>
            Số tài khoản ngân hàng công ty/đại lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.CompanyBankAccountHolderName">
            <summary>
            Tên chủ tài khoản công ty/đại lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.CompanyBankName">
            <summary>
            Tên ngân hàng công ty/đại lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.CanEdit">
            <summary>
            Có thể chỉnh sửa không (chỉ người tạo và trạng thái Draft)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.CanCancel">
            <summary>
            Có thể hủy không (chỉ người tạo và trạng thái Draft)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillItem.CanApprove">
            <summary>
            Có thể duyệt không (role Accountant và trạng thái Draft)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem">
            <summary>
            DTO item cho đơn hàng trong hóa đơn thanh toán chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.TransferPaymentBillId">
            <summary>
            ID hóa đơn thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.OrderId">
            <summary>
            ID đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.OrderCode">
            <summary>
            Mã đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.TransferFeeAmount">
            <summary>
            Số tiền TransferFee của đơn hàng này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.TransferFeeAmountFormatted">
            <summary>
            Số tiền TransferFee (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.Note">
            <summary>
            Ghi chú riêng cho đơn hàng này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.SenderName">
            <summary>
            Tên người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.SenderAddress">
            <summary>
            Địa chỉ người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.SenderPhone">
            <summary>
            Số điện thoại người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.ReceiverName">
            <summary>
            Tên người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.ReceiverAddress">
            <summary>
            Địa chỉ người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.ReceiverPhone">
            <summary>
            Số điện thoại người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.OrderCreatedTime">
            <summary>
            Ngày tạo đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.Status">
            <summary>
            Trạng thái đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.PhysicalStatus">
            <summary>
            Trạng thái vật lý đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.StatusStr">
            <summary>
            Trạng thái đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.PhysicalStatusStr">
            <summary>
            Trạng thái vật lý đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem.ProductInfo">
            <summary>
            Thông tin sản phẩm (gộp các package thành chuỗi)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.UserBankAccountItem">
            <summary>
            Item cho tài khoản ngân hàng người dùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.UserBankAccountItem.UserId">
            <summary>
            ID người dùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.UserBankAccountItem.UserName">
            <summary>
            Tên người dùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.UserBankAccountItem.AccountNumber">
            <summary>
            Số tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.UserBankAccountItem.AccountHolderName">
            <summary>
            Tên chủ tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.UserBankAccountItem.BankId">
            <summary>
            ID ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.UserBankAccountItem.BankCode">
            <summary>
            Mã ngân hàng (VCB, TCB, VTB, etc.)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.UserBankAccountItem.BankName">
            <summary>
            Tên ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.UserBankAccountItem.IsDefault">
            <summary>
            Có phải tài khoản mặc định không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.UserBankAccountItem.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.UserBankAccountItem.ExpenseCount">
            <summary>
            Số lượng chi phí sử dụng tài khoản này
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem">
            <summary>
            Item hiển thị thông tin hóa đơn VAT trong danh sách
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.TemplateCode">
            <summary>
            Ký hiệu mẫu số (khmshdon)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.InvoiceSymbol">
            <summary>
            Ký hiệu hóa đơn (khhdon)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.InvoiceNumber">
            <summary>
            Số hóa đơn (shdon)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.IssueDate">
            <summary>
            Ngày lập (tdlap)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.SellerTaxCode">
            <summary>
            MST người bán (nmmst)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.SellerName">
            <summary>
            Tên người bán (nmten)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.BuyerTaxCode">
            <summary>
            MST người mua (nbmst)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.BuyerName">
            <summary>
            Tên người mua (nbten)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.AmountBeforeTax">
            <summary>
            Tổng tiền hàng (tgtcthue)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.TaxAmount">
            <summary>
            Tổng tiền thuế (tgtthue)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.TotalAmount">
            <summary>
            Tổng thanh toán (tgtttbso)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.Currency">
            <summary>
            Đơn vị tiền (dvtte)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.Status">
            <summary>
            Tình trạng (tthai)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.Note">
            <summary>
            Ghi chú (gchu)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.SyncTime">
            <summary>
            Thời gian đồng bộ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.InvoiceDirection">
            <summary>
            Chiều hóa đơn: 1 = Bán ra, 2 = Mua vào
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.InvoiceDirectionName">
            <summary>
            Tên chiều hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.InvoiceCheckResult">
            <summary>
            Kết quả kiểm tra hóa đơn (ttxly)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.InvoiceCheckResultName">
            <summary>
            Tên kết quả kiểm tra (ttxly)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.VatInvoiceItem.StatusName">
            <summary>
            Tên trạng thái hóa đơn (tthai)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.FuelCards.DriverFuelCardItem">
            <summary>
            DTO trả về thông tin thẻ xăng dầu cho Driver App
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.FuelCards.DriverFuelCardItem.HandoverId">
            <summary>
            ID của bản ghi bàn giao hiện tại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.FuelCards.DriverFuelCardItem.HandoverStatus">
            <summary>
            Trạng thái bàn giao (PendingAccept / Received / Returned)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.FuelCards.FuelCardTransactionItem.HasRefill">
            <summary>
            Giao dịch đã được đổ dầu hay chưa (có FuelRefillId)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.FuelCards.FuelRefillItem.ClampedQuotaUnitPrice">
            <summary>
            Đơn giá khoán đã được clamp trong khoảng [MinQuotaUnitPrice, MaxQuotaUnitPrice]
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.FuelCards.FuelRefillItem.FuelIncomeAmount">
            <summary>
            Thu nhập dầu = DifferenceLiters × ClampedQuotaUnitPrice
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem">
            <summary>
            Chi tiết công từng ngày của nhân viên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem.UserId">
            <summary>
            ID nhân viên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem.UserName">
            <summary>
            Tên đăng nhập
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem.FullName">
            <summary>
            Họ và tên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem.WorkDate">
            <summary>
            Ngày làm việc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem.CheckInTime">
            <summary>
            Thời gian check-in (sớm nhất trong ngày)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem.CheckOutTime">
            <summary>
            Thời gian check-out (muộn nhất trong ngày)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem.WorkingHours">
            <summary>
            Số giờ làm việc trong ngày (có 1 số sau dấu phẩy)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem.WorkCredit">
            <summary>
            Số công trong ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem.OvertimeKips">
            <summary>
            Số kíp trong ngày — tổng kíp của TỪNG CA tính trên giờ thô, cùng công thức với bảng lương
            (<c>AttendanceFormulas.CalculateOvertimeKips</c>). Không suy được từ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem.WorkingHours"/>
            vì cột đó đã gộp theo ngày và làm tròn 0,1h.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem.StartOdo">
            <summary>
            Số ODO đầu ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem.EndOdo">
            <summary>
            Số ODO cuối ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem.TotalOdo">
            <summary>
            Tổng ODO chạy trong ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem.Month">
            <summary>
            Tháng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceDetailItem.Year">
            <summary>
            Năm
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceItem.CheckInOdo">
            <summary>
            Số ODO khi check-in
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceItem.CheckOutOdo">
            <summary>
            Số ODO khi check-out
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceItem.CheckInMedias">
            <summary>
            Danh sách ảnh check-in
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceItem.CheckOutMedias">
            <summary>
            Danh sách ảnh check-out
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceMediaItem">
            <summary>
            Đối tượng đại diện cho media của attendance
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceSummaryItem">
            <summary>
            Tổng hợp số công của nhân viên theo tháng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceSummaryItem.UserId">
            <summary>
            ID nhân viên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceSummaryItem.UserName">
            <summary>
            Tên đăng nhập
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceSummaryItem.FullName">
            <summary>
            Họ và tên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceSummaryItem.TotalWorkDays">
            <summary>
            Tổng số ngày đi làm
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceSummaryItem.TotalWorkingHours">
            <summary>
            Tổng số giờ làm việc (có 1 số sau dấu phẩy)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceSummaryItem.TotalWorkCredits">
            <summary>
            Tổng số công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceSummaryItem.Month">
            <summary>
            Tháng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.AttendanceSummaryItem.Year">
            <summary>
            Năm
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.FullName">
            <summary>
            Họ và tên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.PhoneNumber">
            <summary>
            Số điện thoại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.Address">
            <summary>
            Địa chỉ hiện tại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.Introduction">
            <summary>
            Giới thiệu về bản thân
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.Status">
            <summary>
            Trạng thái hồ sơ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.StatusContent">
            <summary>
            Nội dung đánh dấu trạng thái
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.AppointmentTime">
            <summary>
            Thời gian hẹn phỏng vấn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.CreatedTime">
            <summary>
            Thời gian tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.RecruiterId">
            <summary>
            ID người phụ trách tuyển hồ sơ này (trống nếu chưa ai nhận)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.RecruiterName">
            <summary>
            Tên người phụ trách tuyển — service tra theo <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.RecruiterId"/> cho từng trang kết quả
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.OnboardedTime">
            <summary>
            Thời điểm hồ sơ chuyển sang nhận việc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.CvFileName">
            <summary>
            Tên file CV
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.CvFileUrl">
            <summary>
            URL để truy cập CV
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.CvFileSize">
            <summary>
            Kích thước file CV (bytes)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.CvFileType">
            <summary>
            Loại file CV
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.CvUploadedTime">
            <summary>
            Thời gian upload CV
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem.HasCv">
            <summary>
            Có CV hay không
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DepositTrackingItem">
            <summary>
            Item hiển thị dòng theo dõi cọc trách nhiệm của 1 lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DepositTrackingItem.UserId">
            <summary>
            ID lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DepositTrackingItem.UserName">
            <summary>
            Tên đăng nhập
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DepositTrackingItem.FullName">
            <summary>
            Họ và tên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DepositTrackingItem.PhoneNumber">
            <summary>
            Số điện thoại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DepositTrackingItem.AgencyId">
            <summary>
            ID chi nhánh quản lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DepositTrackingItem.AgencyName">
            <summary>
            Tên chi nhánh quản lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DepositTrackingItem.DepositLimit">
            <summary>
            Hạn mức cọc yêu cầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DepositTrackingItem.DepositPaid">
            <summary>
            Cọc đã đóng lũy kế (đã được kế toán xác nhận nhận tiền)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DepositTrackingItem.DepositMonthly">
            <summary>
            Mức trừ cọc qua lương mỗi tháng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DepositTrackingItem.DepositPending">
            <summary>
            Cọc đang chờ xác nhận (Income Pending, chưa cộng vào Đã đóng)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DepositTrackingItem.Remaining">
            <summary>
            Số tiền còn thiếu = max(0, Hạn mức - Đã đóng)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DepositTrackingItem.Status">
            <summary>
            Trạng thái: "Đủ" | "Thiếu" | "Chưa nộp"
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DepositTrackingItem.LastPaymentTime">
            <summary>
            Thời điểm nộp gần nhất
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DriverEvaluationItem">
            <summary>
            Item hiển thị Bảng đánh giá lái xe
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DriverEvaluationDetailItem">
            <summary>
            Item chi tiết điểm đánh giá
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.DriverSalaryScaleItem">
            <summary>
            Item hiển thị Bảng tra mức lương
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.EmployeePayrollRecordItem">
            <summary>
            Item hiển thị Phiếu lương (Snapshot)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.EmployeePayrollRecordItem.InsuranceBase">
            <summary>Mức khai đóng BHXH bắt buộc (snapshot)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.EmployeePayrollRecordItem.SocialInsuranceDeduction">
            <summary>Khấu trừ thực tế = InsuranceBase × 10.5%</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.EmployeePayrollRecordItem.SalaryAdvance">
            <summary>Tiền tạm ứng lương cấn trừ trong kỳ (snapshot)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.EmployeePayrollRecordItem.ResponsibilityDeposit">
            <summary>Tiền cọc trách nhiệm cấn trừ trong kỳ (snapshot)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.EmployeePayrollRecordItem.IsExpensePaid">
            <summary>Expense liên kết đã thanh toán (Paid) → không cho sửa phiếu lương</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.EmployeeSalaryConfigItem">
            <summary>
            Item hiển thị Cấu hình lương nhân viên
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.EvaluationCriteriaGroupItem">
            <summary>
            Item hiển thị Nhóm tiêu chí đánh giá
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.EvaluationCriteriaItem">
            <summary>
            Item hiển thị Tiêu chí đánh giá
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.Title">
            <summary>
            Tiêu đề bài viết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.CreatedTime">
            <summary>
            Thời gian tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.CreatedBy">
            <summary>
            Thời gian cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.Description">
            <summary>
            Mô tả công việc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.ExperienceRequirements">
            <summary>
            Yêu cầu kinh nghiệm (ví dụ: 2 năm c++)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.WorkingAddress">
            <summary>
            Địa chỉ làm việc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.JobType">
            <summary>
            Loại hình công việc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.StartDate">
            <summary>
            Ngày bắt đầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.EndDate">
            <summary>
            Ngày kết thúc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.Email">
            <summary>
            Email tiếp nhận CV
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.Agency">
            <summary>
            Phòng ban
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.AgencyId">
            <summary>
            Phòng ban
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.Position">
            <summary>
            Vị trí ứng tuyển
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.MinSalary">
            <summary>
            Mức lương tối thiểu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.MaxSalary">
            <summary>
            Mức lương tối đa
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.JobStatus">
            <summary>
            Trạng thái tin tuyển dụng: mở / đóng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.JobPostItem.JobStatusStr">
            <summary>
            Trạng thái tin tuyển dụng: mở / đóng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.LeaveRequestItem">
            <summary>
            Item hiển thị phiếu nghỉ phép
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.LeaveBalanceItem">
            <summary>
            Item hiển thị quỹ phép nhân viên
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.LeaveTypeItem">
            <summary>
            Item hiển thị loại nghỉ phép
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.HolidayItem">
            <summary>
            Item hiển thị ngày lễ
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.MyPayslipStatusItem">
            <summary>
            Trạng thái phiếu lương gần nhất của người đang đăng nhập — cho thẻ "Phiếu lương tháng M" trên đầu Bảng tin
            (docs/plan-bang-tin-noi-bo.md §3.8). CỐ Ý không có số tiền: thẻ nằm trên trang tin, chỉ cần kỳ + trạng thái.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.MyPayslipStatusItem.HasPayslip">
            <summary>Có ít nhất một phiếu đã gửi cho người này (khác Bản nháp). <c>false</c> → các trường còn lại trống, thẻ ẩn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.MyPayslipStatusItem.Status">
            <summary>Trạng thái hiệu lực: "NLĐ đã xác nhận" mà phiếu chi đã chi thì là "Đã thanh toán" — như trang phiếu lương.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.PayrollAdjustmentItem">
            <summary>
            Item hiển thị Thưởng/Phạt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.SalaryOtherDeductionItem.DeductionType">
            <summary>0 = Fixed, 1 = Percentage</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.SalaryOtherDeductionItem.Value">
            <summary>Số tiền hoặc % nhập vào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.SalaryOtherDeductionItem.Amount">
            <summary>Số tiền đã tính (snapshot)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.TeamMemberRevenueItem">
            <summary>
            Chi tiết doanh số từng thành viên trong team (dùng cho TeamLeader/BranchManager)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem">
            <summary>
            Lớp đại diện cho thông tin nhân viên.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.Id">
            <summary>
            ID của nhân viên.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.UserName">
            <summary>
            Tên đăng nhập của nhân viên.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.FullName">
            <summary>
            Họ và tên của nhân viên.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.PhoneNumber">
            <summary>
            Số điện thoại của nhân viên.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.AgencyId">
            <summary>
            ID của đại lý mà nhân viên thuộc về.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.IsLocked">
            <summary>
            Trạng thái khóa của nhân viên.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.UserType">
            <summary>
            Loại người dùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.CreatedTime">
            <summary>
            Ngày tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.UpdatedTime">
            <summary>
            Ngày cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.AttendanceCode">
            <summary>
            Mã chấm công (khớp với mã máy chấm công vân tay khi import)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.ManagerId">
            <summary>
            ID người quản lý trực tiếp
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.ManagerName">
            <summary>
            Tên người quản lý trực tiếp
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.SalaryAdvance">
            <summary>
            Số tiền tạm ứng lương hiện tại trong tháng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.ResponsibilityDepositLimit">
            <summary>
            Tổng hạn mức cọc trách nhiệm yêu cầu của lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.ResponsibilityDepositPaid">
            <summary>
            Số tiền cọc trách nhiệm đã đóng lũy kế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.StaffItem.ResponsibilityDepositMonthly">
            <summary>
            Số tiền cọc trách nhiệm cấn trừ hàng tháng qua lương
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Identity.UserTrackItem">
            <summary>
            DTO trả về lịch sử thao tác người dùng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsResult">
            <summary>
            Kết quả thao tác bảng tin. <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsResult.IsNotFound"/> → HTTP 404 (cả khi bài có thật nhưng người gọi không được
            xem/sửa — không lộ tồn tại), <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsResult.IsForbidden"/> → HTTP 403 (vượt phạm vi đăng).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsResult.DraftVersion">
            <summary>Dấu bản đang sửa sau thao tác (lưu khối) — gửi lại khi bấm Đăng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsResult.DraftChanged">
            <summary>Bản đang sửa đã khác bản người đăng xem lúc mở màn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsResult.NotifiedCount">
            <summary>Số người được gửi chuông lúc đăng (0 khi không gửi).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsNavItem">
            <summary>Cờ cho giao diện (rule <c>quyen-hien-thi</c>) — <c>GET api/InternalNews/nav</c>, không đòi role.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsNavItem.ManageableAgencyIds">
            <summary>Đơn vị người chỉ có quyền mức đơn vị được chọn làm đối tượng (gồm con cháu).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAudienceItem.TargetName">
            <summary>Tên đích để hiển thị (tên nhóm / đơn vị / người); trống khi Tất cả.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAudienceItem.IsFranchiseOnly">
            <summary>
            Đích chỉ có ở phía nhượng quyền (bưu cục NQ, người của bưu cục NQ, "Mọi bưu cục nhượng quyền") — giao diện gỡ
            dòng này khi người soạn chuyển sang "Chỉ nhân viên LADA" (plan §6.6).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsFileItem">
            <summary>Tài liệu / video của bài — KHÔNG có đường dẫn trên đĩa.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsFileItem.Url">
            <summary>URL tuyệt đối trên <c>Media.Domain</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAdminListItem">
            <summary>Một dòng của màn quản trị bảng tin.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAdminListItem.AudienceScope">
            <summary>Chỉ nhân viên LADA / Gồm cả bưu cục nhượng quyền (plan §6.6).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAdminListItem.ReadCount">
            <summary>Số người đã mở bài.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAdminListItem.ScheduleCancelledBySystem">
            <summary>
            Lịch đăng bị job huỷ tự động — bài tới giờ mà không đăng được nên về nháp (plan bảng tin §3.13 mục 4, nợ BT-9).
            Tắt khi có người lưu bài lại.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAdminDetailItem">
            <summary>Chi tiết bài cho người soạn: thông tin + đối tượng + bản đang sửa + tệp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAdminDetailItem.DraftVersion">
            <summary>Dấu bản đang sửa — gửi lại ở <c>ExpectedDraftVersion</c> khi bấm Đăng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAdminDetailItem.HasUnpublishedChanges">
            <summary>Bài đang đăng và bản đang sửa khác ảnh chụp người đọc đang thấy (cần "Đăng lại").</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsBlockItem">
            <summary>Một khối để hiển thị (ảnh chụp đã đăng, hoặc bản xem trước đã lọc).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsFeedItem">
            <summary>Một bài trên bảng tin của người đọc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsFeedItem.IsPinned">
            <summary>Đang ghim (đã tính <c>PinnedUntil</c>).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsDetailItem">
            <summary>Chi tiết bài cho người đọc: thông tin + ảnh chụp khối + tệp mà khối tham chiếu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAgencyOptionItem.CanIncludeChildren">
            <summary>Được tick "gồm đơn vị con" cho đơn vị này (mức đơn vị: chỉ cây mình đứng tên quản lý).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAgencyOptionItem.IsFranchise">
            <summary>Bưu cục nhượng quyền — ẩn khi bài đang để "Chỉ nhân viên LADA" (plan §6.6).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAgencyTypeOptionItem">
            <summary>Một loại đơn vị chọn được ("Mọi bưu cục nhượng quyền", "Mọi chi nhánh của LADA"…) — Id = giá trị AgencyType.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAgencyTypeOptionItem.IsFranchise">
            <summary>Chỉ gồm người phía nhượng quyền — ẩn khi bài đang để "Chỉ nhân viên LADA".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsUserOptionItem.IsFranchise">
            <summary>Người của bưu cục nhượng quyền (theo đơn vị hoặc tài khoản NQ) — ẩn khi "Chỉ nhân viên LADA".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAudienceOptionsItem">
            <summary>
            Dữ liệu cho ô chọn đối tượng — ĐÃ lọc theo phạm vi người đăng, để màn soạn không phải mượn API tra cứu của miền
            khác (<c>Permission.Search</c>, <c>Agency.GetTree</c> — trưởng bưu cục không có các role đó, plan §7).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAudienceOptionsItem.CanPublishAll">
            <summary>Được chọn "Tất cả", nhóm quyền, loại đơn vị (mức công ty).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAudienceOptionsItem.CanChooseScope">
            <summary>
            Thấy lựa chọn phạm vi Chỉ nhân viên LADA / Gồm cả bưu cục nhượng quyền (plan §6.6, §5 câu 12c): mức công ty, và
            mức đơn vị có cả đơn vị LADA lẫn bưu cục NQ trong phạm vi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAudienceOptionsItem.ForcedScope">
            <summary>Phạm vi máy chủ tự đặt cho mọi bài của người này; <c>null</c> khi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAudienceOptionsItem.CanChooseScope"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAudienceOptionsItem.Permissions">
            <summary>Nhóm quyền đang hoạt động — rỗng với người chỉ có mức đơn vị.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAudienceOptionsItem.Agencies">
            <summary>Đơn vị chọn được: mọi đơn vị (mức công ty) hoặc cây đơn vị mình quản lý (mức đơn vị).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsAudienceOptionsItem.AgencyTypes">
            <summary>Loại đơn vị chọn được (mức công ty) — Id = giá trị AgencyType.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsRecipientCountResult">
            <summary>Ước tính người nhận chuông cho đối tượng đang chọn — đúng tập <c>ResolveRecipientsAsync</c> sẽ gửi.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsStatsItem">
            <summary>
            Thống kê đọc của một bài (plan §3.17, GĐ D). "Người nhắm" = đúng tập <c>ResolveRecipientsAsync</c> trả cho đối tượng
            HIỆN TẠI của bài (bỏ tài khoản xoá / đang khoá); đã đọc / đã xác nhận chỉ đếm trong tập đó.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsStatsItem.OutsideReadCount">
            <summary>Người đã đọc nhưng KHÔNG thuộc tập người nhắm hiện tại (đổi đối tượng, khoá / xoá tài khoản) — không vào tử số.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsStatsItem.Agencies">
            <summary>Theo đơn vị làm việc còn sống; nhiều người chưa đọc lên trước, "Không thuộc đơn vị" cuối.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsStatsAgencyItem.AgencyId">
            <summary><c>null</c> = không đơn vị / đơn vị đã xoá (dòng "Không thuộc đơn vị").</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsStatsPersonItem">
            <summary>Một người nhắm trong danh sách thống kê.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationItem">
            <summary>
            Một dòng tổng hợp quý/năm của một chỉ số (§7.1).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationItem.TargetValue">
            <summary>
            Mục tiêu kỳ tổng hợp trên đúng tập tháng ĐÃ CHỐT (§7.13): Σ mục tiêu với chỉ số cộng dồn;
            mục tiêu tháng cuối đã chốt với chỉ số ảnh chụp; bình quân gia quyền theo mẫu số với chỉ
            số tỷ lệ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationItem.ActualValue">
            <summary>
            Giá trị thực của kỳ, cộng từ snapshot <c>KpiResult</c> các tháng đã chốt — KHÔNG chạy lại
            provider (§7.13). Null khi chưa tính được: chưa tháng nào chốt, thiếu tử/mẫu, hoặc chỉ số
            nhập tay thiếu số.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationItem.Numerator">
            <summary>Σ tử số các tháng đã chốt — chỉ có với chỉ số dạng tỷ lệ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationItem.Denominator">
            <summary>Σ mẫu số các tháng đã chốt — chỉ có với chỉ số dạng tỷ lệ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationItem.IsRatio">
            <summary>Chỉ số dạng tỷ lệ/bình quân — giá trị kỳ = Σtử ÷ Σmẫu, không phải Σ%</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationItem.ClosedMonthCount">
            <summary>Số tháng có giao chỉ số này ĐÃ CHỐT — chỉ những tháng này góp vào con số</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationItem.UnclosedMonthCount">
            <summary>Số tháng có giao chỉ số này CHƯA CHỐT — không góp số, chỉ ghi nhãn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationItem.Weight">
            <summary>Trọng số bình quân các tháng ĐÃ CHỐT có giao chỉ số này</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationItem.AssignedMonthCount">
            <summary>Số tháng trong khoảng có giao chỉ số này — khác số tháng của kỳ là bộ chỉ tiêu không đều</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationItem.IsPointInTime">
            <summary>
            Chỉ số này là ảnh chụp tại một thời điểm (chỉ tiêu không cộng dồn) hay số cộng dồn cả kỳ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationItem.ActualFromDate">
            <summary>
            Đầu khoảng các tháng ĐÃ CHỐT thật sự góp vào con số của riêng chỉ số này (tháng đầu đã
            chốt; với ảnh chụp là tháng cuối đã chốt)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationItem.ActualToDate">
            <summary>Cuối khoảng các tháng đã chốt thật sự góp vào con số (tháng cuối đã chốt)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationItem.Note">
            <summary>Lý do dòng chưa có số, hoặc ghi chú về cách con số được tạo ra; null nghĩa là tính thẳng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationResult">
            <summary>
            Bảng tổng hợp KPI quý/năm của một chủ thể — cộng từ snapshot <c>KpiResult</c> các tháng ĐÃ
            CHỐT (§7.13), nên bất biến khi dữ liệu gốc đổi sau khi tháng đã chốt.
            </summary>
            <remarks>
            Snapshot điểm kỳ chỉ xảy ra một lần duy nhất: lúc bản đánh giá <c>KpiPeriodicReview</c> chuyển
            <c>Final</c> thì <c>TotalScore</c> được ghi vào <c>AggregatedScore</c> (§7.1) — và chỉ khi
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationResult.UnclosedMonthCount"/> = 0 và kỳ đã kết thúc.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationResult.PeriodIndex">
            <summary>Quý 1-4; bằng 0 khi kỳ năm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationResult.FromDate">
            <summary>Đầu kỳ tổng hợp (giờ Việt Nam)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationResult.ToDate">
            <summary>Cuối kỳ tổng hợp (giờ Việt Nam)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationResult.ClosedMonthCount">
            <summary>Số tháng trong kỳ có chỉ tiêu và ĐÃ CHỐT (đủ mọi chỉ tiêu của tháng)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationResult.UnclosedMonthCount">
            <summary>
            Số tháng trong kỳ có chỉ tiêu nhưng CÒN dòng chưa chốt — khác 0 thì bảng này chưa trọn kỳ,
            và <c>Finalize</c> bị chặn (§7.13, đóng KPI-11)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationResult.Note">
            <summary>Nhãn kiểu "còn N tháng chưa chốt: 08, 09" cho người đọc; null khi trọn kỳ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationResult.TotalWeight">
            <summary>Tổng trọng số bình quân — khác 100% là bộ chỉ tiêu các tháng không đồng nhất</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationResult.TotalScore">
            <summary>Điểm KPI tổng hợp của kỳ = Σ điểm trọng số các dòng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationResult.PendingCount">
            <summary>Số dòng chưa tính được số</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAssignmentItem">
            <summary>
            Item hiển thị chỉ tiêu KPI trong danh sách.
            SubjectName / AssignedByName do service gán tay sau khi map (SubjectId đa hình, không có navigation).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPolicyItem">
            <summary>Mẫu bậc thang thưởng KPI kèm các bậc</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPolicyTierItem">
            <summary>Một bậc: điểm trong [MinScore, MaxScore) ⇒ tiền</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusSettingItem">
            <summary>Dòng cấu hình thưởng của một nhân viên trong một tháng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusSettingItem.ScoreSubjectName">
            <summary>Tên chủ thể nguồn điểm — chính nhân viên, hoặc tên bưu cục/khu vực</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPreviewItem">
            <summary>
            Một dòng của bảng tính thử thưởng KPI — hiện tiền <b>sẽ</b> sinh, hoặc lý do không sinh.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPreviewItem.Score">
            <summary>Σ điểm trọng số các chỉ tiêu đã chốt của chủ thể nguồn điểm trong tháng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPreviewItem.ClosedMetricCount">
            <summary>Số chỉ tiêu đã chốt góp vào điểm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPreviewItem.TierLabel">
            <summary>Bậc trúng: nhãn "[50 – 80)" để đối soát</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPreviewItem.BonusAmount">
            <summary>Tiền sẽ sinh; 0 khi không đủ điều kiện</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPreviewItem.WillGenerate">
            <summary>Có sinh <c>PayrollAdjustment</c> hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPreviewItem.Reason">
            <summary>Lý do không sinh (kỳ thử nghiệm, công tắc tắt, mẫu tắt, chưa chốt kỳ, không trúng bậc…)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPreviewItem.IsTrial">
            <summary>Kỳ thử nghiệm — không bao giờ sinh tiền kể cả khi công tắc bật (§7.9)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPreviewResult">
            <summary>Bảng tính thử thưởng KPI của một kỳ tháng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPreviewResult.BonusEnabled">
            <summary>Công tắc <c>Kpi.EnableBonus</c> đang bật hay tắt</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPreviewResult.IsTrialPeriod">
            <summary>Kỳ này là kỳ thử nghiệm (chốt trước <c>Kpi.EffectiveFrom</c>)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPreviewResult.SettingCount">
            <summary>Số dòng cấu hình xét tới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPreviewResult.GeneratingCount">
            <summary>Số dòng thực sự sẽ sinh tiền</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPreviewResult.TotalAmount">
            <summary>Tổng tiền sẽ sinh</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusGenerateResult">
            <summary>Kết quả một lần chạy sinh thưởng thật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusGenerateResult.CreatedCount">
            <summary>Số adjustment tạo mới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusGenerateResult.UpdatedCount">
            <summary>Số adjustment cập nhật (chốt lại kỳ)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusGenerateResult.RemovedCount">
            <summary>Số adjustment gỡ đi vì dòng cấu hình không còn đủ điều kiện sinh tiền</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusGenerateResult.SkippedCount">
            <summary>Số dòng cấu hình không sinh tiền</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusGenerateResult.SkipReasons">
            <summary>Lý do không sinh của từng dòng bị bỏ qua — để nghiệp vụ biết vì sao không có tiền</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiMetricItem">
            <summary>
            Item hiển thị chỉ số KPI trong danh sách
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodicReviewItem">
            <summary>
            Một dòng danh sách đánh giá KPI định kỳ quý/năm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodicReviewItem.SubjectKindStr">
            <summary>Mô tả loại chủ thể để hiển thị thẳng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodicReviewItem.SubjectName">
            <summary>Tên nhân viên hoặc tên đơn vị được đánh giá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodicReviewItem.PeriodIndex">
            <summary>Quý 1-4; 0 khi kỳ năm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodicReviewItem.PeriodLabel">
            <summary>Nhãn kỳ để hiển thị: "Quý 3/2026" hoặc "Năm 2026"</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodicReviewItem.AggregatedScore">
            <summary>Điểm snapshot lúc chuyển Final; null khi còn Draft (màn hình hiện số sống)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressItem">
            <summary>
            Một dòng theo dõi chỉ tiêu trong kỳ — giá trị thực tính tại thời điểm gọi, chưa chốt kỳ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressItem.AssignmentId">
            <summary>Id chỉ tiêu đang theo dõi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressItem.MetricCode">
            <summary>Mã chỉ số, vd "driver.delivery-count"</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressItem.Unit">
            <summary>Đơn vị đo (đơn, đồng, %, KH, người...)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressItem.Direction">
            <summary>Chiều đánh giá — quyết định cách đọc % hoàn thành</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressItem.SubjectName">
            <summary>Tên nhân viên hoặc tên đơn vị được giao chỉ tiêu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressItem.ActualValue">
            <summary>Giá trị thực tính tại thời điểm gọi; null khi chưa tính được (chỉ số nhập tay hoặc lỗi nguồn)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressItem.CompletionPercent">
            <summary>% hoàn thành thô, chưa áp trần</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressItem.CappedCompletionPercent">
            <summary>% hoàn thành sau khi áp trần — số dùng để tính điểm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressItem.WeightedScore">
            <summary>Điểm đã nhân trọng số</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressItem.SourceType">
            <summary>Chỉ số lấy giá trị tự động hay nhập tay</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressItem.Note">
            <summary>
            Lý do dòng này chưa có số: nguồn dữ liệu lỗi, chỉ số nhập tay chưa nhập, chỉ tiêu không hợp lệ.
            Null nghĩa là dòng tính bình thường.
            </summary>
            <remarks>
            Không gộp lỗi thành giá trị 0: 0 đọc ra là "không đạt chỉ tiêu", còn lỗi nguồn là
            "chưa biết" — hai thứ khác nhau, và nhầm chúng ở GĐ E là mất tiền thưởng của người ta (§3.9d).
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressSubjectItem">
            <summary>
            Kết quả màn theo dõi KPI trong kỳ, gộp theo từng chủ thể.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressSubjectItem.TotalWeight">
            <summary>Tổng trọng số các chỉ tiêu của chủ thể trong kỳ — khác 100% là bộ chỉ tiêu chưa đủ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressSubjectItem.TotalScore">
            <summary>Tổng điểm KPI tạm tính của kỳ = Σ điểm trọng số các dòng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressSubjectItem.PendingCount">
            <summary>Số dòng chưa tính được số (lỗi nguồn hoặc chờ nhập tay)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiRecloseWindowItem">
            <summary>
            Tình trạng cửa sổ chốt lại của một kỳ (plan §3.4) — thứ màn chốt kỳ cần để nói rõ với người
            dùng "còn mấy ngày" thay vì để họ bấm rồi mới biết đã hết hạn.
            </summary>
            <remarks>
            Số ngày nằm ở <c>AppConfig: Kpi.RecloseWindowDays</c> và trước GĐ F chỉ
            <c>KpiPeriodCloseService</c> đọc được. Phơi ra ở đây thay vì để FE gọi <c>AppConfig/Search</c>
            vì đọc thẳng AppConfig từ màn KPI là mượn role của miền khác — đúng bẫy §8 mà GĐ C đã cắn.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiRecloseWindowItem.PeriodEnd">
            <summary>Thời điểm hết kỳ (theo mốc kỳ giờ Việt Nam của <c>KpiPeriod</c>)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiRecloseWindowItem.IsPeriodEnded">
            <summary>Kỳ đã kết thúc chưa — chưa hết kỳ thì không chốt được, kể cả lần đầu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiRecloseWindowItem.RecloseWindowDays">
            <summary>Số ngày cửa sổ chốt lại đang cấu hình</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiRecloseWindowItem.RecloseDeadline">
            <summary>Hạn cuối còn chốt lại được = hết kỳ + số ngày cửa sổ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiRecloseWindowItem.IsRecloseWindowOpen">
            <summary>Cửa sổ chốt lại còn mở không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiRecloseWindowItem.RemainingDays">
            <summary>
            Số ngày còn lại của cửa sổ, làm tròn lên; 0 khi đã hết hạn hoặc kỳ chưa kết thúc.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiRecloseWindowItem.IsClosed">
            <summary>
            Chủ thể đã có chỉ tiêu nào ở trạng thái đã chốt chưa — chỉ có giá trị khi lời gọi truyền
            chủ thể và chủ thể đó nằm trong phạm vi thao tác của người gọi; ngoài ra là <c>null</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiRecloseWindowItem.Message">
            <summary>Câu giải thích tiếng Việt để hiển thị thẳng lên băng thông báo</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiResultItem">
            <summary>
            Một dòng kết quả kỳ ĐÃ CHỐT — đọc thẳng từ <c>KpiResult</c>, không tính lại.
            </summary>
            <remarks>
            Kỳ đã chốt là snapshot bất biến (§3.4). Đây chính là thứ chặn phơi nhiễm của nợ <c>KPI-8</c>:
            nhân sự chuyển bưu cục sau khi chốt không làm số của kỳ cũ trôi, vì không ai chạy lại provider.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiResultItem.MetricCode">
            <summary>Mã chỉ số, vd "sales.revenue"</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiResultItem.Unit">
            <summary>Đơn vị đo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiResultItem.SubjectName">
            <summary>Tên nhân viên hoặc tên đơn vị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiResultItem.ActualValue">
            <summary>Giá trị thực đã chốt</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiResultItem.ManualValue">
            <summary>Giá trị nhập tay nếu dòng này do người nhập, null nếu engine tính</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiResultItem.ManualReason">
            <summary>Lý do nhập tay</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiResultItem.IsTrial">
            <summary>
            Kỳ thử nghiệm (§7.9) — xem và đối chiếu được, KHÔNG BAO GIỜ sinh thưởng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiResultItem.ClosedByName">
            <summary>Tên người chốt; job tự động ghi tài khoản hệ thống</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiResultItem.DetailJson">
            <summary>Breakdown đối soát, ghi nguyên văn từ provider lúc chốt</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodCloseSummary">
            <summary>
            Kết quả một lần chạy chốt kỳ — số dòng chốt được, số dòng lỗi, lý do từng dòng lỗi.
            </summary>
            <remarks>
            Job ghi nguyên khối này vào log. Đọc kỹ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodCloseSummary.ErrorCount"/>: dòng lỗi là dòng
            <b>chưa chốt</b>, không phải dòng chốt với giá trị 0 (§3.9d).
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodCloseSummary.IsTrial">
            <summary>Kỳ này là kỳ thử nghiệm hay chính thức (§7.9)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodCloseSummary.ClosedCount">
            <summary>Số chỉ tiêu đã ghi được KpiResult và chuyển sang Đã chốt kỳ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodCloseSummary.UpdatedCount">
            <summary>Số chỉ tiêu cập nhật lại kết quả cũ (chốt lại) thay vì tạo mới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodCloseSummary.ErrorCount">
            <summary>
            Số chỉ tiêu KHÔNG chốt được vì nguồn dữ liệu lỗi hoặc chỉ số nhập tay chưa có giá trị —
            những dòng này giữ nguyên trạng thái cũ, chờ sửa nguồn rồi chốt lại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodCloseSummary.Errors">
            <summary>Lý do từng dòng lỗi, dạng "chỉ tiêu #id (mã chỉ số): lý do"</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodCloseSummary.BonusCreatedCount">
            <summary>Số khoản thưởng KPI sinh mới sau lần chốt này (GĐ E) — 0 khi chưa đủ 4 chốt chặn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodCloseSummary.BonusUpdatedCount">
            <summary>Số khoản thưởng KPI được cập nhật (chốt lại kỳ)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodCloseSummary.BonusTotalAmount">
            <summary>Tổng tiền thưởng KPI của lần chạy này</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiSubjectOptionItem">
            <summary>
            Một lựa chọn cho ô chọn chủ thể của màn giao chỉ tiêu — chỉ định danh, không mang gì thêm.
            </summary>
            <remarks>
            Cố ý **chỉ có Id và tên**. Đây là đường đọc mới, và §8 của plan chốt rằng đường đọc mới không
            bao giờ được rộng hơn đường đọc sẵn có của chính miền dữ liệu đó: người có
            <c>KpiAssignment.CreateOrUpdate</c> không vì thế mà được đọc số điện thoại, email hay bưu cục
            của nhân sự — đó là dữ liệu miền HR, phải hỏi role của miền HR.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiSubjectOptionItem.Id">
            <summary>Id của nhân viên hoặc đơn vị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiSubjectOptionItem.Name">
            <summary>Tên hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiSubjectOptionItem.SubjectKind">
            <summary>Nhân viên hay đơn vị — để FE khỏi phải suy lại từ tham số đã gửi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Medias.MediaItem.Caption">
            <summary>
            Caption của media
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Medias.MediaItem.DisplayOrder">
            <summary>
            Thứ tự hiển thị của media
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileSearchItem">
            <summary>Một dòng danh sách hồ sơ bưu cục.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileSearchItem.AgencyDeleted">
            <summary>Chi nhánh đã bị xoá mềm ở Quản lý chi nhánh — hồ sơ cần đóng/chuyển hướng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileSearchItem.RegionId">
            <summary>
            Khu vực = node <c>AgencyType.Region</c> gần nhất phía trên chi nhánh trong cây <c>ParentId</c> (cột "khu vực" đặc tả
            §6.1); null khi chi nhánh không nằm dưới khu vực nào.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileSearchItem.UpdatedByUserName">
            <summary>Người sửa hồ sơ lần cuối (cột "người cập nhật" đặc tả §6.1).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileSearchItem.Missing">
            <summary>Mã điều kiện công bố cứng còn thiếu (chỉ điều kiện đã làm ở GĐ hiện tại).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileSearchItem.CallClicks30d">
            <summary>
            Lượt bấm gọi 30 ngày gần nhất (tới hết hôm qua — nguồn <c>AgencyWebEventDaily</c> do job đêm gộp). 0 khi chưa
            có sự kiện nào.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileDetailItem">
            <summary>Chi tiết hồ sơ bưu cục cho màn 7 tab.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileDetailItem.Agency">
            <summary>Thông tin lõi của <c>Agency</c> — CHỈ ĐỌC, sửa ở Quản lý chi nhánh.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileDetailItem.Media">
            <summary>Rỗng tới GĐ A2.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileDetailItem.CoverageWardCount">
            <summary>Số xã bộ 2 cấp trong vùng phủ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileDetailItem.PendingChangeRequests">
            <summary>
            Đề xuất còn chờ duyệt của bưu cục (GĐ D) — chỉ trả cho người đọc được hàng đợi (người duyệt, Branch.Manager);
            người khác nhận mảng rỗng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyCoreItem.AddressLevelType">
            <summary>Giá trị cột thô — KHÔNG đáng tin (Việc 0 Đ2); dùng <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyCoreItem.IsTwoLevelAddress"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyCoreItem.IsTwoLevelAddress">
            <summary>Địa chỉ thật sự ở bộ 2 cấp (tính từ <c>Location</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyCoreItem.ManagerName">
            <summary>Họ tên người quản lý chi nhánh (<c>User.FullName</c>) — null khi chưa gán.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyMediaItem.IsApproved">
            <summary>false = chờ duyệt — portal vẫn thấy, trang công khai không lấy.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyMediaItem.UploadedByUserName">
            <summary>Người tải lên — màn duyệt ảnh cần biết ảnh của ai.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileVersionItem">
            <summary>Một dòng lịch sử phiên bản — không kèm <c>SnapshotJson</c> (nặng); xem chi tiết qua <c>Versions/{agencyId}/{versionNo}</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileVersionItem.IsCurrent">
            <summary>Phiên bản hồ sơ đang ở.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileVersionList">
            <summary>Trang lịch sử phiên bản, mới nhất trước.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileVersionDetailItem">
            <summary>Một phiên bản kèm ảnh chụp đã đọc (thuộc tính thiếu trong JSON cũ mang giá trị mặc định).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileLookups">
            <summary>Danh mục chọn cho màn hồ sơ bưu cục.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileLookups.Provinces">
            <summary>Tỉnh bộ 2 cấp (Level 1, LevelType 2).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileLookups.RoutePages">
            <summary>Trang tuyến <c>dich-vu/…</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileLookups.GoodsTypes">
            <summary>Loại hàng (<c>Category.ContentType = GoodsType</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileLookups.AgenciesWithoutProfile">
            <summary>Chi nhánh LadaBranch/Franchise chưa có hồ sơ — chỉ trả cho người được tạo hồ sơ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileLookups.Regions">
            <summary>Khu vực (<c>Agency</c> loại Region) cho bộ lọc "khu vực" của danh sách — rỗng thì portal ẩn bộ lọc đó.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileLookups.AgencyTypes">
            <summary>Loại sở hữu một bưu cục có thể mang (Chi nhánh LADA / Nhượng quyền) — bộ lọc "loại" của danh sách.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileLookups.PublicPagesEnabled">
            <summary>
            Trang công khai <c>/buu-cuc/&lt;slug&gt;</c> đã bật chưa (AppConfig <c>Network.BuuCucPublicEnabled</c>). Tắt thì portal
            không hiện link "Xem trang công khai" — link đó là 404 tới khi marketing công bố đủ hồ sơ và bật cờ (plan §4.1).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyChangeRequestItem">
            <summary>Một đề xuất sửa hồ sơ (GĐ D) kèm bảng so sánh hiện tại ↔ đề xuất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyChangeRequestItem.Summary">
            <summary>Một dòng tóm tắt: "Đổi toạ độ", "Thêm nhân sự Nguyễn Văn A"…</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyChangeRequestItem.ReviewedByUserName">
            <summary>Người duyệt / từ chối (null khi còn chờ hoặc bị thay bằng đề xuất mới).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyChangeRequestItem.BaseVersionNo">
            <summary>Phiên bản hồ sơ lúc gửi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyChangeRequestItem.CurrentVersionNo">
            <summary>Phiên bản hồ sơ hiện tại — gửi lại làm <c>ExpectedVersion</c> khi duyệt.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyChangeRequestItem.AppliedVersionNo">
            <summary>Phiên bản sinh ra khi duyệt.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyChangeRequestItem.Changes">
            <summary>
            Bảng so sánh — "hiện tại" là giá trị ĐANG lưu lúc đọc (không phải lúc gửi), "đề xuất" là giá trị sẽ ghi. Chữ
            thuần (Intro đã bỏ thẻ) — FE hiện bằng nội suy văn bản, không bao giờ <c>v-html</c>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyChangeRequestChange">
            <summary>Một dòng của bảng so sánh.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyChangeRequestList">
            <summary>Hàng đợi đề xuất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyChangeRequestList.PendingCount">
            <summary>Số đề xuất còn chờ trong phạm vi người gọi (không theo bộ lọc trạng thái) — dải "N đề xuất chờ duyệt".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyPendingChangeRequestItem">
            <summary>Đề xuất đang chờ của một bưu cục — hiện trên thẻ nhóm ở trang chi tiết.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyBulkExceptionResult">
            <summary>Kết quả áp ngoại lệ giờ hàng loạt.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyBulkExceptionResult.Dates">
            <summary>Các ngày áp dụng, <c>yyyy-MM-dd</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyBulkExceptionRow">
            <summary>Kết quả một bưu cục.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyBulkExceptionRow.VersionNo">
            <summary>Phiên bản mới (khi có thay đổi) hoặc phiên bản hiện tại.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebCounts">
            <summary>
            Bộ đếm một nhóm sự kiện: lượt (<c>Count</c>) và phiên (<c>SessionHash</c> distinct theo ngày) cho từng loại. Lượt bơm
            được trong trần 120/phút/IP — hiện cả phiên cạnh lượt.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebCounts.Total">
            <summary>Tổng lượt mọi loại.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebCounts.SetSessions(Lada.Framework.Data.Domains.Network.AgencyWebEventType,System.Int32)">
            <summary>Đặt (không cộng) số phiên của một loại — số phiên khác nhau trên cả phạm vi tính từ sự kiện thô.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReport">
            <summary>Báo cáo bưu cục một tháng (GĐ D) — nguồn <c>AgencyWebEventDaily</c>; nguồn truy cập/trang từ sự kiện thô.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReport.Month">
            <summary>Tháng báo cáo <c>yyyy-MM</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReport.From">
            <summary>Ngày đầu tháng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReport.To">
            <summary>Ngày cuối tính số — cuối tháng, hoặc ngày gộp gần nhất nếu tháng đang chạy.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReport.LastAggregatedDate">
            <summary>Ngày gần nhất job gộp đã chạy (toàn hệ thống); null = job chưa từng gộp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReport.RawAvailable">
            <summary>Sự kiện thô của tháng còn (giữ 13 tháng) — false thì bảng nguồn/trang rỗng vì đã dọn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReport.SessionsExact">
            <summary>
            Số phiên ở <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReport.Totals"/> và <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReport.Daily"/> là khách khác nhau trên CẢ phạm vi (tính từ sự kiện thô —
            một khách xem 2 bưu cục là 1 phiên). False (tháng đã quá 13 tháng, không còn sự kiện thô) thì hai chỗ đó là
            TỔNG số phiên từng bưu cục (một khách xem 2 bưu cục tính 2). Dòng từng bưu cục luôn là số phiên của riêng bưu cục.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReport.Sources">
            <summary>Top nguồn truy cập (utm_source, hoặc host referrer, hoặc "(trực tiếp)") — chữ do trình duyệt khách gửi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReport.Pages">
            <summary>Top trang phát sinh sự kiện — chữ do trình duyệt khách gửi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReport.Agencies">
            <summary>Bưu cục trong phạm vi người xem — nguồn ô lọc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReport.Regions">
            <summary>
            Khu vực (node Region) cho ô lọc — trả kèm báo cáo vì người chỉ có role <c>Report</c> không gọi được <c>Lookups</c>.
            Phạm vi Own (Branch.Manager) nhận mảng rỗng: một bưu cục thì không có gì để lọc.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReportRow">
            <summary>Một bưu cục trong báo cáo.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReportDay">
            <summary>Một ngày (cộng mọi bưu cục trong bộ lọc) — biểu đồ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyWebReportBreakdown">
            <summary>Một dòng nguồn / trang.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanItem">
            <summary>
            Cả bộ tham số mục "Kế hoạch kinh doanh" của cổng nhượng quyền (<c>GET api/FranchiseBusinessPlan/get</c>, plan cổng
            §3.13, §6.24): năm dòng sản lượng theo bậc phường + một dòng tham số + dấu phiên bản cho form sửa.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanItem.Stamp">
            <summary>Dấu phiên bản của cả bộ — gửi lại khi lưu; khác dấu hiện tại = người khác vừa sửa.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanItem.Tiers">
            <summary>Năm bậc phường 1–5 theo thứ tự bậc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanItem.Setting">
            <summary>null = chưa chạy migration seed.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanItem.MaxPreviewWards">
            <summary>Số phường mỗi bậc tối đa ở ô xem thử (trần số phường một mã).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanItem.UpdatedTime">
            <summary>Lần lưu gần nhất của cả bộ (dòng nào mới nhất).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseTierVolumeItem">
            <summary>Một bậc phường — ba số là đơn MỖI PHƯỜNG MỖI NGÀY.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseTierVolumeItem.TotalPerDay">
            <summary>Tổng ba số — để đối chiếu với sản lượng nội bộ của bậc trong bảng giá.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanSettingItem">
            <summary>Tham số chung. Tiền: đồng (đơn giá đ/đơn, chi phí đ/tháng).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanSaveResult">
            <summary>Kết quả lưu. <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanSaveResult.Errors"/> = MỌI lỗi kiểm dữ liệu trong một lần.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanPreviewResult">
            <summary>Kết quả tính thử (<c>POST api/FranchiseBusinessPlan/preview</c>) — không ghi gì, không chạm mã nào.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanPreviewItem">
            <summary>Kế hoạch tính thử — cùng luật với trang của khách. Tiền: đồng (đã làm tròn 10.000 đ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanPreviewItem.State">
            <summary><c>Ready</c> · <c>NoWards</c> · <c>NoTieredWards</c> · <c>NotConfigured</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanPreviewItem.PackageName">
            <summary>Gói vùng phủ theo số phường (POINT…); null = chưa đủ gói.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanPreviewItem.Offices">
            <summary>Số bưu cục nhân chi phí cố định.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanPreviewItem.PotentialDelivery">
            <summary>Sản lượng vùng khi chạy đủ (trước tỷ lệ khởi động), đơn/ngày.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanPreviewItem.Milestones">
            <summary>Tháng 1 / 3 / 6 / 12.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseBusinessPlanPreviewItem.Months">
            <summary>24 tháng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem">
            <summary>Một dòng của danh sách "Đăng ký nhượng quyền".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem.Code">
            <summary>Mã đăng ký người gửi nhận được trên website, dạng <c>NQ000123</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem.ProvinceCode">
            <summary><c>Location.Code</c> của tỉnh, hoặc <c>khac</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem.BusinessStatus">
            <summary>Mã <c>da-co</c> / <c>se-thanh-lap</c> / <c>chua-dinh</c>; <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem.BusinessStatusName"/> là nhãn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem.AppointmentAt">
            <summary>
            Lịch hẹn gặp / khảo sát gần nhất (plan cổng §6.29) — còn giữ sau khi đăng ký rời "Đã hẹn gặp/khảo sát";
            <c>null</c> = chưa từng ghi lịch.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem.Channel">
            <summary>Kênh tiếp nhận; <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem.ChannelName"/> là nhãn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem.CreatedByUserName">
            <summary>Nhân viên nhập tay; rỗng với đăng ký từ form website.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem.PortalLastSeenAt">
            <summary>
            Lần khách vào xem Cổng nhượng quyền gần nhất (plan cổng §6.28): <c>LastSeenAt</c> lớn nhất của mọi phiên trên mọi
            mã gắn đăng ký này — cổng chạm mốc này khi khách còn đang xem, không chỉ lúc nhập mã. <c>null</c> = khách chưa
            từng vào cổng (kể cả khi sale đã chọn tay "Đã xem thông tin nhượng quyền"). Không gác theo role cổng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem.AccessCode">
            <summary>
            Mã truy cập Cổng nhượng quyền gần nhất của đăng ký (plan cổng §6.23): mã chưa thu hồi nếu có, không thì mã thu
            hồi gần nhất; <c>null</c> khi chưa từng cấp mã HOẶC người gọi không có role cổng (<c>FranchisePortal.Sale</c> /
            <c>Manage</c>) — role cổng là hàng rào của mã.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem.CanViewAccessCode">
            <summary>
            Người gọi xem được mã truy cập của đăng ký này — cùng phạm vi <c>FranchisePortalNavPermissions.ApplyScope</c>: role
            cổng ∧ (quản lý mọi mã ∨ là người phụ trách). <c>false</c> thì <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem.AccessCode"/> rỗng vì KHÔNG ĐƯỢC XEM,
            không phải vì chưa cấp mã — giao diện không được nói "chưa cấp mã" (rule quyen-hien-thi).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem.CanCreateAccessCode">
            <summary>
            Người gọi tạo được mã truy cập cho đăng ký này: có role tạo mã ∧ là người phụ trách ∧ đăng ký chưa có mã chưa
            thu hồi — cùng luật máy chủ kiểm ở <c>POST api/FranchisePortalAccessCode/create</c>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadTimelineItem">
            <summary>
            Các đoạn trạng thái theo thời gian của một đăng ký (<c>POST api/FranchiseLead/status-timeline</c>) — thanh của biểu
            đồ Gantt trang lịch hẹn (plan cổng §6.30).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadTimelineItem.Spans">
            <summary>Liền nhau, cũ trước; đoạn cuối <c>To = null</c> là trạng thái hiện tại.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadStatusSpanItem">
            <summary>Một khoảng thời gian đăng ký ở một trạng thái.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadStatusSpanItem.To">
            <summary><c>null</c> = còn đang ở trạng thái này.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadAccessCodeItem">
            <summary>Tóm tắt mã truy cập trên dòng đăng ký — KHÔNG có mã rõ (mã rõ chỉ ở <c>GET api/FranchisePortalAccessCode/{id}</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadAccessCodeItem.CodePrefix">
            <summary>4 ký tự đầu phần thân mã (<c>NQ-ABCD-••••</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadAccessCodeItem.State">
            <summary><c>active</c> · <c>expiring</c> · <c>expired</c> · <c>revoked</c> (tính tại lúc đọc).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadAccessCodeItem.LiveCount">
            <summary>Số mã CHƯA thu hồi của đăng ký — lớn hơn 1 chỉ có ở dữ liệu trước luật "một mã" (§6.23).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadDetailItem">
            <summary>Chi tiết một đăng ký — thêm bằng chứng đồng ý, nguồn chiến dịch, trang gửi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadDetailItem.ConsentText">
            <summary>Nguyên văn câu đồng ý người gửi đã đánh dấu; rỗng với đăng ký nhập tay.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadDetailItem.ConsentAt">
            <summary><c>null</c> với đăng ký nhập tay.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadDetailItem.LegacyLeadId">
            <summary>Dòng <c>Lead</c> gốc nếu bản ghi được chuyển từ bảng cũ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadHistoryItem">
            <summary>
            Một dòng lịch sử cập nhật của đăng ký (<c>GET {id}/history</c>), mới nhất trước. Dòng "Tạo đăng ký" của đăng ký
            từ website (và của đăng ký có trước khi bật ghi lịch sử) dựng từ chính bản ghi — <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadHistoryItem.Id"/> bằng 0.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadHistoryItem.Changes">
            <summary>Mỗi phần tử một trường đổi, dạng <c>Nhãn: cũ → mới</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadHistoryItem.CreatedByUserName">
            <summary>Người thao tác; rỗng khi người đăng ký tự gửi form website.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadAssigneeItem">
            <summary>Một người có thể được giao phụ trách đăng ký (giữ role Search hoặc Manage, còn làm việc).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadFilterOptionsItem">
            <summary>
            Danh mục cho ô lọc của màn "Đăng ký nhượng quyền" — máy chủ là nguồn duy nhất, giao diện không chép danh sách
            sang JS (nợ NQW-1: GĐ E đổi nguồn tỉnh ở máy chủ, giao diện tự theo).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadFilterOptionsItem.Statuses">
            <summary>Trạng thái xử lý, theo số của <see cref="T:Lada.Framework.Data.Domains.Network.FranchiseLeadStatus"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadFilterOptionsItem.Provinces">
            <summary>Tỉnh, thành nhận đăng ký (<c>Location.Code</c>) + lựa chọn <c>khac</c> ở cuối.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadFilterOptionsItem.BusinessStatuses">
            <summary>Tình trạng doanh nghiệp người đăng ký khai trên form.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadFilterOptionsItem.Channels">
            <summary>Mọi kênh tiếp nhận, theo số của <see cref="T:Lada.Framework.Data.Domains.Network.FranchiseLeadChannel"/> — cho ô lọc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadFilterOptionsItem.ManualChannels">
            <summary>Kênh nhân viên chọn được khi nhập tay — <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadFilterOptionsItem.Channels"/> trừ Website.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadResult">
            <summary>Kết quả thao tác trên một đăng ký; <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadResult.IsNotFound"/> = không có hoặc ngoài phạm vi (trả 404).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadResult.Id">
            <summary>Id của đăng ký vừa tạo/sửa — giao diện mở thẳng chi tiết sau khi nhập tay.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadResult.RevokedAccessCodeCount">
            <summary>Số mã truy cập cổng vừa thu hồi theo đăng ký (lưu "Không phù hợp") — giao diện báo trong câu đã lưu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadAssignManyResult">
            <summary>
            Kết quả giao hàng loạt (<c>POST api/FranchiseLead/assign-many</c>): ba con số cộng lại bằng số id đã gửi (sau khi
            bỏ trùng) — giao diện báo đúng bao nhiêu đăng ký thật sự đổi người.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadAssignManyResult.AssignedCount">
            <summary>Đăng ký đổi người phụ trách (mỗi cái một dòng lịch sử).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadAssignManyResult.UnchangedCount">
            <summary>Đăng ký vốn đã do đúng người đó phụ trách (hoặc vốn chưa giao khi bỏ giao) — không ghi gì.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadAssignManyResult.NotFoundCount">
            <summary>Id không có hoặc ngoài phạm vi người gọi (đã bị xoá sau khi trang nạp) — bỏ qua.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadAssignManyResult.PicUserName">
            <summary>Tên người vừa được giao; <c>null</c> khi bỏ giao.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadFileResult">
            <summary>File Excel của nút Xuất.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadBacklogItem">
            <summary>
            Báo cáo tồn đọng đăng ký nhượng quyền (<c>POST api/FranchiseLead/backlog</c>) — hai bảng cùng một lần đọc, cùng
            phạm vi với danh sách. Mảng <c>Counts</c> xếp đúng thứ tự <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadBacklogItem.Columns"/> (bảng thời gian chờ) hoặc
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadBacklogItem.Statuses"/> (bảng theo tỉnh) — giao diện không chép danh sách cột sang JS.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadBacklogItem.Columns">
            <summary>Cột thời gian chờ: số ngày kể từ lần cập nhật gần nhất (D0, D1, … D30+).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadBacklogItem.Statuses">
            <summary>Mọi trạng thái theo thứ tự tiến trình; <c>IsOpen = false</c> là trạng thái đã đóng (đã ký, không phù hợp).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadBacklogItem.Aging">
            <summary>Bảng thời gian chờ gộp mọi tỉnh — đủ các trạng thái đang xử lý, kể cả dòng bằng 0.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadBacklogItem.AgingByProvince">
            <summary>Bảng thời gian chờ của từng tỉnh có đăng ký đang xử lý — chỉ các dòng khác 0.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadBacklogItem.ByProvince">
            <summary>Mỗi tỉnh một dòng, đếm theo MỌI trạng thái (cả đã đóng).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadBacklogItem.GeneratedAt">
            <summary>Mốc tính "hôm nay" của cột thời gian chờ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadBacklogColumnItem.MinDays">
            <summary>Gửi lại nguyên văn làm khoá lọc <c>idleMinDays</c> / <c>idleMaxDays</c> của <c>search</c> khi bấm vào ô.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadBacklogColumnItem.MaxDays">
            <summary><c>null</c> = không chặn trên (cột cuối).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadAgingTableItem">
            <summary>Một bảng trạng thái × thời gian chờ; <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadAgingTableItem.ProvinceCode"/> rỗng = gộp mọi tỉnh.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadAgingTableItem.ProvinceCode">
            <summary>Gửi lại nguyên văn làm khoá lọc <c>provinceCode</c> (kể cả <c>chua-ro</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadAgingTableItem.Counts">
            <summary>Dòng tổng theo từng cột.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadProvinceRowItem.ProvinceCode">
            <summary><c>null</c> ở dòng tổng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadProvinceRowItem.Counts">
            <summary>Theo thứ tự <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadBacklogItem.Statuses"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadProvinceRowItem.Open">
            <summary>Số đăng ký đang xử lý (trừ trạng thái đã đóng).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePackageTierItem">
            <summary>
            Một bậc gói vùng phủ POINT / HUB / ZONE / REGION (GĐ K, plan cổng §6.16) — cho màn tham số <c>/goi</c> và ô
            "Phạm vi giá" của sale. Dữ liệu nội bộ: KHÔNG đưa nguyên danh sách ra cổng (khách chỉ thấy bậc của mình).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePackageTierItem.IsLast">
            <summary>Bậc cuối — mã có nhiều phường hơn <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePackageTierItem.MaxWards"/> vẫn thuộc bậc này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePackageTierItem.WardRangeText">
            <summary>"6–15 phường, xã" / bậc cuối "từ 31 phường, xã".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePackageTierItem.FeeDiscountText">
            <summary>"Giá bảng" / "Giảm 15 %".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePackageTierItem.DepositText">
            <summary>"75 % bảng chuẩn".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePackageTierItem.ExtraSupport">
            <summary>Hỗ trợ riêng — mỗi dòng một ý.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePackageTierListItem">
            <summary>Bốn bậc theo thứ tự ngưỡng kèm dấu phiên bản — form sửa gửi lại dấu này (người khác vừa sửa thì từ chối).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePackageTierListItem.MaxWardsPerCode">
            <summary>Trần số phường/xã của một mã — dải của mọi bậc phải nằm trong 1 … số này.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalResult">
            <summary>Kết quả một thao tác ghi của Cổng nhượng quyền. <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalResult.IsNotFound"/> = không có hoặc ngoài phạm vi → HTTP 404.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalResult.Id">
            <summary>Id của bản ghi vừa tạo/sửa.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionItem">
            <summary>Một dòng của danh sách "Nội dung cổng".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionItem.TopicId">
            <summary>Topic vật chủ của bộ khối; <c>null</c> với mục bảng giá.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionItem.IsPublished">
            <summary>Mục đã có bản xuất bản khách xem được. Mục bảng giá không có khối nên luôn <c>true</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionDetailItem">
            <summary>Chi tiết một mục cho form sửa.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionDetailItem.TopicSystemName">
            <summary>Tên hệ thống của topic vật chủ (<c>FranchisePortal.&lt;Code&gt;</c>) — editor khối hỏi bộ khối theo tên này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionDetailItem.PortalPath">
            <summary>Đường dẫn của mục trên website.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionFormOptionsItem">
            <summary>Danh mục cho form mục cổng (<c>GET form-options</c>) — giao diện không chép danh sách sang JS.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionFormOptionsItem.ReservedSlugs">
            <summary>Đoạn đường dẫn không đặt được làm slug mục.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionBlocksItem">
            <summary>
            Bản ĐANG SỬA của khối nội dung một mục (<c>GET {id}/blocks</c>) kèm thứ editor cần: bộ khối của vật chủ, dấu
            phiên bản để xuất bản đúng bản đã thấy, trạng thái xuất bản, và cảnh báo khối trỏ tới tệp không còn dùng được.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionBlocksItem.HasBlocks">
            <summary>False với mục không có khối (mục bảng giá) — màn chỉ hiện tab Thông tin.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionBlocksItem.Notice">
            <summary>Lý do mục LẼ RA có khối mà không sửa được (nội dung lệch); <c>null</c> = bình thường.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionBlocksItem.Profile">
            <summary>Bộ khối của mục: loại khối được thêm, luật số lượng, bộ icon. <c>Enabled = false</c> khi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionBlocksItem.HasBlocks"/> false.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionBlocksItem.DraftVersion">
            <summary>Dấu bản đang sửa — gửi lại khi bấm Xuất bản (<c>POST {id}/publish</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionBlocksItem.HasUnpublishedChanges">
            <summary>Bản đang sửa khác bản khách đang thấy (hoặc chưa xuất bản lần nào mà đã có khối).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionBlocksItem.FileWarnings">
            <summary>Khối của bản ĐANG SỬA trỏ tới tệp không còn dùng được — lưu / xuất bản sẽ bị từ chối cho tới khi gỡ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionBlocksItem.PublishedFileWarnings">
            <summary>Khối của bản ĐÃ XUẤT BẢN trỏ tới tệp không còn — cổng đang tự ẩn phần đó với khách.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalBlockFileWarning">
            <summary>Một khối trỏ tới một tệp riêng tư không còn dùng được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalBlockFileWarning.BlockNumber">
            <summary>Thứ tự khối trong bộ khối, tính từ 1.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalBlockFileWarning.Message">
            <summary>Câu nói rõ lý do (đã xoá, sai loại, thuộc mục khác…).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalDraftResult">
            <summary>Kết quả lưu (<c>POST {id}/blocks</c>) hoặc xuất bản (<c>POST {id}/publish</c>) khối của một mục.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalDraftResult.DraftChanged">
            <summary>
            True = có người lưu khối sau khi người bấm mở màn (dấu phiên bản gửi lên đã cũ) — chưa ghi / chưa xuất bản gì.
            Giao diện báo để người dùng tải lại bản mới nhất; không tự tải lại vì sẽ mất phần họ đang soạn.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalPreviewResult">
            <summary>
            Link xem trước bản đang sửa của một mục (<c>POST {id}/preview-token</c>). <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalPreviewResult.Path"/> là đường dẫn trên
            website kèm token (<c>/thong-tin-nhuong-quyen/xem-truoc/…</c>) — giao diện ghép với địa chỉ website của môi trường.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeItem">
            <summary>Một dòng của danh sách "Mã truy cập". Không mang mã rõ — chỉ 4 ký tự đầu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeItem.CodePrefix">
            <summary>4 ký tự đầu phần thân mã (<c>NQ-ABCD-••••</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeItem.FranchiseLeadCode">
            <summary>Mã đăng ký nhượng quyền của khách, dạng <c>NQ000123</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeItem.State">
            <summary>Trạng thái tính tại lúc đọc: <c>active</c> · <c>expiring</c> (còn ≤ 2 ngày) · <c>expired</c> · <c>revoked</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeItem.ProvinceCodes">
            <summary>Mã tỉnh sale ghi cho mã — nhãn lọc, không gác gì trên cổng (thứ khách thấy là <c>PriceScope</c> ở chi tiết mã).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeItem.UnlockedCount">
            <summary>Số mục đang bật đã mở cho mã này / tổng số mục đang bật.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeItem.PriceScopeState">
            <summary>
            Tóm tắt phạm vi giá đã gắn (<see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalPriceScopeStates"/>): <c>none</c> · <c>below</c> (có phường
            nhưng chưa đủ gói — khách thấy câu "cần từ 3 phường…") · <c>wards</c> (đã vào một gói vùng phủ).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeItem.PriceScopeLabel">
            <summary>Nhãn in ở danh sách: "7 phường, xã · HUB" / "2 phường, xã · chưa đủ gói"; <c>null</c> khi chưa gắn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeItem.PriceScopeProvinceName">
            <summary>Tỉnh/thành phố của các phường đã gắn, cách nhau dấu phẩy (được nhiều tỉnh); <c>null</c> khi chưa gắn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalPriceScopeStates">
            <summary>Giá trị của <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeItem.PriceScopeState"/>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalPriceProvinceOption">
            <summary>Tỉnh/thành phố có giá ở phiên bản giá hiện hành trong ô chọn của khối "Phạm vi giá".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalPriceWardOption">
            <summary>Một phường/xã CÓ GIÁ ở phiên bản giá hiện hành trong ô chọn của khối "Phạm vi giá".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalPriceWardOption.WardName">
            <summary>Tên kèm loại (vd "Phường Hà Đông") — đúng chuỗi được chụp vào phạm vi giá khi gắn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeDetailItem">
            <summary>Chi tiết một mã — có mã rõ, chỉ trả cho người trong phạm vi của mã.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeDetailItem.Code">
            <summary>Mã rõ dạng <c>NQ-XXXX-XXXX</c>; rỗng khi máy chủ không giải mã được (đổi khoá bí mật).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeDetailItem.Sections">
            <summary>Mọi mục cổng kèm trạng thái mở/khoá của mã này, theo thứ tự hiển thị.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeDetailItem.RecentHistory">
            <summary>Các thao tác gần nhất, mới trước.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeDetailItem.PriceScope">
            <summary>Thứ sale đã gắn cho khách ở mục bảng giá; null = chưa gắn gì (khách thấy lời nhắn liên hệ tư vấn viên).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessPriceScopeItem">
            <summary>Phạm vi giá của một mã: các phường/xã đã gắn + gói vùng phủ tự xếp theo số phường (GĐ K).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessPriceScopeItem.ProvinceName">
            <summary>Tỉnh/thành phố của các phường, cách nhau dấu phẩy theo thứ tự gắn — được nhiều tỉnh (§6.17).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessPriceScopeItem.TierName">
            <summary>Tên gói vùng phủ của mã ("HUB"); null khi chưa đủ gói hoặc bảng bậc trống.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessPriceScopeItem.TierLabel">
            <summary>Nhãn của gói ("Phát triển").</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessPriceScopeItem.TierMessage">
            <summary>Câu nhắc khi chưa đủ gói ("Cần từ 3 phường, xã để vào gói POINT.") — đúng câu khách thấy trên cổng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessPriceWardItem.Name">
            <summary>Tên kèm loại chụp lúc gắn ("Phường Hà Đông").</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessSectionItem.IsActive">
            <summary><c>false</c> = mục đang ẩn với mọi mã; không mở thêm được, khách không thấy dù đã mở.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessSectionItem.IsDataSection">
            <summary>
            Mục dữ liệu ("Bảng giá vùng phủ", "Kế hoạch kinh doanh" — GĐ M): dựng từ phường/xã đã gắn cho mã; mở mục này mà mã
            chưa gắn phường nào thì khách chỉ thấy "Chưa có khu vực nào được gắn cho bạn".
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAccessCodeCreateResult">
            <summary>Kết quả tạo mã: mã rõ trả về đúng lần này để hiện cho sale (xem lại được ở chi tiết).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionTotalItem">
            <summary>Tổng thời gian xem một mục của một mã = tổng <c>DurationSec</c> các lần rời mục.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalSectionTotalItem.OpenCount">
            <summary>Số lần mở mục.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalEventsItem">
            <summary>Dấu vết của một mã: một trang sự kiện (mới trước) + tổng theo mục trên TOÀN BỘ sự kiện của mã.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalChatMessageItem">
            <summary>Một tin nhắn hỏi-đáp với trợ lý AI của một mã (tab Hỏi đáp của drawer mã — GĐ G).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalChatTranscriptItem">
            <summary>Transcript của một mã: một trang tin nhắn (MỚI trước — giao diện tự đảo để đọc) + bộ đếm câu hỏi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalChatTranscriptItem.QuestionCount">
            <summary>Tổng số câu khách đã hỏi bằng mã này (cột <c>QuestionCount</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalChatTranscriptItem.QuestionsToday">
            <summary>Số câu đã hỏi hôm nay (giờ Việt Nam) và trần mỗi ngày — để biết khách sắp / đã hết lượt.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAssistantProviderItem">
            <summary>Một nhà cung cấp AI chọn được cho trợ lý — KHÔNG có key, chỉ có cờ có / chưa có key.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAssistantProviderItem.IsSupported">
            <summary>Loại mà trợ lý cổng gọi được (Anthropic / OpenAI) — loại khác không chọn được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAssistantProviderItem.BaseUrl">
            <summary>
            Gốc URL — chỉ có ý nghĩa với loại OpenAI (adapter Anthropic luôn gọi địa chỉ mặc định). Hiện cho người quản lý
            thấy dữ liệu khách sẽ đi đâu trước khi lưu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAssistantProviderItem.UpdatedTime">
            <summary>Lần sửa cuối của dòng nhà cung cấp (màn nhà cung cấp AI, role <c>Ai.Marketing</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAssistantProviderItem.Pin">
            <summary>Dấu hiện tại của dòng (<c>FranchisePortalAiRules.ProviderPin</c>) — form gửi lại lúc lưu (CNQ-65).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAssistantConfigItem">
            <summary>Cấu hình trợ lý AI cổng (màn "Cấu hình trợ lý", GĐ G) — đọc từ các khoá <c>FranchisePortal.Ai.*</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAssistantConfigItem.ProviderId">
            <summary>Id nhà cung cấp đã chọn; null = trợ lý tắt (KHÔNG lùi về nhà cung cấp mặc định).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAssistantConfigItem.Model">
            <summary>Model đã cấu hình; rỗng = <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAssistantConfigItem.DefaultModel"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAssistantConfigItem.EffectiveProviderId">
            <summary>Nhà cung cấp trợ lý dùng thật lúc này — đúng dòng đã chọn nếu còn dùng được; null = trợ lý không gọi được ai.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAssistantConfigItem.ProviderChangedSinceSave">
            <summary>
            Dòng đã chọn bị sửa (loại / BaseUrl / key) SAU lần lưu cấu hình cuối, hoặc cấu hình lưu từ trước khi có dấu ghim —
            trợ lý đang tắt tới khi người quản lý kiểm tra rồi lưu lại (CNQ-65).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAssistantConfigItem.ProviderChanges">
            <summary>Phần đã đổi ("loại nhà cung cấp", "địa chỉ gọi", "API key"); rỗng khi không so từng phần được (dấu trống / dạng cũ).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAssistantTestResult">
            <summary>Kết quả "Hỏi thử": câu trả lời + số đo + ngữ cảnh đã dùng (chỉ số đo từng mục, không lặp lại nội dung).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalAssistantTestResult.AccessCodeIsAlive">
            <summary>Mã đã hết hạn / thu hồi: khách không vào được cổng, mọi mục coi như khoá.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalFileItem">
            <summary>Một tệp riêng tư của cổng. Không mang đường dẫn trên đĩa và không mang văn bản đã trích.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalFileItem.HasExtractedText">
            <summary>Đã trích được văn bản cho trợ lý AI (chỉ PDF).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePortalFileResult">
            <summary>Kết quả tải tệp lên.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceProvinceItem">
            <summary>Một tỉnh/thành phố 2 cấp trong ô chọn tỉnh của trang tải mẫu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceProvinceItem.WardCount">
            <summary>Số phường/xã 2 cấp của tỉnh trong danh mục.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceProvinceItem.IsDefault">
            <summary>
            Tỉnh thuộc vùng phủ hiện tại (có phường/xã gắn bưu cục) — mặc định được tích sẵn khi tải mẫu.
            Đọc từ dữ liệu, không ghi cứng danh sách tỉnh.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceProvinceItem.PricedWardCount">
            <summary>Số phường/xã có giá trong phiên bản hiện hành (trang xuất).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceVersionItem">
            <summary>Một phiên bản bảng giá — dòng lịch sử ở trang quản trị, đầu trang ở trang xuất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceVersionItem.EditedLineCount">
            <summary>
            Số dòng đã thêm hoặc sửa tay sau khi upload (dòng có <c>UpdatedTime</c> sau <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceVersionItem.UploadedAt"/>). Khác 0 nghĩa
            là mã phiên bản in trên bảng giá xuất ra không còn chốt đúng giá của file đã upload.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceVersionItem.LastEditedAt">
            <summary>Lần sửa tay gần nhất; null khi chưa sửa dòng nào.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceLineItem">
            <summary>Chi tiết một dòng giá của phiên bản hiện hành — nạp vào form sửa của quản trị.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceLineItem.Stamp">
            <summary>Dấu phiên bản của dòng — gửi lại khi lưu; dòng đã bị người khác sửa thì máy chủ bác.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceCatalogWardItem">
            <summary>Một phường/xã 2 cấp CHƯA có giá trong phiên bản hiện hành — ô chọn của form thêm dòng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceFieldError">
            <summary>Lỗi của một ô trong form thêm/sửa dòng giá — <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceFieldError.Field"/> là tên thuộc tính của model.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceLineResult">
            <summary>Kết quả thêm/sửa một dòng giá: dòng sau khi lưu và phiên bản với số dòng, tổng giá đã tính lại.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceWardItem">
            <summary>Một phường/xã có giá trong phiên bản hiện hành — dòng của bảng tích chọn ở trang xuất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceWardItem.WardId">
            <summary><c>Location.Id</c> của phường/xã — khoá dòng, cũng là giá trị gửi lên khi xuất.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceRowError">
            <summary>Lỗi của một dòng (hoặc của cả file khi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceRowError.Row"/> = 0) lúc kiểm file upload.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceRowError.Row">
            <summary>Số dòng trong Excel (hàng 1 là tên cột); 0 = lỗi mức file.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePricePreviewGroup">
            <summary>Số dòng và tổng giá theo một nhóm (tỉnh hoặc bậc) ở bản xem trước.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePricePreviewItem">
            <summary>Bản xem trước sau khi file qua kiểm — quản trị bấm xác nhận thì mới lưu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceImportResult">
            <summary>
            Kết quả kiểm / lưu file upload. Có lỗi thì <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceImportResult.Errors"/> đầy và <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceImportResult.Preview"/> null — không ghi gì.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceImportResult.Version">
            <summary>Phiên bản vừa lưu (chỉ có sau bước xác nhận).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceFileResult">
            <summary>File nhị phân trả về cho nút Tải mẫu / Xuất.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceSummary">
            <summary>Phần tổng của bảng giá xuất ra khi có tích chọn — kết quả của <c>FranchisePriceCalculator</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceSummary.BelowMinimumWards">
            <summary>Số phường/xã đã chọn ít hơn mức tối thiểu — ghi cảnh báo đỏ, vẫn cho xuất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceSummary.TotalFranchisePrice">
            <summary>Σ giá nhượng quyền (gồm VAT).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceSummary.PriceBeforeVat">
            <summary>Làm tròn nửa lên (tổng ÷ (1 + thuế suất)).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceSummary.VatAmount">
            <summary>Tổng − giá chưa VAT.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceSummary.TotalVolumeDeposit">
            <summary>Σ cọc theo sản lượng, trước khi kẹp sàn/trần.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceSummary.RegionGuarantee">
            <summary>min(tối đa, max(tối thiểu, Σ cọc theo sản lượng)).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceSummary.VehicleGuarantee">
            <summary>Số xe × bảo đảm mỗi xe thuê.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceSummary.TotalGuarantee">
            <summary>Tiền bảo đảm theo vùng + bảo đảm xe thuê.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceSummary.TotalDueAtSigning">
            <summary>Tổng phí nhượng quyền + tổng tiền bảo đảm.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementNavPermissionItem">
            <summary>Cờ hiển thị màn Đối soát bưu cục.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementNavPermissionItem.CanManage">
            <summary>Kế toán LADA: lập nháp, phát hành, khoá, đánh dấu hoá đơn, xem mọi phiếu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementNavPermissionItem.CanConfirm">
            <summary>Bưu cục xác nhận phiếu của mình.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementNavPermissionItem.CanViewOwn">
            <summary>Bưu cục xem phiếu của mình (Confirm hoặc FranchiseWallet.View, thuộc bưu cục nhượng quyền).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementItem">
            <summary>Một phiếu đối soát tháng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementItem.PeriodLabel">
            <summary>"11/2026".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseStatementLineItem">
            <summary>Một dòng bảng kê hoá đơn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseK1AppendixItem">
            <summary>Một đơn của phụ lục K1.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseK1AppendixItem.CollectedBy">
            <summary>"Bưu cục tự thu" hoặc người đã thu CƯỚC hộ (không kể tiền thu hộ COD, không kể khoản đã đảo).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementActions">
            <summary>Quyền thao tác trên đúng phiếu này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementActions.CanAddAdjustment">
            <summary>Thêm điều chỉnh tay "vào kỳ" của phiếu nháp này (cần cả quyền quản lý phiếu lẫn quyền điều chỉnh Ví).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementDetail">
            <summary>Chi tiết phiếu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementDetail.Minutes">
            <summary>Ví v2: biên bản đối chiếu tháng — đầu kỳ, phát sinh theo mã, nạp, rút, cuối kỳ (plan §3.6).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementDetail.SaleToCustomer">
            <summary>Ví v2: chiều 3 — cước bưu cục sale lập hoá đơn cho khách (E5, CK-THẲNG, đơn hoàn).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementDetail.SaleToCustomerTotal">
            <summary>Tổng chiều 3.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementDetail.IntraRegionOrders">
            <summary>V-65: đơn nội vùng của kỳ (cước chính thức = cước tạm tính) kèm cân khai — kế toán kiểm xác suất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementDetail.IntraRegionTotal">
            <summary>Tổng cước các đơn nội vùng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseIntraRegionOrderItem">
            <summary>Một đơn nội vùng của phiếu tháng (V-65).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseIntraRegionOrderItem.LockedAt">
            <summary>Lúc chốt cước chính thức (= lúc đơn được nhận diện nội vùng).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseIntraRegionOrderItem.DeclaredWeightGram">
            <summary>Cân khai (gram) — Σ cân kiện lúc tạo đơn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseIntraRegionOrderItem.Fee">
            <summary>Cước tạm tính = cước chính thức.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementMinutesItem">
            <summary>Biên bản đối chiếu tháng (Ví v2): Đầu kỳ + Phát sinh + Nạp + Rút = Cuối kỳ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementMinutesItem.MovementTotal">
            <summary>Phát sinh nghiệp vụ (mã E, điều chỉnh tay) — không gồm nạp / rút.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementMinutesItem.WithdrawalTotal">
            <summary>Rút ròng (rút − hoàn lệnh rút bị huỷ / từ chối), số âm.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSaleToCustomerItem">
            <summary>Một dòng chiều 3 của bảng kê.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementGenerateItem">
            <summary>Kết quả lập nháp hàng loạt.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementAgencyItem">
            <summary>Một bưu cục nhượng quyền trong ô lọc / hộp lập phiếu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseSettlementFileResult">
            <summary>File tải về.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletNavPermissionItem">
            <summary>Cờ hiển thị của màn Ví bưu cục (nav-permissions).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletNavPermissionItem.CanViewOwn">
            <summary>Bưu cục xem ví của chính mình.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletNavPermissionItem.CanManage">
            <summary>Kế toán LADA: xem mọi ví, tạo điều chỉnh, duyệt lần 1, đối chiếu lại đơn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletNavPermissionItem.CanApprove">
            <summary>Duyệt lần 2 điều chỉnh từ ngưỡng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletNavPermissionItem.DualApprovalThreshold">
            <summary>Ngưỡng cần người duyệt thứ hai.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletNavPermissionItem.CanConfig">
            <summary>Bật ví cho chi nhánh / sửa tham số ví (Ví v2, role FranchiseWallet.Config hoặc Founder).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletNavPermissionItem.CanWithdraw">
            <summary>Tạo / huỷ lệnh rút của ví bưu cục mình (Ví v2 GĐ C, role FranchiseWallet.Withdraw + thuộc bưu cục nhượng quyền).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletNavPermissionItem.CanTreasury">
            <summary>Kế toán quỹ: ghi nhận nạp, chuyển / từ chối lệnh rút (Ví v2 GĐ C, role FranchiseWallet.Treasury hoặc Founder).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletNavPermissionItem.CanViewEntries">
            <summary>Đọc dòng Ví / tóm tắt / đơn nợ cước / dự kiến phí (View thuộc bưu cục nhượng quyền, Manage, Approve) — plan §3.8.1.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletNavPermissionItem.CanSeeAll">
            <summary>Thấy mọi ví: sổ vấn đề, duyệt / từ chối điều chỉnh, ô chọn bưu cục (Manage, Approve).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletNavPermissionItem.CanListWallets">
            <summary>Danh sách ví (Manage, Approve, Config, Treasury) — kế toán quỹ chọn bưu cục khi ghi nạp, kế toán trưởng mở cấu hình (V-47).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletNavPermissionItem.CanSeeFunds">
            <summary>Xem lệnh rút / khoản nạp: bưu cục (ví mình — View hoặc Withdraw) và LADA (Manage, Approve, Treasury).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletNavPermissionItem.OwnAgencyId">
            <summary>Bưu cục của người dùng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletNavPermissionItem.OwnAgencyName">
            <summary>Tên bưu cục của người dùng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntryItem">
            <summary>Một dòng Ví.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntryItem.CountsInBalance">
            <summary>Dòng có vào số dư không.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntryItem.Basis">
            <summary>Cách tính đọc được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntryItem.CashierAgencyName">
            <summary>Tên bưu cục / chi nhánh của người thu tiền.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntryItem.ReferenceEntryId">
            <summary>Dòng gốc mà điều chỉnh tay này điều chỉnh.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntryItem.SettlementCode">
            <summary>Mã phiếu đối soát (BB-…) — chỉ điền ở chi tiết một dòng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntryItem.NeedsSecondApproval">
            <summary>Điều chỉnh tay đang chờ người duyệt thứ hai.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntryItem.OrderRole">
            <summary>Vai của bưu cục trên đơn khi ghi dòng (Ví v2): 1 bán (S) · 2 lấy (L) · 3 phát (P) · 4 phát hoàn (PH).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntryItem.BaseAmount">
            <summary>Cước / COD dùng để tính dòng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntryItem.BaseIsOfficial">
            <summary>Cơ sở tính là cước chính thức (đã chốt khi nhập kho) hay tạm tính.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntryItem.BaseLabel">
            <summary>Cơ sở tính đọc được — "Cước chính thức 246.000 đ", "COD 2.500.000 đ".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntryItem.PayFeeTypeAtEvent">
            <summary>Hình thức trả cước của đơn tại sự kiện ghi dòng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntrySearchResult">
            <summary>Danh sách dòng Ví kèm tổng (khuôn <c>TransactionSearchResult</c>: tổng do máy chủ tính trên toàn phạm vi lọc, không theo trang).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntrySearchResult.Balance">
            <summary>Số dư hiện tại của ví (mọi thời gian, mọi dòng vào số dư).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntrySearchResult.ProvisionalTotal">
            <summary>Tổng tạm tính hiện tại (chưa vào số dư).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntrySearchResult.PostedTotalInFilter">
            <summary>Tổng các dòng vào số dư trong phạm vi lọc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEntrySearchResult.ProvisionalTotalInFilter">
            <summary>Tổng tạm tính trong phạm vi lọc.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletTypeTotal">
            <summary>Tổng một loại dòng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletSummaryItem">
            <summary>Tóm tắt ví của một bưu cục trong một khoảng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletSummaryItem.IsFranchise">
            <summary>Bưu cục nhượng quyền (chịu ngưỡng / rút); false = chi nhánh LADA bật ví chỉ để đo.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletSummaryItem.WalletEnabled">
            <summary>Ví đã bật (Active ∧ EnabledAt).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletSummaryItem.MaxWithdrawable">
            <summary>Số rút được ngay = số dư − tạm giữ − số dư tối thiểu (≥ 0); chỉ bưu cục nhượng quyền đã bật ví.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletSummaryItem.BelowWarning">
            <summary>Số dư dưới ngưỡng cảnh báo (bằng ngưỡng không tính).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletSummaryItem.BankLabel">
            <summary>Tài khoản nhận tiền rút đã khai.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEnabledItem">
            <summary>Một ví trong danh sách của LADA.</summary>
            <summary>Kết quả bật ví cho một chi nhánh (Ví v2, <c>POST api/FranchiseWallet/wallets/enable</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEnabledItem.AgencyType">
            <summary>2 = bưu cục nhượng quyền, 3 = chi nhánh LADA.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEnabledItem.AlreadyEnabled">
            <summary>Ví đã bật từ trước — lần gọi này không đổi gì.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletEnabledItem.BlockOutbound">
            <summary>Cờ chặn xuất kho theo ví (bưu cục nhượng quyền: bật; chi nhánh LADA: tắt — chỉ ghi để đo).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletListItem.AgencyType">
            <summary>2 = bưu cục nhượng quyền, 3 = chi nhánh LADA.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletListItem.BelowWarning">
            <summary>Bưu cục nhượng quyền đã bật ví có số dư dưới ngưỡng cảnh báo.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletConfigChangeItem">
            <summary>Một lần đổi cấu hình ví (tham số / tài khoản) — plan §3.10 "Tham số: mỗi lần đổi ghi lịch sử".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWalletConfigChangeItem.Changes">
            <summary>Nội dung đổi đọc được: "Số dư tối thiểu: 20.000.000 → 15.000.000; Tài khoản nhận: … → …".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseOrderForecastItem">
            <summary>Dự kiến phí của một đơn nếu giao thành công từ trạng thái hiện tại (<c>GET api/FranchiseWallet/orders/{id}/forecast</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseOrderForecastItem.Total">
            <summary>Tổng các dòng trả về = ví thay đổi dự kiến (gồm cả dòng giữ tiền bưu cục đang cầm).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseOrderForecastItem.GrossMargin">
            <summary>Lãi gộp dự kiến: tổng trừ các dòng giữ tiền E1 / E2 / E3 / E9 (tiền mặt cầm hộ, không phải lãi / lỗ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseOrderForecastItem.BasedOnProvisionalFee">
            <summary>Chưa chốt cước chính thức — số theo cước tạm tính.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseOrderForecastItem.Agencies">
            <summary>
            Tổng + lãi gộp theo từng bưu cục có dòng (V-56) — LADA xem đơn nhiều bưu cục thì <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseOrderForecastItem.GrossMargin"/> cộng lẫn phí của
            nhiều bên, không còn là "lãi gộp của bưu cục"; bưu cục chỉ thấy dòng mình nên luôn một phần tử.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseOrderForecastAgencyItem">
            <summary>Dự kiến phí của một bưu cục trên đơn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseOrderForecastLineItem">
            <summary>Một dòng dự kiến.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLedgerIssueItem">
            <summary>Một vấn đề ghi Ví cần soát.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLedgerIssueItem.IssueKind">
            <summary>Loại vấn đề (V-24): 0 luật · 1 lỗi kỹ thuật · 2 chặn xuất kho · 3 bất biến T17 · 4 ghi chú chốt cước.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLedgerIssueItem.AgencyId">
            <summary>Bưu cục liên quan (chặn xuất kho: bưu cục phát).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLedgerIssueItem.IsResolved">
            <summary>Đã tự đóng (lượt đối chiếu / kiểm bất biến sau không còn gặp).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.CustomerOwnerAgencyItem">
            <summary>Bưu cục sở hữu một khách.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.CustomerOwnerAgencyItem.CanEdit">
            <summary>Người xem được sửa bưu cục sở hữu (role <c>Customer.CreateOrUpdate</c> / Founder) — giao diện ẩn ô chọn khi false.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.CustomerOwnerAgencyItem.Options">
            <summary>Bưu cục nhượng quyền chọn được.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLedgerReconcileItem">
            <summary>Kết quả đối chiếu lại một đơn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWithdrawalItem">
            <summary>Một lệnh rút tiền ví (Ví v2 §3.5).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWithdrawalItem.EntryId">
            <summary>Dòng RUT đã trừ ví.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWithdrawalItem.ReversalEntryId">
            <summary>Dòng RUT-HOAN hoàn ví (từ chối / huỷ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWithdrawalItem.ReversalPendingApproval">
            <summary>Dòng RUT-HOAN đang chờ người duyệt thứ hai (từ chối từ ngưỡng duyệt hai người) — ví CHƯA được hoàn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWithdrawalListItem">
            <summary>Danh sách lệnh rút kèm số rút tối đa hiện tại của ví (khi xem một ví).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWithdrawalListItem.AgencyId">
            <summary>Ví đang xem (null = nhiều ví).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWithdrawalListItem.Balance">
            <summary>Số dư hiện tại của ví đang xem.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWithdrawalListItem.MaxWithdrawable">
            <summary>Số tối đa rút được ngay lúc này = số dư − tạm giữ − số dư tối thiểu (≥ 0).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseWithdrawalListItem.BankLabel">
            <summary>Tài khoản nhận tiền rút đã khai của ví đang xem.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseDepositItem">
            <summary>Một khoản nạp ví (Ví v2 §3.5).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseDepositItem.EntryId">
            <summary>Dòng NAP đã cộng ví.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseDepositItem.BalanceAfter">
            <summary>Số dư ví sau khi ghi nhận (chỉ có ở kết quả ghi nhận).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseReturnFeeDebtItem">
            <summary>Một khoản khách nợ cước đơn hoàn (dòng NO-CUOC) — danh sách đơn nợ cước của bưu cục sale (mota L2-4).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseReturnFeeDebtItem.EntryId">
            <summary>Dòng NO-CUOC.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseReturnFeeDebtItem.Amount">
            <summary>Cước đi + hoàn khách còn nợ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseReturnFeeDebtItem.EventAt">
            <summary>Hoàn thành công lúc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseReturnFeeDebtItem.SlipId">
            <summary>Phiếu đối soát khách đang giữ chỗ / đã cấn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseReturnFeeDebtItem.OffsetOrderId">
            <summary>Đơn COD đã / sẽ bị cấn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceResult`1">
            <summary>
            Vỏ kết quả chung của API bảng giá nội bộ: <c>Result</c>/<c>Message</c> như mọi API, kèm dữ liệu, cờ 403 và danh sách
            lỗi / cảnh báo để màn hình in từng dòng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceResult`1.Data">
            <summary>Dữ liệu (null khi thất bại).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceResult`1.IsForbidden">
            <summary>Bị từ chối vì quyền / phạm vi (controller trả HTTP 403).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceResult`1.IsNotFound">
            <summary>Không tìm thấy (controller trả HTTP 404).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceResult`1.Errors">
            <summary>Các lý do chặn (in từng dòng).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceResult`1.Warnings">
            <summary>Cảnh báo không chặn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceResult`1.Ok(`0,System.String,System.Collections.Generic.IEnumerable{System.String})">
            <summary>Thành công.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceResult`1.Fail(System.String,System.Collections.Generic.IEnumerable{System.String})">
            <summary>Thất bại nghiệp vụ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceResult`1.Forbidden(System.String)">
            <summary>Bị từ chối quyền.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceResult`1.NotFound(System.String)">
            <summary>Không tìm thấy.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceFileResult">
            <summary>File Excel một phiên bản bảng giá (GĐ5).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceNavPermissionItem">
            <summary>Cờ hiển thị của trang bảng giá nội bộ (nav-permissions).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceNavPermissionItem.CanManage">
            <summary>Soạn / sửa nháp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceNavPermissionItem.CanApprove">
            <summary>Duyệt / huỷ / đặt ngày ngừng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceNavPermissionItem.CanViewOwn">
            <summary>Xem bản áp cho bưu cục của mình (có role View và thuộc bưu cục nhượng quyền).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceNavPermissionItem.OwnAgencyId">
            <summary>Bưu cục của người dùng (0 = không thuộc bưu cục nào).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceNavPermissionItem.OwnAgencyName">
            <summary>Tên bưu cục của người dùng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceNavPermissionItem.HasViewRole">
            <summary>Có role xem bảng của bưu cục (để màn hình nói đúng lý do khi CanViewOwn = false).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceNavPermissionItem.OwnAgencyIsFranchise">
            <summary>Bưu cục của người dùng là bưu cục nhượng quyền.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceAgencyOption">
            <summary>Một bưu cục nhượng quyền để chọn phạm vi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceAgencyOption.Id">
            <summary>Id.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceAgencyOption.Code">
            <summary>Mã.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceAgencyOption.Name">
            <summary>Tên.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceAgencyOption.Status">
            <summary>Trạng thái hoạt động (<c>AgencyStatus</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceAgencyOption.IsActive">
            <summary>Đang hoạt động.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceVersionItem">
            <summary>Một dòng danh sách phiên bản.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceVersionItem.KindCode">
            <summary><c>gia_mua_don</c> / <c>phi_lay</c> / <c>phi_giao</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceVersionItem.DisplayStatus">
            <summary>Trạng thái suy từ ngày (Nháp / Sắp / Đang / Hết hiệu lực / Huỷ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceVersionItem.EffectiveTo">
            <summary>Ngày ngừng áp dụng tường minh.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceVersionItem.EffectiveEnd">
            <summary>Ngày kết thúc thực (tường minh, hoặc ngày bản sau thay); null = chưa kết thúc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceVersionItem.ScopeLabel">
            <summary>"Toàn mạng" hoặc "3 bưu cục: A, B, C".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceCellItem">
            <summary>Một ô của phiên bản (kèm giá niêm yết hiện tại để soi lệch).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceCellItem.WeightLabel">
            <summary>"1–3 kg".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceCellItem.BasePrice">
            <summary>Giá niêm yết lúc chụp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceCellItem.CurrentBasePrice">
            <summary>Giá niêm yết hiện tại của nấc (null = nấc không còn trong niêm yết).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceMatrixRow">
            <summary>Một hàng của ma trận (một dải; phí lấy / giao chỉ có một hàng với RouteId null).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceMatrixRow.DistanceMin">
            <summary>Khoảng cách từ (mét, không gồm) — null với hàng "mọi dải".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceMatrixRow.DistanceMax">
            <summary>Khoảng cách đến (mét, gồm).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceMatrixColumn">
            <summary>Một cột của ma trận (một nấc cân).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceMatrixColumn.Unit">
            <summary>"đ/đơn" hoặc "đ/kg".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceFrameDiffItem">
            <summary>Một nấc lệch khung.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceVersionActions">
            <summary>Quyền thao tác của người đang xem trên đúng bản này.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceVersionDetail">
            <summary>Chi tiết một phiên bản.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceVersionDetail.IsFrameAligned">
            <summary>Khớp khung niêm yết hiện tại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceVersionDetail.ApprovalBlockers">
            <summary>Lý do bấm Duyệt lúc này sẽ bị từ chối (xem trước, chỉ với bản nháp).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceVersionDetail.ApprovalWarnings">
            <summary>Cảnh báo khi duyệt (không chặn).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceVersionRef">
            <summary>Tham chiếu ngắn tới một phiên bản.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceVersionRef.IsDraftPreview">
            <summary>Đang dùng bản nháp thay bản hiệu lực (chỉ trong cân đối).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceRetainItem">
            <summary>Hai con số giữ lại của một cách bán.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceBalanceRowItem">
            <summary>Một dòng cân đối.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceBalanceRowItem.StepWeight">
            <summary>Bước cân (gram) — đơn vị "đ/bước" của ô cộng bước.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceBalanceItem">
            <summary>Kết quả kiểm tra cân đối.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceAgencyCellItem">
            <summary>Một ô trong màn xem của bưu cục.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceAgencyVersionItem">
            <summary>Một bản trong màn xem của bưu cục (không có ghi chú nội bộ / người soạn).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceAgencyVersionItem.AppliesFrom">
            <summary>Ngày bản này bắt đầu áp cho bưu cục (bản sắp áp có thể khác <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceAgencyVersionItem.EffectiveFrom"/>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceAgencyVersionItem.IsAgencySpecific">
            <summary>Bản riêng của bưu cục (true) hay bản toàn mạng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceApplicableTable">
            <summary>Bản đang và sắp áp của một bảng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceApplicableItem">
            <summary>Bảng giá áp cho một bưu cục.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceResolved">
            <summary>Bản áp dụng đã tra kèm ô — dùng lại cho Ví bưu cục (GĐ2).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Items.Network.InternalPriceResolved.#ctor(Lada.Framework.Data.Domains.Network.InternalPriceVersion,System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Network.InternalPriceCell})">
            <summary>Bản áp dụng đã tra kèm ô — dùng lại cho Ví bưu cục (GĐ2).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.OrderBusiness.OrderFailReasonItem">
            <summary>
            Item hiển thị lý do thất bại (Search/List)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.OrderBusiness.OrderFailReasonItem.Name">
            <summary>
            Tên/tiêu đề lý do thất bại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.OrderBusiness.OrderFailReasonItem.Description">
            <summary>
            Mô tả chi tiết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.OrderBusiness.OrderFailReasonItem.Type">
            <summary>
            Loại thất bại: 1 = Pickup, 2 = Delivery, 3 = Both
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.OrderBusiness.OrderFailReasonItem.TypeName">
            <summary>
            Tên loại thất bại (hiển thị)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.OrderBusiness.OrderFailReasonItem.IsMediaRequired">
            <summary>
            Có bắt buộc tải ảnh minh chứng không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.OrderBusiness.OrderFailReasonItem.MediaTitle">
            <summary>
            Tiêu đề/hướng dẫn ảnh cần tải
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.OrderBusiness.OrderFailReasonItem.SortOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.OrderBusiness.OrderFailReasonItem.IsActive">
            <summary>
            Trạng thái hoạt động
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.OrderBusiness.OrderFailReasonItem.CreatedTime">
            <summary>
            Ngày tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.OrderBusiness.OrderFailReasonItem.CreatedByUserName">
            <summary>
            Người tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.OrderBusiness.OrderFailReasonItem.UpdatedTime">
            <summary>
            Ngày cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.OrderBusiness.OrderFailReasonItem.UpdatedByUserName">
            <summary>
            Người cập nhật
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem">
            <summary>
            DTO item cho xuất Excel đơn hàng cơ bản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.OrderId">
            <summary>
            ID đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.OrderCode">
            <summary>
            Mã đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.PartnerCode">
            <summary>
            Mã đối tác
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.SaleName">
            <summary>
            Tên Sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.SenderName">
            <summary>
            Tên người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.SenderAddress">
            <summary>
            Địa chỉ người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.SenderPhone">
            <summary>
            Số điện thoại người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.ReceiverName">
            <summary>
            Tên người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.ReceiverAddress">
            <summary>
            Địa chỉ người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.ReceiverPhone">
            <summary>
            Số điện thoại người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.OrderStatus">
            <summary>
            Trạng thái đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.OrderPhysicalStatus">
            <summary>
            Trạng thái vật lý đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.ChargeWeight">
            <summary>
            Khối lượng tính cước (gram)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.ChargeWeightKg">
            <summary>
            Khối lượng tính cước (kg) - hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.TotalFee">
            <summary>
            Tổng cước phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.TotalFeeFormatted">
            <summary>
            Tổng cước phí (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.CollectAmount">
            <summary>
            Số tiền thu hộ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.CollectAmountFormatted">
            <summary>
            Số tiền thu hộ (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.PayFeeType">
            <summary>
            Loại thanh toán cước phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.OrderCreatedTime">
            <summary>
            Thời gian tạo đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.OrderCreatedTimeFormatted">
            <summary>
            Thời gian tạo đơn hàng (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.PickupTime">
            <summary>
            Thời gian lấy hàng thành công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.PickupTimeFormatted">
            <summary>
            Thời gian lấy hàng thành công (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.DeliveryTime">
            <summary>
            Thời gian giao hàng thành công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.DeliveryTimeFormatted">
            <summary>
            Thời gian giao hàng thành công (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.TotalPackages">
            <summary>
            Tổng số kiện
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.TotalWeight">
            <summary>
            Tổng khối lượng (gram)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.TotalWeightKg">
            <summary>
            Tổng khối lượng (kg) - hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.PackageContent">
            <summary>
            Nội dung hàng hóa
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.BasicOrderExportItem.Note">
            <summary>
            Ghi chú đơn hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem">
            <summary>
            DTO item cho xuất Excel đơn hàng - mục đích vận hành
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.OrderId">
            <summary>
            ID đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.OrderCode">
            <summary>
            Mã đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.PartnerCode">
            <summary>
            Mã đối tác
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.CustomerPhone">
            <summary>
            Số điện thoại khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.SaleName">
            <summary>
            Tên Sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.SalePhone">
            <summary>
            Số điện thoại Sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.SenderName">
            <summary>
            Tên người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.SenderFullAddress">
            <summary>
            Địa chỉ người gửi đầy đủ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.SenderPhone">
            <summary>
            Số điện thoại người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.ReceiverName">
            <summary>
            Tên người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.ReceiverFullAddress">
            <summary>
            Địa chỉ người nhận đầy đủ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.ReceiverPhone">
            <summary>
            Số điện thoại người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.SourceProvince">
            <summary>
            Tỉnh/Thành phố gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.SourceDistrict">
            <summary>
            Quận/Huyện gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.DestProvince">
            <summary>
            Tỉnh/Thành phố nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.DestDistrict">
            <summary>
            Quận/Huyện nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.OrderStatus">
            <summary>
            Trạng thái đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.OrderPhysicalStatus">
            <summary>
            Trạng thái vật lý đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.OrderDirection">
            <summary>
            Hướng đơn hàng (Nội tỉnh/Liên tỉnh)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.RouteName">
            <summary>
            Tuyến vận chuyển
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.CurrentWarehouse">
            <summary>
            Kho hiện tại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.PickupStaff">
            <summary>
            Nhân viên phụ trách lấy hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.DeliveryStaff">
            <summary>
            Nhân viên phụ trách giao hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.OrderCreatedTime">
            <summary>
            Thời gian tạo đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.OrderCreatedTimeFormatted">
            <summary>
            Thời gian tạo đơn hàng (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.PickupPlanTime">
            <summary>
            Thời gian lên kế hoạch lấy hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.PickupPlanTimeFormatted">
            <summary>
            Thời gian lên kế hoạch lấy hàng (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.DeployPickupTime">
            <summary>
            Thời gian triển khai lấy hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.DeployPickupTimeFormatted">
            <summary>
            Thời gian triển khai lấy hàng (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.PickupTime">
            <summary>
            Thời gian lấy hàng thành công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.PickupTimeFormatted">
            <summary>
            Thời gian lấy hàng thành công (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.DeployDeliveryTime">
            <summary>
            Thời gian triển khai giao hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.DeployDeliveryTimeFormatted">
            <summary>
            Thời gian triển khai giao hàng (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.DeliveryTime">
            <summary>
            Thời gian giao hàng thành công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.DeliveryTimeFormatted">
            <summary>
            Thời gian giao hàng thành công (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.TotalPackages">
            <summary>
            Tổng số kiện
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.TotalWeight">
            <summary>
            Tổng khối lượng (gram)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.TotalWeightKg">
            <summary>
            Tổng khối lượng (kg) - hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.ChargeWeight">
            <summary>
            Khối lượng tính cước (gram)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.ChargeWeightKg">
            <summary>
            Khối lượng tính cước (kg) - hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.PackageContent">
            <summary>
            Nội dung hàng hóa
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.PackageValue">
            <summary>
            Giá trị hàng hóa
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.PackageValueFormatted">
            <summary>
            Giá trị hàng hóa (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.TotalFee">
            <summary>
            Tổng cước phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.TotalFeeFormatted">
            <summary>
            Tổng cước phí (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.CollectAmount">
            <summary>
            Số tiền thu hộ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.CollectAmountFormatted">
            <summary>
            Số tiền thu hộ (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.PayFeeType">
            <summary>
            Loại thanh toán cước phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.CodStage">
            <summary>
            Trạng thái thu COD
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.Note">
            <summary>
            Ghi chú đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.OperationNote">
            <summary>
            Ghi chú vận hành
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.Priority">
            <summary>
            Độ ưu tiên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OperationsOrderExportItem.SpecialService">
            <summary>
            Dịch vụ đặc biệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderAddressItem.AddressLevelType">
            <summary>
            Phân loại địa chỉ: 2 cấp hoặc 3 cấp
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderAddressItem.CityName">
            <summary>
            Tên thành phố (dùng cho hiển thị tuyến)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderAddressItem.Lat">
            <summary>
            Vĩ độ điểm lấy/giao. Null nếu chưa xác định được vị trí.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderAddressItem.Long">
            <summary>
            Kinh độ điểm lấy/giao. Null nếu chưa xác định được vị trí.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderAddressItem.CoordSource">
            <summary>
            Nguồn toạ độ: 0 = chưa có, 1 = ghim chính xác (địa chỉ đã có toạ độ hoặc
            đã geocode), 2 = tâm phường/xã (gần đúng, chỉ để định vị sơ bộ trên bản đồ).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderAddressItem.ScheduledTime">
            <summary>
            Thời gian hẹn lấy / giao hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderAddressItem.CanEdit">
            <summary>
            Cho phép sửa hay không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderFinItem.GoodsAttributeFee">
            <summary>
            Phụ phí theo thuộc tính loại hàng (0 với đơn không chọn danh mục)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderFinItem.SourceFeeCollectedAmount">
            <summary>Số lái xe thực thu của người gửi khi lấy (Ví v2 E1 đã neo số này) — màn thu tiền người gửi hiện thay cước (V-27).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderFinItem.ReconciliationAmount">
            <summary>
            Tiền đối soát dựa trên PayFeeType
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderGoodsAttributeItem">
            <summary>
            Thuộc tính loại hàng đã lưu trên đơn (snapshot tại thời điểm lên đơn / sửa đơn)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderGoodsAttributeItem.OrderPackageId">
            <summary>
            Kiện hàng mang thuộc tính này. <c>null</c> = thuộc tính khai ở cấp đơn (đơn cũ, hoặc kênh chưa
            khai loại hàng theo kiện).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderGoodsAttributeItem.AttributeId">
            <summary>
            Id thuộc tính gốc, dùng để dựng lại lựa chọn khi sửa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderGoodsAttributeItem.OptionId">
            <summary>
            Id lựa chọn gốc, null với kiểu nhập văn bản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderGoodsAttributeItem.AttributeName">
            <summary>
            Tên thuộc tính tại thời điểm lưu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderGoodsAttributeItem.AttributeTypeName">
            <summary>
            Mô tả tiếng Việt của kiểu thuộc tính
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderGoodsAttributeItem.OptionLabel">
            <summary>
            Nhãn lựa chọn tại thời điểm lưu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderGoodsAttributeItem.Price">
            <summary>
            Giá tại thời điểm lưu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderGoodsAttributeItem.ValueText">
            <summary>
            Giá trị khách nhập với kiểu nhập văn bản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderGoodsAttributeItem.ValueNumber">
            <summary>
            Giá trị khách nhập với kiểu khoảng số
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderItem.Code">
            <summary>
            Mã vận đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderItem.PartnerCode">
            <summary>
            Mã đối tác
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderItem.Note">
            <summary>
            Ghi chú đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderItem.CustomerId">
            <summary>
            Đơn hàng của khách hàng nào
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderItem.SellerAgencyId">
            <summary>Bưu cục bán (Ví v2 — vai S trên màn Đơn hàng bưu cục).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderItem.SaleId">
            <summary>
            Đơn hàng của sale nào
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderItem.RouteName">
            <summary>
            Tuyến
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderItem.MediaItems">
            <summary>
            Danh sách ảnh của đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderItem.GoodsCategoryId">
            <summary>
            Danh mục hàng hóa khách chọn (Category có ContentType = GoodsType)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderItem.GoodsAttributes">
            <summary>
            Thuộc tính loại hàng đã lưu trên đơn (snapshot). Rỗng với đơn cũ / đơn không phân loại.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderItem.TimeTrack">
            <summary>
            Thông tin thời gian (tạm thời để lưu dữ liệu cho xuất Excel)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderListItem.Code">
            <summary>
            Mã đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderListItem.Note">
            <summary>
            Ghi chú đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderListItem.CustomerId">
            <summary>
            Đơn hàng của khách hàng nào
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderListItem.SaleId">
            <summary>
            Đơn hàng của sale nào
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderMediaItem">
            <summary>
            Một ảnh gắn với đơn hàng (bảng <c>Media</c>) kèm mốc sự kiện đã sinh ra nó
            (<c>OrderTrack</c>: lấy hàng, giao hàng, trả hàng, nhập/xuất kho...).
            </summary>
            <remarks>
            App tài xế nhóm ảnh theo <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderMediaItem.OrderTrackId"/> và dùng <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderMediaItem.TrackName"/> làm tiêu đề nhóm —
            tên track do hệ thống sinh sẵn bằng tiếng Việt ("X lấy hàng thành công.") nên không cần app tự
            suy diễn từ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderMediaItem.TrackActionType"/>, vốn có nhiều giá trị trùng mô tả.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderMediaItem.Url">
            <summary>Đường dẫn tải ảnh (đã đổi từ <c>SystemPath</c> sang URL).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderMediaItem.OrderTrackId">
            <summary>Sự kiện sinh ra ảnh; <c>Guid.Empty</c> nếu ảnh không gắn với track nào.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderMediaItem.TrackName">
            <summary>Tên sự kiện (tiếng Việt, hệ thống sinh) — rỗng nếu không tìm thấy track.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderMediaItem.TrackTime">
            <summary>Thời điểm sự kiện; null nếu không tìm thấy track.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageItem.Picture">
            <summary>
            Ảnh kiện hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageItem.GoodsCategoryId">
            <summary>
            Loại hàng của riêng kiện này, <c>null</c> = kiện không khai loại (đơn cũ dùng loại cấp đơn).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageItem.GoodsCategoryName">
            <summary>
            Tên loại hàng của kiện — điền ở tầng service, rỗng khi kiện không khai loại.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageItem.GoodsAttributes">
            <summary>
            Thuộc tính loại hàng đã lưu cho riêng kiện này (snapshot lúc lên đơn).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageResponseItem">
            <summary>
            Response item cho OrderPackage với thông tin đơn vị đo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageResponseItem.Picture">
            <summary>
            Ảnh kiện hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageResponseItem.Weight">
            <summary>
            Trọng lượng (đã chuyển đổi về đơn vị client)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageResponseItem.Length">
            <summary>
            Chiều dài (đã chuyển đổi về đơn vị client)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageResponseItem.Width">
            <summary>
            Chiều rộng (đã chuyển đổi về đơn vị client)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageResponseItem.Height">
            <summary>
            Chiều cao (đã chuyển đổi về đơn vị client)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageResponseItem.SubTotalWeight">
            <summary>
            Tổng trọng lượng (đã chuyển đổi về đơn vị client)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageResponseItem.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageResponseItem.GoodsCategoryId">
            <summary>
            Loại hàng của riêng kiện này, <c>null</c> = kiện không khai loại (đơn cũ dùng loại cấp đơn).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageResponseItem.WeightUnit">
            <summary>
            Đơn vị trọng lượng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageResponseItem.DimensionUnit">
            <summary>
            Đơn vị kích thước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageResponseItem.WeightUnitDescription">
            <summary>
            Mô tả đơn vị trọng lượng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderPackageResponseItem.DimensionUnitDescription">
            <summary>
            Mô tả đơn vị kích thước
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Premises.PremiseItem">
            <summary>
            Item hiển thị danh sách mặt bằng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Premises.PremiseContactItem">
            <summary>
            Item hiển thị thông tin liên hệ
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Premises.PremiseScoreItem">
            <summary>
            Item hiển thị điểm chấm
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Premises.PremiseScoringCriteriaItem">
            <summary>
            Item hiển thị tiêu chí chấm điểm (cho admin và cho NV khi chấm điểm)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Premises.PremiseScoringCriteriaItem.Options">
            <summary>
            Danh sách options kèm điểm
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Premises.PremiseScoringOptionItem">
            <summary>
            Item hiển thị option
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Promotions.PromotionProgramItem">
            <summary>
            Item hiển thị trong danh sách chương trình khuyến mãi
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Promotions.PromotionCodeItem">
            <summary>
            Item hiển thị trong danh sách mã khuyến mãi
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Promotions.PromotionUsageLogItem">
            <summary>
            Item hiển thị trong log sử dụng khuyến mãi
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Rewards.AutoPenaltyConfigItem">
            <summary>
            Item DTO cho danh sách cấu hình phạt tự động (Search)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.CallPathGetAllItem">
            <summary>
            DTO đơn giản cho API GetAll CallPath (dùng cho mobile/client).
            Path = Domain + RelativePath (đã gộp sẵn).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.CallPathGetAllItem.Name">
            <summary>
            Tên call path (ví dụ: ACCOUNT_REFRESH_TOKEN)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.CallPathGetAllItem.Path">
            <summary>
            Đường dẫn đầy đủ = Domain + RelativePath (ví dụ: https://srv.v2.ladaexpress.vn/api/Account/RefreshToken)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.CallPathGetAllItem.Description">
            <summary>
            Mô tả
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.CallPathItem">
            <summary>
            Represents a CallPath data transfer object
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.CallPathItem.Name">
            <summary>
            Gets or sets the name
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.CallPathItem.RelativePath">
            <summary>
            Gets or sets the relative path
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.CallPathItem.Description">
            <summary>
            Gets or sets the description
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.CallPathVersionItem">
            <summary>
            Item cho CallPathVersion - dùng cho Search/GetAll
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.CallPathVersionItem.Version">
            <summary>
            Số phiên bản (ví dụ: 1.0.0)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.CallPathVersionItem.Build">
            <summary>
            Số build (ví dụ: 101)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.CallPathVersionItem.Domain">
            <summary>
            Domain cơ sở (ví dụ: https://api.ladaexpress.vn)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.CallPathVersionItem.Description">
            <summary>
            Mô tả phiên bản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.CallPathVersionItem.IsDefault">
            <summary>
            Đánh dấu phiên bản mặc định
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.CallPathVersionItem.CallPathCount">
            <summary>
            Số lượng CallPath thuộc phiên bản này
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireOverviewItem">
            <summary>
            Tổng quan hàng đợi Hangfire: số liệu theo trạng thái, server đang chạy, queue.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireOverviewItem.Servers">
            <summary>Số server Hangfire đang gửi heartbeat.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireOverviewItem.Recurring">
            <summary>Số tác vụ định kỳ đã đăng ký.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireOverviewItem.Enqueued">
            <summary>Số job đang nằm trong queue chờ worker nhận.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireOverviewItem.Queues">
            <summary>Số queue.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireOverviewItem.Scheduled">
            <summary>Số job đã lên lịch (chạy sau).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireOverviewItem.Processing">
            <summary>Số job đang được worker xử lý.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireOverviewItem.Succeeded">
            <summary>Số job chạy thành công (còn trong cửa sổ lưu trữ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireOverviewItem.Failed">
            <summary>Số job thất bại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireOverviewItem.Deleted">
            <summary>Số job đã xoá.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireOverviewItem.ServerList">
            <summary>Danh sách server đang chạy.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireOverviewItem.QueueList">
            <summary>Danh sách queue.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireServerItem">
            <summary>
            Một server Hangfire (một tiến trình API đang chạy worker).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireQueueItem">
            <summary>
            Một queue Hangfire cùng số job đang chờ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireRecurringJobItem">
            <summary>
            Tác vụ định kỳ đã đăng ký bằng RecurringJob.AddOrUpdate.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireRecurringJobItem.Id">
            <summary>Id tác vụ, ví dụ notification-cleanup.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireRecurringJobItem.Cron">
            <summary>Biểu thức cron 5 trường.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireRecurringJobItem.JobName">
            <summary>Tên lớp.phương thức sẽ chạy, ví dụ NotificationCleanupJob.Execute.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireRecurringJobItem.Error">
            <summary>Lỗi khi Hangfire không lên lịch được (cron sai, không nạp được kiểu...).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireRecurringJobItem.Removed">
            <summary>Đã bị gỡ khỏi lịch (RemoveIfExists) nhưng còn lưu vết.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireRecurringJobItem.DisplayName">
            <summary>Tên hiển thị tiếng Việt (từ danh mục; job ngoài danh mục dùng Id).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireRecurringJobItem.Description">
            <summary>Job làm gì (từ danh mục).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireRecurringJobItem.InCatalog">
            <summary>Có trong RecurringJobCatalog — tức tạm dừng rồi đăng ký lại được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireRecurringJobItem.AutoRegister">
            <summary>Tự đăng ký khi API khởi động (trừ khi đã tạm dừng).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireRecurringJobItem.DefaultCron">
            <summary>Cron mặc định trong danh mục (dùng khi bấm Đăng ký).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireRecurringJobItem.IsRegistered">
            <summary>Đang nằm trong lịch Hangfire (có bản ghi và chưa bị gỡ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireRecurringJobItem.IsPaused">
            <summary>Đã bị tạm dừng từ trang Tác vụ nền — không tự đăng ký lại khi khởi động.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireJobItem">
            <summary>
            Một job trong danh sách theo trạng thái.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireJobItem.State">
            <summary>Trạng thái đang liệt kê: Processing / Scheduled / Enqueued / Succeeded / Failed / Deleted.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireJobItem.InState">
            <summary>Job có còn ở đúng trạng thái này không (false nghĩa là đã chuyển trạng thái khác sau khi liệt kê).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireJobItem.At">
            <summary>Thời điểm vào trạng thái (bắt đầu chạy / thành công / thất bại / xoá...).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireJobItem.EnqueueAt">
            <summary>Thời điểm dự kiến đưa vào queue (job Scheduled).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireJobItem.DurationMs">
            <summary>Tổng thời gian chạy tính bằng mili giây (job Succeeded).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireJobPageItem">
            <summary>
            Một trang job theo trạng thái.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireJobDetailItem">
            <summary>
            Chi tiết một job kèm lịch sử chuyển trạng thái.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Settings.HangfireJobStateItem">
            <summary>
            Một bước trong lịch sử trạng thái của job.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAssignmentItem">
            <summary>
            Một lượt giữ hội thoại, đọc được — dòng của màn "ai từng cầm hội thoại này".
            <para>
            Danh sách trắng như <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelStaffItem"/>: chỉ tên hiển thị, không tên đăng
            nhập, không thông tin liên hệ.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAssignmentItem.StaffId">
            <summary>Người giữ lượt này (chính là <c>User.Id</c>)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAssignmentItem.ReleasedAt">
            <summary>Bỏ trống nghĩa là người này <b>đang</b> giữ hội thoại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAssignmentItem.IsAuto">
            <summary>Máy quyết hay người quyết</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAssignmentItem.ActorUserId">
            <summary>Người bấm nút; bỏ trống là máy quyết</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAssignmentItem.KeepReadAccess">
            <summary>
            Người này còn đọc được hội thoại sau khi thôi giữ không — hiển thị để quản lý thấy
            được hệ quả thật của lý do đã chọn, chứ không phải một ô để sửa.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem">
            <summary>
            DTO trả về cho danh sách và chi tiết kênh chat.
            <para>
            Lớp này KHÔNG có trường nào chứa token, kể cả dạng đã che. Che chuỗi vẫn là lộ một phần
            chuỗi, mà câu hỏi duy nhất giao diện cần trả lời là "kênh đã có token chưa, còn hạn tới bao
            giờ" — hai giá trị bên dưới đủ. Danh sách trường ở đây là danh sách trắng: thứ gì không
            khai ở đây thì không có đường ra khỏi máy chủ.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem.Platform">
            <summary>Nền tảng của kênh</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem.PlatformStr">
            <summary>Tên nền tảng để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem.ExternalChannelId">
            <summary>Định danh kênh phía nền tảng (OA id với Zalo, Page id với Facebook)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem.HasAccessToken">
            <summary>Kênh đã có access token hay chưa — giao diện dùng để biết có cần bấm "Kết nối" không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem.HasRefreshToken">
            <summary>Kênh đã có refresh token hay chưa — thiếu là không tự làm mới được, phải cấp quyền lại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem.TokenExpiredAt">
            <summary>Thời điểm access token hết hạn (Zalo: 25 giờ kể từ lúc cấp)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem.IsTokenExpired">
            <summary>Token đã hết hạn tại thời điểm truy vấn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem.AuthorizedAt">
            <summary>Lần cấp quyền gần nhất</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem.LastRefreshedAt">
            <summary>Lần job làm mới token gần nhất</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem.IsActive">
            <summary>Kênh đang bật thì webhook mới nhận tin và mới gửi tin ra được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem.AgencyId">
            <summary>Bưu cục sở hữu kênh — nhãn tổ chức, không phải hàng rào quyền</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem.AgencyName">
            <summary>Tên bưu cục sở hữu kênh, rỗng khi chưa gắn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem.AssignmentMode">
            <summary>Chế độ phân phối — cũng là công tắc bật hàng rào quyền xem của kênh</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem.AssignmentModeStr">
            <summary>Tên chế độ phân phối để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem.StaffCount">
            <summary>Số nhân viên đang phụ trách kênh này</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelStaffItem">
            <summary>
            Một dòng trong danh sách nhân viên phụ trách một kênh chat.
            <para>
            Danh sách trắng: chỉ đủ để giao diện dựng bảng phụ trách. Không có tên đăng nhập, không có
            số điện thoại — cùng lý lẽ với <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatStaffOptionItem"/>.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelStaffItem.StaffId">
            <summary>Mã nhân viên (chính là <c>User.Id</c>)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelStaffItem.StaffName">
            <summary>Tên hiển thị của nhân viên</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelStaffItem.ChannelRoleStr">
            <summary>Tên vai trò để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelStaffItem.WeightOverride">
            <summary>Trọng số ép cứng, bỏ trống là tính theo điểm chất lượng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelStaffItem.OpenConversationCount">
            <summary>
            Số hội thoại chưa đóng người này còn đang giữ <b>trên chính kênh này</b>.
            <para>
            Yêu cầu tối thiểu của sổ nợ PP-18: nút Gỡ phải nói trước "người này còn giữ N hội thoại"
            rồi mới hỏi xác nhận, vì gỡ xong chúng về hàng chờ và không còn ai đang theo dõi chúng.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationDetail">
            <summary>
            Chi tiết một hội thoại: phần đầu khung chat cộng với các tin nhắn đã nạp.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationDetail.Conversation">
            <summary>Thông tin hội thoại — cùng hình dạng với một dòng trong danh sách</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationDetail.Messages">
            <summary>Tin nhắn theo thứ tự thời gian tăng dần (tin cũ ở trên, tin mới ở dưới)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationDetail.TotalMessages">
            <summary>
            Tổng số tin của hội thoại. Lớn hơn số phần tử trong <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationDetail.Messages"/> nghĩa là
            còn tin cũ chưa nạp — giao diện dùng để biết có nên hiện nút "xem thêm" không.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem">
            <summary>
            Một dòng trong danh sách hội thoại, và cũng là phần đầu của khung chat.
            <para>
            Đây là danh sách trắng: entity <c>ChatConversation</c> có navigation sang
            <c>ChatChannel</c> và <c>Customer</c>, đẩy thẳng entity ra ngoài vừa lộ dữ liệu không cần
            thiết vừa làm bộ tuần tự của SignalR ném lỗi vòng tham chiếu (nó không kế thừa cấu hình
            <c>ReferenceLoopHandling.Ignore</c> của tầng MVC).
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.Platform">
            <summary>Nền tảng của hội thoại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.PlatformStr">
            <summary>Tên nền tảng để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.ChannelName">
            <summary>Tên kênh — một hệ thống có thể nối nhiều OA/Page nên phải phân biệt được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.ExternalUserId">
            <summary>Định danh khách phía nền tảng. Cần cho việc đối soát, không hiển thị thẳng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.ExternalUserName">
            <summary>
            Tên hiển thị của khách trên nền tảng. Rỗng khi chưa lấy được hồ sơ — giao diện phải
            tự lùi về một nhãn đọc được thay vì hiện ô trống.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.IsAnonymous">
            <summary>
            Khách của hội thoại này là người ẩn danh — nền tảng không cấp định danh bền vững.
            <para>
            Giao diện dựa vào cờ này để nói thẳng "khách ẩn danh" và để không mời gắn khách hàng.
            Không suy từ việc <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.ExternalUserName"/> rỗng: khách thường mà lời gọi lấy hồ sơ
            hỏng cũng rỗng y như vậy.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.CustomerId">
            <summary>Khách hàng trong hệ thống đã gắn với hội thoại này (giai đoạn D)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.CustomerName">
            <summary>Tên khách hàng đã gắn, rỗng khi chưa gắn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.AssignedStaffId">
            <summary>Nhân viên được phân công (giai đoạn D). v1 chỉ dùng để lọc, không chặn quyền xem</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.AssignedStaffName">
            <summary>
            Tên nhân viên được phân công, rỗng khi chưa phân công.
            <para>
            Không đến từ navigation — cột <c>AssignedStaffId</c> không có khoá ngoại sang bảng
            người dùng. Giá trị do <c>IChatStaffDirectory</c> tra và ĐƯỢC TRUYỀN VÀO mapper, nên
            mọi đường ghi DTO đều phải cung cấp nó (tham số bắt buộc, trình biên dịch canh giúp).
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.StatusStr">
            <summary>Tên trạng thái để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.LastMessage">
            <summary>Tóm tắt tin nhắn cuối cùng, dựng sẵn ở tầng lõi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.LastInboundAt">
            <summary>
            Lần cuối KHÁCH nhắn vào. Cửa sổ trả lời của mọi nền tảng đều tính từ mốc này
            (Zalo 48 giờ, Facebook 24 giờ).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.ReplyWindowHoursLeft">
            <summary>Số giờ còn lại của cửa sổ trả lời; âm là đã hết, null là chưa có tin vào nào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.SupportsReadReceipt">
            <summary>
            Nền tảng của hội thoại này có báo "khách đã xem" hay không.
            <para>
            Với Zalo là <c>false</c> — đã đo, nền tảng không gửi sự kiện đó (§6.9 kế hoạch).
            Giao diện dùng cờ này để nói thẳng rằng thang trạng thái dừng ở "Đã nhận", thay vì
            để nhân viên chờ một dấu hiệu không bao giờ sáng.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.SupportsQuotedReply">
            <summary>
            Hội thoại này có gửi được tin <b>trả lời trích dẫn</b> hay không.
            <para>
            Là câu trả lời cho từng hội thoại chứ không cho từng nền tảng: Zalo trả lời được với
            khách thường nhưng <b>không</b> với khách ẩn danh (endpoint v2.0 của luồng ẩn danh không
            có trường trích dẫn). Giao diện dùng cờ này để ẩn hẳn nút "Trả lời", thay vì để nhân
            viên soạn xong một câu rồi mới nhận lỗi.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.SupportsReaction">
            <summary>Hội thoại này có thả được biểu tượng cảm xúc lên tin nhắn hay không.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.ReactionEmojis">
            <summary>
            Bộ biểu tượng cảm xúc nền tảng chấp nhận, theo đúng thứ tự hiển thị.
            <b>Mảng rỗng nghĩa là không giới hạn</b> — giao diện được cho chọn biểu tượng bất kỳ
            (đó là trường hợp của Facebook; Zalo trả về đúng sáu mã của mình).
            <para>
            Danh sách đi từ máy chủ ra chứ không để phía trình duyệt tự chép: hai bảng song song là
            hai bảng sẽ lệch, và cái lệch chỉ lộ ra khi nền tảng từ chối một biểu tượng đã bấm được.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.SupportsHistorySync">
            <summary>
            Hội thoại này có nút "Đồng bộ lại tin từ nền tảng" hay không — cờ năng lực của nền tảng,
            không phải cờ quyền: endpoint <c>conversation/{id}/sync-history</c> gác bằng
            <c>ChatConversation.GetById</c>, đúng role người dùng đã phải có để mở được hội thoại này.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.CanWrite">
            <summary>
            Người đang đăng nhập có được <b>thay đổi</b> hội thoại này không — trả lời, đánh dấu đã
            đọc, nhận về mình, phân công, nhả, chuyển, gắn khách. <c>false</c> = <b>chỉ đọc</b>.
            </summary>
            <remarks>
            <para>
            <b>Sổ nợ PP-36.</b> Máy chủ vốn đã phân biệt đọc với ghi rất rõ — đo được ở §18.4 trên
            cùng một hội thoại, cùng một người, cách nhau vài giây: <c>GET conversation/298</c> trả
            <b>200</b> còn <c>mark-read</c> / <c>send</c> / <c>assign</c> đều trả "Không tìm thấy
            hội thoại." Thiếu cờ này thì <b>chỉ giao diện là không biết</b>: ô soạn tin không khoá,
            nút Gửi bật ngay khi gõ, và một sale gõ xong câu trả lời cho khách thật là mất trắng,
            kèm một câu báo lỗi nói sai chuyện.
            </para>
            <para>
            Giá trị lấy <b>nguyên</b> từ <c>ChatVisibility.AllowsWrite</c> — cùng biểu thức mà 13
            đường ghi đang dùng, không có bản thứ hai để lệch. Cờ này <b>không phải hàng rào</b>:
            hàng rào vẫn ở tầng service. Nó chỉ làm giao diện biết đúng điều máy chủ vốn đã biết.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.AssignmentMode">
            <summary>
            Chế độ phân phối của kênh chứa hội thoại. <c>null</c> = không tra được kênh.
            </summary>
            <remarks>
            Ra tới giao diện vì <b>hai</b> trường dưới im lặng theo chế độ kênh (§6.5, PP-34), và
            không có trường này thì màn hàng chờ không phân biệt được hai chuyện rất khác nhau:
            "khách không đang chờ" và "kênh này hệ thống không chấm". Bản đầu của bản vá PP-34 để
            tooltip nói câu thứ nhất cho cả hai — tức dịch một phép <b>không đo</b> thành một lời
            <b>khẳng định</b>, đúng lớp lỗi FB-2 mà cả đợt này đã cắn tám lần.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.AssignmentModeStr">
            <summary>Chữ hiển thị của <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.AssignmentMode"/>; rỗng khi không tra được kênh.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.WaitingWorkingMinutes">
            <summary>
            Số phút <b>giờ làm</b> khách đã chờ được trả lời. <c>null</c> = khách không đang chờ
            (đã có tin trả lời sau tin của họ, hoặc hội thoại đã đóng), <b>hoặc</b> kênh không ở
            chế độ tự phân phối nên hệ thống không chấm thời gian chờ ở đó (§6.5, PP-34) — phân biệt
            hai ca bằng <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.AssignmentMode"/>.
            </summary>
            <remarks>
            Tính ở <b>máy chủ</b>, không để trình duyệt tự trừ hai mốc thời gian. Giờ làm việc là
            một cấu hình có nghỉ trưa, có ngày nghỉ và có múi giờ; chép phép tính ấy sang JavaScript
            là dựng nguồn sự thật thứ hai, và cái lệch sẽ hiện ra dưới dạng "màn hình nói khách chờ
            620 phút" trong khi hệ thống mới đếm 10.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.WaitingOverdue">
            <summary>
            Khách đã chờ quá ngưỡng chưa. Hội thoại <b>đã giao</b> chấm theo
            <c>Chat.Sla.RemindMinutes</c>; hội thoại còn ở <b>hàng chờ</b> chấm theo
            <c>Chat.Queue.AlertMinutes</c>.
            <para>
            <b>Luôn <c>false</c> ngoài kênh <c>AutoDistribute</c></b> (§6.5, PP-34): nhãn "Quá hạn"
            hứa rằng hệ thống <b>sẽ</b> nhắc và <b>sẽ</b> thu hồi, mà không lượt quét nào chạy cho
            kênh khác — cả hai job đều lọc <c>AssignmentMode == AutoDistribute</c>.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAssignmentDecisionItem">
            <summary>
            Một dòng của màn nhật ký quyết định phân phối.
            <para>
            Danh sách trắng như mọi DTO khác của miền: đủ để dựng bảng và trả lời "vì sao không phải
            tôi", không kèm nội dung tin nhắn của khách.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAssignmentDecisionItem.CustomerName">
            <summary>Tên hiển thị của khách trong hội thoại — để người đọc nhận ra dòng nào là dòng nào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAssignmentDecisionItem.ChosenStaffName">
            <summary>Tên người được chọn; rỗng khi không ai nhận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAssignmentDecisionItem.RuleCode">
            <summary>Mã luật: <c>sticky-customer</c> / <c>least-loaded</c> / <c>no-candidate</c> / <c>lost-race</c></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAssignmentDecisionItem.RuleStr">
            <summary>Tên luật bằng tiếng Việt để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAssignmentDecisionItem.Candidates">
            <summary>Bảng ứng viên đã cân nhắc, kèm lý do bị loại của từng người</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDecisionCandidateItem">
            <summary>Một ứng viên trong bảng cân nhắc của một quyết định</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDecisionCandidateItem.ExcludedReasonStr">
            <summary>Lý do bị loại bằng tiếng Việt; "đủ điều kiện" khi không bị loại</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionShareItem">
            <summary>
            Một dòng của bảng đối chiếu dry-run: một sale trên một kênh nhận bao nhiêu lượt trong cửa
            sổ phát lại.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionShareItem.AssignedCount">
            <summary>Số lượt được chọn trong cửa sổ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionShareItem.SharePercent">
            <summary>Tỉ lệ phần trăm trên tổng lượt có người nhận của kênh</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionShareItem.ExpectedPercent">
            <summary>
            Tỉ lệ phần trăm <b>đáng lẽ</b> nhận được nếu chia đúng theo trọng số — mẫu số là tổng
            trọng số của những người có mặt trong bảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionShareItem.DeviationPoints">
            <summary>Lệch tuyệt đối giữa <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionShareItem.SharePercent"/> và <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionShareItem.ExpectedPercent"/>, tính bằng điểm phần trăm</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionChannelShare">
            <summary>
            Bảng đối chiếu dry-run của một kênh — đầu vào của cổng D2.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionChannelShare.DecisionCount">
            <summary>Tổng số quyết định trong cửa sổ, kể cả lượt không ai nhận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionChannelShare.AssignedCount">
            <summary>Số lượt có người nhận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionChannelShare.NoCandidateCount">
            <summary>Số lượt không ai đủ điều kiện</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionChannelShare.StickyCount">
            <summary>Số lượt luật khách quen quyết định</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionChannelShare.StaffCount">
            <summary>Số người có mặt trong bảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionChannelShare.MaxPairDeviationPercent">
            <summary>
            Lệch lớn nhất giữa hai người <b>cùng trọng số</b>, tính bằng phần trăm trên người nhận
            nhiều hơn. Ngưỡng cổng D2: &gt; 20 % là không bật.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionChannelShare.ReliabilityNote">
            <summary>
            Câu cảnh báo về độ tin cậy — cỡ mẫu quá nhỏ, hoặc kênh chỉ có một người. Rỗng nghĩa là
            bảng này đọc được như một bảng phân bố.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionReplayResult">
            <summary>Kết quả một lượt phát lại lịch sử</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionReplayResult.InboundMessageCount">
            <summary>Số tin inbound đã duyệt qua</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionReplayResult.ConversationCount">
            <summary>Số hội thoại có ít nhất một quyết định</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionReplayResult.DecisionCount">
            <summary>Số dòng nhật ký quyết định đã ghi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionReplayResult.ClearedCount">
            <summary>Số dòng nhật ký phát lại cũ đã dọn trước khi chạy</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDtoMapper">
            <summary>
            Chuyển entity chat sang DTO. Đây là ranh giới ra khỏi máy chủ — thứ gì không khai trong DTO
            thì không có đường đi ra.
            <para>
            Để ở một chỗ dùng chung vì có HAI đường ra: REST (controller) và SignalR (<c>ChatHub</c>).
            Hai đường map khác nhau là hai nguồn dữ liệu cùng đổ vào một mảng phía trình duyệt mà lại
            khác hình dạng — đúng loại lỗi im lặng mà kế hoạch §6.8 đang tìm cách tránh.
            </para>
            <para>
            Phân hệ này KHÔNG dùng AutoMapper (theo tiền lệ <c>ChatChannelService.ToItem</c>): DTO có
            trường dẫn xuất cần tra cứu theo nền tảng (<see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem.ReplyWindowHoursLeft"/>),
            diễn đạt bằng hàm thường rõ hơn bằng cấu hình.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDtoMapper.ToItem(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessengerResolver,System.DateTimeOffset,System.String,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext,System.Nullable{Lada.Framework.Data.Enums.ChatAssignmentMode},System.Boolean)">
            <summary>
            Chuyển một hội thoại sang DTO.
            </summary>
            <param name="conversation">Hội thoại; navigation <c>ChatChannel</c>/<c>Customer</c> có thì dùng, không có thì để rỗng</param>
            <param name="messengerResolver">Dùng để biết cửa sổ trả lời của nền tảng; bỏ trống thì không tính</param>
            <param name="now">Mốc thời gian tính cửa sổ trả lời</param>
            <param name="assignedStaffName">
            Tên nhân viên đang phân công, tra sẵn qua <c>IChatStaffDirectory</c>.
            <b>Tham số bắt buộc, cố ý không có giá trị mặc định.</b> Cột <c>AssignedStaffId</c>
            không có navigation nên mapper không tự tra được, mà quên điền thì dòng hội thoại đẩy
            qua SignalR sẽ mang tên rỗng và phía trình duyệt thay nguyên dòng bằng bản vừa nhận —
            tên người phụ trách biến mất khỏi màn hình ngay khi có tin mới. Đúng hình dạng của lỗi
            đã cắn ở giai đoạn C. Để trình biên dịch bắt người viết đường ghi mới phải quyết định.
            </param>
            <param name="channelMode">
            Chế độ phân phối của kênh chứa hội thoại — cổng của nhãn "Quá hạn" và cột "Chờ trả lời"
            (§6.5, sổ nợ PP-34). <c>null</c> nghĩa là <b>không tra được kênh</b>, và khi đó coi như
            kênh không tự phân phối: fail-closed, cùng chiều với
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatRealtimeAudience.Resolve(System.Nullable{Lada.Framework.Data.Enums.ChatAssignmentMode},System.Int32,System.Nullable{System.Int32})"/>.
            <para>
            <b>Tham số bắt buộc, cố ý không có giá trị mặc định</b> — cùng lý do với
            <paramref name="assignedStaffName"/> và <paramref name="waiting"/>: đường đẩy realtime
            nạp hội thoại từ webhook và <b>không phải lúc nào cũng Include kênh</b>, nên một giá trị
            mặc định ở đây là nhãn "Quá hạn" tắt hoặc bật sai ở đúng cái đường đã cắn hai lần.
            </para>
            </param>
            <param name="canWrite">
            Người đang xem có được thay đổi hội thoại này không — <b>luôn</b> là
            <c>ChatVisibility.AllowsWrite(conversation)</c> của chính người đó (sổ nợ PP-36).
            <para>
            <b>Tham số bắt buộc, cố ý không có giá trị mặc định</b>, và ở đây lý do còn nặng hơn
            hai tham số trên: khai <c>= false</c> thì một đường gọi bị quên sẽ <b>khoá ô soạn tin
            của người đang phụ trách khách thật</b> — tệ hơn chính lỗi đang vá; khai <c>= true</c>
            thì bản vá lặng lẽ không có tác dụng ở đúng đường bị quên.
            </para>
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDtoMapper.ResolveWaiting(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext,System.Nullable{Lada.Framework.Data.Enums.ChatAssignmentMode})">
            <summary>
            Khách đã chờ bao nhiêu phút giờ làm, và đã quá ngưỡng chưa.
            </summary>
            <remarks>
            <para>
            Câu hỏi "khách có đang chờ không, và từ lúc nào" đi qua
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules.WaitingSince(System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset},Lada.Framework.Data.Enums.ChatConversationStatus)"/> — đúng hàm mà lượt quét hạn phản hồi dùng. Viết
            lại ở đây là dựng định nghĩa thứ hai, và cái lệch chỉ lộ ra khi một sale hỏi vì sao màn
            hình nói 5 phút mà hệ thống vừa thu hồi hội thoại của họ.
            </para>
            <para>
            Hai ngưỡng khác nhau vì đó là hai việc khác nhau: hội thoại <b>đã giao</b> chấm theo hạn
            phản hồi của người đang giữ, hội thoại còn ở <b>hàng chờ</b> chấm theo ngưỡng báo trưởng
            nhóm. Dùng chung một ngưỡng là nói dối ở một trong hai màn.
            </para>
            <para>
            Và từ KC-18 cũng là <b>hai cách đếm</b>: dòng đã giao đếm trong giờ riêng của người đang
            giữ, dòng hàng chờ đếm những phút có ít nhất một ứng viên của kênh vào ca. Mốc bắt đầu thì
            vẫn chung một hàm <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules.WaitingSince(System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset},Lada.Framework.Data.Enums.ChatConversationStatus)"/> cho cả hai.
            </para>
            <para>
            <b>Cổng theo chế độ kênh (§6.5, PP-34).</b> Chỉ kênh <c>AutoDistribute</c> được chấm.
            Cổng này <b>không phải luật mới</b> — nó là đúng cái cổng mà cả hai lượt quét đã có
            (<c>ChatSlaSweepService</c> và <c>ChatQueueSweepService</c> đều lọc
            <c>AssignmentMode == AutoDistribute</c> khi chọn kênh), chỉ là tầng hiển thị chưa có.
            Thiếu nó thì ngày deploy đầu tiên <b>mọi</b> hội thoại đang chờ nổi nhãn đỏ trên mọi
            kênh — migration đặt mọi kênh production về <c>Shared</c> — trong khi nguyên tắc số 1
            hứa "deploy xong hệ thống không đổi hành vi một chút nào".
            </para>
            <para>
            Cổng áp cho <b>cả hai nhánh ngưỡng</b>, không riêng nhánh đã giao: nhánh hàng chờ đọc
            <c>Chat.Queue.AlertMinutes</c>, đúng ngưỡng mà lượt quét đọc nó cũng không chạy cho kênh
            <c>Shared</c>. Kênh <c>FixedOwner</c> cũng không được chấm, và vì cùng một lý do: không
            lượt quét nào chạy cho nó, nên một nhãn "Quá hạn" ở đó hứa một hành động sẽ không xảy ra.
            </para>
            <para>
            Đọc <b>THẲNG</b> chế độ kênh chứ không hỏi qua một hàm tiện dụng nào — bài học đắt nhất
            của cổng chất lượng giai đoạn D là <c>IsAssignableToChannelAsync</c> CỐ Ý trả
            <c>true</c> cho kênh <c>Shared</c> nên không phân biệt được hai chế độ. Cùng lý do và
            cùng cách viết với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules.Decide(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaInput,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours,System.Int32,System.Int32)"/>.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDtoMapper.ToItem(Lada.Framework.Data.Domains.SocialChat.ChatMessage,Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageQuoteItem)">
            <summary>Chuyển một tin nhắn sang DTO.</summary>
            <param name="message">Tin nhắn</param>
            <param name="replyTo">
            Khối trích dẫn đã tra sẵn qua <c>IChatQuoteResolver</c>, <c>null</c> với tin thường.
            <b>Tham số bắt buộc, cố ý không có giá trị mặc định</b> — cùng lý do với
            <c>assignedStaffName</c> ở trên: quên điền ở một đường ghi thì khối trích dẫn biến mất
            khỏi màn hình ngay khi tin nhận được một cập nhật giao nhận, mà không có lỗi nào báo.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDtoMapper.BuildPreview(System.String,Lada.Framework.Data.Enums.ChatContentType)">
            <summary>
            Chữ hiển thị thay cho một tin không có nội dung văn bản.
            <para>
            Ở một chỗ dùng chung vì có hai nơi cần đúng cùng một nhãn: cột xem trước của danh sách
            hội thoại (<c>ChatConversation.LastMessage</c>) và khối trích dẫn. Hai bảng nhãn song
            song là hai bảng sẽ lệch nhau.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDtoMapper.CalculateReplyWindowHoursLeft(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger,System.DateTimeOffset)">
            <summary>
            Số giờ còn lại của cửa sổ trả lời tự do. Trả <c>null</c> khi khách chưa nhắn lần nào,
            hoặc khi chưa có bản gửi tin cho nền tảng đó — không biết luật thì không đoán một con
            số, vì con số bịa ra vẫn hiện lên màn hình y như con số đã kiểm chứng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageItem">
            <summary>
            Một bong bóng tin nhắn trong khung chat.
            <para>
            Danh sách trắng như <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem"/>, và vì lý do giống hệt: entity
            <c>ChatMessage</c> có navigation ngược về hội thoại.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageItem.Direction">
            <summary>Chiều tin: khách gửi vào hay nhân viên gửi ra</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageItem.Content">
            <summary>Nội dung văn bản, hoặc chú thích của ảnh</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageItem.AttachmentUrl">
            <summary>Đường dẫn tệp đính kèm để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageItem.ExternalMessageId">
            <summary>Định danh tin phía nền tảng — cần cho việc đối soát trạng thái giao nhận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageItem.ReplyTo">
            <summary>
            Khối trích dẫn của tin gốc, khi tin này là một câu trả lời trích dẫn. <c>null</c> với tin thường.
            <para>
            Nội dung được máy chủ tra sẵn (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuoteResolver"/>)
            vì nền tảng chỉ gửi MÃ tin gốc. Cố ý KHÔNG trả mã đó ra ngoài: khung chat hiện nay không
            để lọt chuỗi định danh nền tảng nào của khách, và khối trích dẫn không được là chỗ phá lệ.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageItem.SenderName">
            <summary>Tên người gửi hiển thị dưới bong bóng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageItem.SenderStaffId">
            <summary>Nhân viên đã bấm gửi, null với tin của khách</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageItem.ExternalSenderAdminId">
            <summary>
            Định danh admin phía nền tảng đã gõ tin này ngoài LADA (SC-26). Chỉ Zalo có; đây là
            admin của CHÍNH OA LADA chứ không phải định danh của khách, nên hiện ra được.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageItem.CustomerReactionEmoji">
            <summary>
            Biểu tượng cảm xúc khách đã thả lên tin này, dạng ký tự emoji thật. <c>null</c> là chưa
            thả hoặc đã gỡ. Giao diện vẽ thẳng ký tự này, KHÔNG có bảng dịch nào ở phía trình duyệt.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageItem.StaffReactionEmoji">
            <summary>Biểu tượng cảm xúc phía LADA đã thả lên tin này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageItem.StaffReactionByStaffId">
            <summary>
            Nhân viên đã thả <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageItem.StaffReactionEmoji"/>; <c>null</c> mà emoji vẫn có nghĩa là
            cảm xúc được thả ngoài LADA, từ cửa sổ chat của chính nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageItem.FailureReason">
            <summary>
            Lý do gửi hỏng, đã dịch sang tiếng Việt ở tầng <c>ZaloErrorCatalog</c>. Giao diện hiện
            thẳng chuỗi này dưới bong bóng, KHÔNG viết bảng dịch thứ hai ở phía trình duyệt.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageQuoteItem">
            <summary>
            Đoạn trích của tin gốc hiện phía trên một câu trả lời trích dẫn.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageQuoteItem.MessageId">
            <summary>
            Mã tin gốc TRONG LADA, để khung chat cuộn tới khi nhân viên bấm vào khối trích dẫn.
            <c>null</c> nghĩa là không dựng lại được tin gốc (có trước khi nối kênh, hoặc đã xoá) —
            khối vẫn hiện, chỉ không bấm được và không có nội dung.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageQuoteItem.Direction">
            <summary>Chiều của tin gốc — khung chat dùng để nói "bạn" hay tên khách</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageQuoteItem.ContentType">
            <summary>Loại nội dung của tin gốc</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageQuoteItem.SenderName">
            <summary>Tên người gửi tin gốc</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatMessageQuoteItem.Preview">
            <summary>Đoạn trích đã cắt ngắn; rỗng khi không dựng lại được tin gốc</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatCustomerOptionItem">
            <summary>
            Một dòng gợi ý khách hàng khi nhân viên gắn hội thoại với hồ sơ trong hệ thống.
            <para>
            Danh sách trắng rất hẹp, và hẹp có chủ ý: quyền gắn khách hàng
            (<c>ChatConversation.LinkCustomer</c>) được cấp cho nhân viên chăm sóc khách hàng, không
            phải cho người quản lý dữ liệu khách. Nó chỉ cần đủ để nhận ra đúng người — không kèm
            địa chỉ, email, công nợ hay bảng giá.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatStaffOptionItem">
            <summary>
            Một dòng gợi ý nhân viên khi phân công hội thoại.
            <para>
            Cố ý chỉ có mã và tên hiển thị, hẹp hơn <c>UserOptionItem</c> dùng chung của repo (không
            số điện thoại, không tên đăng nhập): ô chọn này chỉ cần một chuỗi để bấm, mà mỗi trường
            mở thêm là thêm dữ liệu nội bộ đi ra cho một quyền vốn chỉ nói về chuyện phân công hội
            thoại. Tên đăng nhập đặc biệt không nên có mặt — nó là một nửa của cặp đăng nhập.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatStaffOptionItem.FullName">
            <summary>Tên hiển thị; tài khoản chưa điền họ tên thì đã được lùi về tên đăng nhập ở tầng dịch vụ</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem">
            <summary>
            Trạng thái sẵn sàng của một người, dựng cho màn hình.
            </summary>
            <remarks>
            Trả <b>cả</b> trạng thái hiệu lực lẫn trạng thái tự khai, có chủ ý: menu đổi trạng thái phải
            hiện đúng thứ người dùng đã chọn (<see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.SelfStatus"/>), còn cái chip cạnh nó phải nói
            sự thật lúc này (<see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.EffectiveStatus"/>). Trộn hai thứ vào một trường là lúc 8 giờ
            tối, menu tự nhảy sang "Ngoài giờ làm việc" — một giá trị người dùng không chọn được và
            không gỡ được.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.StaffId">
            <summary>Mã nhân viên</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.StaffName">
            <summary>Tên hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.EffectiveStatus">
            <summary>Trạng thái hiệu lực lúc này — kết quả sau khi gộp mọi nguồn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.EffectiveStatusStr">
            <summary>Nhãn tiếng Việt của <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.EffectiveStatus"/></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.SelfStatus">
            <summary>Trạng thái người này tự khai (thứ hiện trong menu)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.SelfStatusStr">
            <summary>Nhãn tiếng Việt của <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.SelfStatus"/></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.UntilTime">
            <summary>Hạn của trạng thái tự khai</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.Note">
            <summary>Ghi chú của chính người đó</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.SuspendedUntil">
            <summary>Bị quản lý tạm ngưng đến khi nào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.SuspendedNote">
            <summary>Lý do tạm ngưng do quản lý nhập</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.CanReceiveNewCustomer">
            <summary>Có nhận khách mới lúc này không — bằng <c>EffectiveStatus == Available</c></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.WorkingHoursText">
            <summary>
            Câu mô tả giờ làm việc <b>riêng</b> của người này, ví dụ "08:00–17:30, Thứ Hai–Thứ Bảy,
            nghỉ trưa 12:00–13:00". Có mặt để màn hình <b>giải thích được</b> vì sao đang "Ngoài giờ
            làm việc" thay vì chỉ khẳng định là thế.
            <para>
            <b>Chuỗi rỗng khi chưa đặt</b> (KC-18, §8.6: giờ làm mặc định ẩn) — trước KC-18 trường
            này luôn mô tả cấu hình chung, nên chip hiện một giờ làm không áp cho ai.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.HasOwnWorkingHours">
            <summary>
            Đã có giờ làm riêng dùng được chưa (KC-18). <c>false</c> = chưa đặt — người này luôn
            trong ca, không bao giờ tự thành "Ngoài giờ", và tiêu chí tỉ lệ sẵn sàng coi là chưa có
            mẫu. Dữ liệu giờ riêng hỏng cũng là <c>false</c> (xem
            <c>ChatStaffWorkingHours.HasOwnWorkingHours</c>).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.WorkStart">
            <summary>Giờ bắt đầu làm việc riêng, dạng <c>HH:mm</c>; <c>null</c> khi chưa đặt</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.WorkEnd">
            <summary>
            Giờ kết thúc làm việc riêng, dạng <c>HH:mm</c>; <c>null</c> khi chưa đặt. Làm tới hết
            ngày thì là <c>23:59</c> — đúng giá trị người dùng chọn và gửi lại được nguyên văn.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.BreakStart">
            <summary>Giờ bắt đầu nghỉ trưa, dạng <c>HH:mm</c>; <c>null</c> = không nghỉ trưa hoặc chưa đặt</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.BreakEnd">
            <summary>Giờ kết thúc nghỉ trưa, dạng <c>HH:mm</c>; <c>null</c> = không nghỉ trưa hoặc chưa đặt</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.WorkingDays">
            <summary>
            Ngày làm, mã 2 (Thứ Hai) … 7 (Thứ Bảy), 8 (Chủ Nhật), tăng dần — cùng cách đánh số với
            <c>Chat.WorkingHours.WorkingDays</c>. Mảng rỗng khi chưa đặt.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.SuggestedWorkingHours">
            <summary>
            Giờ <b>gợi ý</b> lấy từ cấu hình chung <c>Chat.WorkingHours.*</c> — cùng dạng các trường
            giờ ở trên, để hộp "Đặt giờ làm việc" điền sẵn khi người này chưa đặt. Chủ dự án chốt
            (§8.7 câu 5): cấu hình chung chỉ còn là giờ gợi ý, không áp cho ai.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.MaxSelfStatusMinutes">
            <summary>Trần thời hạn cho Bận / Ra ngoài, tính bằng phút — giao diện dùng để chặn tại chỗ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.MaxLeaveDays">
            <summary>Trần thời hạn cho Nghỉ, tính bằng ngày</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.DelegateOnLeaveDays">
            <summary>
            Nghỉ từ bấy nhiêu ngày trở lên thì hội thoại đang cầm được uỷ quyền tạm; 0 = tắt.
            Giao diện dùng để cảnh báo trước khi người dùng bấm xác nhận.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatWorkingHoursItem">
            <summary>
            Một bộ giờ làm việc ở dạng giao diện đọc và gửi lại được (KC-18) — dùng cho giờ gợi ý
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.SuggestedWorkingHours"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatWorkingHoursItem.WorkStart">
            <summary>Giờ bắt đầu làm việc, dạng <c>HH:mm</c></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatWorkingHoursItem.WorkEnd">
            <summary>Giờ kết thúc làm việc, dạng <c>HH:mm</c>; hết ngày là <c>23:59</c></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatWorkingHoursItem.BreakStart">
            <summary>Giờ bắt đầu nghỉ trưa, dạng <c>HH:mm</c>; <c>null</c> = không nghỉ trưa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatWorkingHoursItem.BreakEnd">
            <summary>Giờ kết thúc nghỉ trưa, dạng <c>HH:mm</c>; <c>null</c> = không nghỉ trưa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatWorkingHoursItem.WorkingDays">
            <summary>Ngày làm, mã 2 (Thứ Hai) … 8 (Chủ Nhật), tăng dần</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatPresenceDurationItem">
            <summary>
            Một dòng của bảng thời lượng theo trạng thái — mỗi nhân viên một dòng, các trạng thái là cột.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatPresenceDurationItem.StaffId">
            <summary>Mã nhân viên</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatPresenceDurationItem.StaffName">
            <summary>Tên hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatPresenceDurationItem.EffectiveStatus">
            <summary>Trạng thái hiệu lực lúc xem báo cáo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatPresenceDurationItem.EffectiveStatusStr">
            <summary>Nhãn tiếng Việt của <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatPresenceDurationItem.EffectiveStatus"/></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatPresenceDurationItem.HasOwnWorkingHours">
            <summary>
            Đã có giờ làm riêng dùng được chưa (KC-18). <c>false</c> = chưa đặt — người này luôn
            trong ca và nhận khách theo trạng thái đang đặt.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatPresenceDurationItem.WorkingHoursText">
            <summary>
            Câu mô tả giờ làm riêng, cùng dạng với <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAgentPresenceItem.WorkingHoursText"/>;
            chuỗi rỗng khi chưa đặt.
            </summary>
            <remarks>
            Có mặt vì KC-20 (§8.7 câu 6): sale tự đặt được một ca rất ngắn để gần như luôn "Ngoài
            giờ" — không nhận khách mới, không bị nhắc hay thu hồi. Chủ dự án chọn không chặn mà cho
            quản lý <b>nhìn thấy</b> để đặt hộ lại.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatPresenceDurationItem.AvailableMinutes">
            <summary>Số phút ở trạng thái Sẵn sàng trong cửa sổ báo cáo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatPresenceDurationItem.BusyMinutes">
            <summary>Số phút ở trạng thái Bận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatPresenceDurationItem.AwayMinutes">
            <summary>Số phút ở trạng thái Ra ngoài</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatPresenceDurationItem.OnLeaveMinutes">
            <summary>Số phút ở trạng thái Nghỉ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatPresenceDurationItem.SuspendedMinutes">
            <summary>Số phút bị tạm ngưng nhận khách</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatPresenceDurationItem.LoggedMinutes">
            <summary>
            Tổng số phút <b>có ghi nhật ký</b> trong cửa sổ. Nhỏ hơn độ dài cửa sổ là bình thường:
            người chưa từng đổi trạng thái không có dòng nhật ký nào, và bịa ra thời lượng cho họ
            là bịa ra dữ liệu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatPresenceDurationItem.OpenConversationCount">
            <summary>Số hội thoại người này đang giữ (chưa đóng) lúc xem báo cáo</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQualityCriterionScoreItem">
            <summary>
            Điểm một tiêu chí, kèm <b>mọi thứ cần để người dùng hiểu con số</b> — không chỉ con số.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQualityCriterionScoreItem.Unit">
            <summary>Đơn vị của <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQualityCriterionScoreItem.RawValue"/> — <c>phút</c>, <c>%</c></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQualityCriterionScoreItem.RawValue">
            <summary>Số thô — trung vị phút, tỉ lệ phần trăm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQualityCriterionScoreItem.Sample">
            <summary>
            <b>Cỡ mẫu, luôn hiện ra.</b> Trang phải nói được "trung vị này dựng từ 2 hội thoại" chứ
            không im lặng trình bày nó như một trung vị dựng từ 200 — đó là yêu cầu thẳng của prompt
            giai đoạn F và là hệ quả của sổ nợ PP-13.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQualityCriterionScoreItem.CanScore">
            <summary>
            Tiêu chí này có chấm được không. <c>false</c> khi cỡ mẫu bằng 0 — giao diện phải hiện
            "chưa có dữ liệu" chứ <b>không</b> hiện 0 điểm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQualityCriterionScoreItem.ImprovementHint">
            <summary>Việc cần làm để tăng điểm tiêu chí này</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQualityMyScoreItem">
            <summary>Điểm của chính người đang đăng nhập — dữ liệu của trang <c>/diem-chat-cua-toi</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQualityMyScoreItem.HasScore">
            <summary>Đã có lượt tính nào cho người này chưa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQualityMyScoreItem.ActiveCriteriaCount">
            <summary>Tổng số tiêu chí đang bật — mẫu số của <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQualityMyScoreItem.ScoredCriteriaCount"/></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQualityMyScoreItem.Rank">
            <summary>
            Thứ hạng trong nhóm người cùng phụ trách kênh — <c>null</c> khi chưa xếp hạng được.
            </summary>
            <remarks>
            Chốt CH-9: hiện <b>thứ hạng của mình</b> ("bạn đứng thứ 3/7") nhưng <b>không</b> hiện
            điểm người khác — đủ động lực, không đủ để so đo. Vì thế DTO này cố ý không có trường
            nào mang điểm của người khác, kể cả ẩn danh.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQualityMyScoreItem.RankTotal">
            <summary>Tổng số người trong nhóm xếp hạng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQualityMyScoreItem.AffectsDistribution">
            <summary>
            Điểm có đang ảnh hưởng số lượng khách được chia không — cờ
            <c>Chat.Quality.AffectsDistribution</c>.
            </summary>
            <remarks>
            Phải nói ra trên giao diện. Trình bày một trọng số 1,18 mà không nói nó <b>chưa có hiệu
            lực</b> là để người dùng tin rằng họ đang được chia nhiều hơn đồng nghiệp trong khi thực
            tế máy vẫn chia đều.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQualityTeamItem">
            <summary>Một dòng trong bảng điểm đội — chỉ cho người có quyền <c>ChatQuality.ViewTeam</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQuickReplyItem">
            <summary>
            Một mẫu tin nhắn nhanh trả cho giao diện — danh sách chọn ở ô soạn tin và bảng ở <c>/tin-nhan-nhanh</c>.
            <para>
            Danh sách trắng. <b>Không có <c>ImageSystemPath</c></b> — đường dẫn đĩa máy chủ không bao giờ ra
            client (nguyên tắc 1.5; ca test số 10 soi bằng reflection). <b>Không có <c>OwnerUserId</c></b> — giao
            diện chỉ cần biết "của tôi hay không" (<see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQuickReplyItem.IsMine"/>), không cần mã người dùng của ai.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQuickReplyItem.ScopeStr">
            <summary>Tên phạm vi để hiển thị: "Của tôi" / "Dùng chung"</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQuickReplyItem.HasImage">
            <summary>
            Mẫu có ảnh <b>gửi được</b> hay không — tính theo đường dẫn tệp phía máy chủ, không theo
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQuickReplyItem.ImageUrl"/>: Zalo tải ảnh lên từ tệp, có URL mà không có tệp là gửi không được.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQuickReplyItem.ImageUrl">
            <summary>URL công khai để xem trước. Trên dev trả 404 vì <c>Media.Domain</c> trỏ production (TN-6).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatQuickReplyItem.IsMine">
            <summary>Mẫu cá nhân của chính người đang xem</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.FacebookPageItem">
            <summary>
            Một Facebook Page mà quản trị viên đang quản lý, trả về cho bước chọn Page khi kết nối kênh.
            <para>
            Lớp này KHÔNG có trường token, và không bao giờ được có: <c>GET /me/accounts</c> trả về Page
            access token của từng Page, mà token ấy <b>không hết hạn</b> — để nó lọt ra khỏi máy chủ một
            lần là ai cầm được cũng nhắn tin thay Page mãi mãi. Danh sách trường ở đây là danh sách trắng.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.FacebookPageItem.Id">
            <summary>Định danh Page phía Facebook</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.FacebookPageItem.Name">
            <summary>Tên Page hiển thị cho người chọn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.FacebookPageItem.AvatarUrl">
            <summary>Ảnh đại diện Page</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.FacebookPageItem.IsConnected">
            <summary>Page này đã có kênh trong hệ thống chưa — chọn lại là cập nhật token, không tạo kênh thứ hai</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Training.CourseItem">
            <summary>
            Item hiển thị khóa học trong danh sách
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Training.CurriculumItem">
            <summary>
            Item trong curriculum của khóa học (section hoặc standalone lesson)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Training.CurriculumItem.Type">
            <summary>type: "section" | "standalone"</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Training.CurriculumItem.Id">
            <summary>Id của section hoặc lesson</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Training.CurriculumItem.GlobalOrder">
            <summary>Thứ tự thống nhất trong curriculum</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Training.CurriculumOrderRequest">
            <summary>
            Request sắp xếp lại curriculum
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Training.LessonDetailItem">
            <summary>
            Chi tiết bài giảng (kèm media, thông tin section/course) cho Learner View
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Training.LessonItem">
            <summary>
            Item hiển thị bài giảng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Training.LessonMediaItem">
            <summary>
            Item hiển thị media trong bài giảng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Training.SectionItem">
            <summary>
            Item hiển thị section trong khóa học
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.GarageItem">
            <summary>
            Garage trong danh mục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.GarageItem.Name">
            <summary>
            Tên garage
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.GarageItem.Address">
            <summary>
            Địa chỉ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.GarageItem.Phone">
            <summary>
            Số điện thoại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.GarageItem.ContactPerson">
            <summary>
            Người liên hệ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.GarageItem.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.GarageItem.IsActive">
            <summary>
            Còn sử dụng hay không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckActivityItem.CurrentOdo">
            <summary>
            Số ODO hiện tại của xe (áp dụng cho tất cả hoạt động: nhận xe, trả xe, đổ dầu)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckActivityItem.MediaItems">
            <summary>
            Danh sách hình ảnh kèm theo
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckActivityMediaItem">
            <summary>
            Item hiển thị media trong hoạt động xe tải
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckActivityMediaItem.TruckActivityId">
            <summary>
            ID hoạt động xe tải
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckActivityMediaItem.MediaId">
            <summary>
            ID media
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckActivityMediaItem.MediaUrl">
            <summary>
            URL của media
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckActivityMediaItem.AltText">
            <summary>
            Alt text của media
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckActivityMediaItem.Caption">
            <summary>
            Caption của media
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckActivityMediaItem.MediaType">
            <summary>
            Loại media (Ảnh nhận xe/Ảnh trả xe)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckActivityMediaItem.MediaTypeStr">
            <summary>
            Mô tả loại media
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckActivityMediaItem.DisplayOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckAssetItem.UnitPrice">
            <summary>
            Đơn giá
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem">
            <summary>
            Một cảnh báo tuổi thọ bộ phận do job nền sinh ra.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.TruckComponentId">
            <summary>Bộ phận bị cảnh báo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.TruckId">
            <summary>Xe</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.LicensePlate">
            <summary>Biển số</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.AgencyId">
            <summary>Chi nhánh quản lý xe</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.ComponentTypeName">
            <summary>Tên loại bộ phận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.Position">
            <summary>Vị trí bộ phận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.PositionStr">
            <summary>Vị trí để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.Level">
            <summary>Mức cảnh báo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.LevelStr">
            <summary>Mức cảnh báo để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.TriggeredDate">
            <summary>Thời điểm phát hiện</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.TriggeredDateStr">
            <summary>Thời điểm phát hiện để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.SnapshotKmUsed">
            <summary>Số km đã dùng tại thời điểm cảnh báo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.SnapshotDaysUsed">
            <summary>Số ngày đã dùng tại thời điểm cảnh báo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.NotifiedAt">
            <summary>Thời điểm đã gửi thông báo; null = chưa gửi (công tắc đang tắt hoặc chưa tới lượt)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.IsNotified">
            <summary>Đã gửi thông báo hay chưa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.ResolvedAt">
            <summary>Thời điểm cảnh báo được xử lý xong (bộ phận đã thay)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentAlertItem.IsResolved">
            <summary>Cảnh báo còn đang mở hay đã xử lý</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem">
            <summary>
            Bộ phận đang lắp trên xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.TruckId">
            <summary>
            Xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.LicensePlate">
            <summary>
            Biển số xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.ComponentTypeId">
            <summary>
            Loại bộ phận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.ComponentTypeName">
            <summary>
            Tên loại bộ phận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.Position">
            <summary>
            Vị trí trên xe (giá trị enum <c>ComponentPosition</c>)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.PositionName">
            <summary>
            Tên vị trí hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.InstalledDate">
            <summary>
            Ngày lắp
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.InstalledOdo">
            <summary>
            ODO lúc lắp
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.Source">
            <summary>
            Nguồn gốc (giá trị enum <c>ComponentSource</c>)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.SourceName">
            <summary>
            Tên nguồn gốc hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.LifespanKmOverride">
            <summary>
            Tuổi thọ theo km riêng của bộ phận này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.LifespanMonthsOverride">
            <summary>
            Tuổi thọ theo tháng riêng của bộ phận này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.EffectiveLifespanKm">
            <summary>
            Tuổi thọ theo km đang áp dụng (riêng nếu có, không thì của loại)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.EffectiveLifespanMonths">
            <summary>
            Tuổi thọ theo tháng đang áp dụng (riêng nếu có, không thì của loại)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentItem.IsActive">
            <summary>
            Còn đang lắp trên xe hay không
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeAliasItem">
            <summary>Một tên gọi khác của loại bộ phận K200.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeAliasItem.Source">
            <summary><c>ComponentTypeAliasSource</c>: 1 = dữ liệu nền, 2 = người dùng xác nhận.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeItem">
            <summary>
            Loại bộ phận xe trong danh mục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeItem.Code">
            <summary>
            Mã loại bộ phận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeItem.Name">
            <summary>
            Tên hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeItem.DefaultLifespanKm">
            <summary>
            Tuổi thọ mặc định theo km
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeItem.DefaultLifespanMonths">
            <summary>
            Tuổi thọ mặc định theo tháng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeItem.RequiresPosition">
            <summary>
            Có gắn với vị trí trên xe hay không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeItem.WarnBeforeKm">
            <summary>
            Ngưỡng cảnh báo trước theo km (null = dùng mặc định toàn cục)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeItem.WarnBeforeDays">
            <summary>
            Ngưỡng cảnh báo trước theo ngày (null = dùng mặc định toàn cục)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeItem.GroupType">
            <summary>
            Nhóm phân loại (giá trị enum)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeItem.GroupTypeName">
            <summary>
            Tên hiển thị của nhóm phân loại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeItem.QuantityPerTruck">
            <summary>
            Số lượng trên mỗi xe, dạng chữ tham khảo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeItem.ReferenceCost">
            <summary>
            Chi phí tham khảo dạng chữ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeItem.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeItem.IsActive">
            <summary>
            Còn dùng hay không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentTypeItem.SortOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem">
            <summary>
            Một dòng của màn tình trạng đội xe: xe + ODO hiện tại + số bộ phận đang có vấn đề.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.TruckId">
            <summary>Xe</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.LicensePlate">
            <summary>Biển số</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.AgencyId">
            <summary>Chi nhánh quản lý xe</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.AgencyName">
            <summary>Tên chi nhánh</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.OperatingStatus">
            <summary>Trạng thái vận hành</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.OperatingStatusStr">
            <summary>Trạng thái vận hành để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.CurrentOdo">
            <summary>ODO hiện tại; null khi xe chưa có dữ liệu ODO nào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.OdoRecordedAt">
            <summary>Thời điểm ghi nhận ODO</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.OdoRecordedAtStr">
            <summary>Thời điểm ghi nhận ODO để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.OdoAgeInDays">
            <summary>Số ngày kể từ lần ghi nhận ODO gần nhất</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.OdoSource">
            <summary>Nguồn của số ODO: FuelRefill / TruckActivity / LastRefillOdo / None</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.ComponentCount">
            <summary>Tổng số bộ phận đang lắp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.DueSoonCount">
            <summary>Số bộ phận sắp đến hạn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.OverdueCount">
            <summary>Số bộ phận đã quá hạn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.StaleOdoCount">
            <summary>Số bộ phận không tính được vì chuỗi ODO quá cũ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.WorstLevel">
            <summary>Mức nặng nhất trong các bộ phận của xe; null khi xe không có vấn đề gì</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem.WorstLevelStr">
            <summary>Mức nặng nhất để hiển thị</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem">
            <summary>
            Tình trạng một bộ phận trên xe — dùng cho lưới bộ phận của hồ sơ xe và cho DriverApp.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.TruckComponentId">
            <summary>Bộ phận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.TruckId">
            <summary>Xe</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.LicensePlate">
            <summary>Biển số</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.ComponentTypeId">
            <summary>Loại bộ phận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.ComponentTypeName">
            <summary>Tên loại bộ phận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.Position">
            <summary>Vị trí trên xe</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.PositionStr">
            <summary>Vị trí để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.InstalledDate">
            <summary>Ngày lắp hiện hành (mốc tính tuổi thọ)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.InstalledDateStr">
            <summary>Ngày lắp để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.InstalledOdo">
            <summary>ODO lúc lắp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.Source">
            <summary>Nguyên bản nhà máy hay đã thay</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.SourceStr">
            <summary>Nguồn gốc để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.EffectiveLifespanKm">
            <summary>Tuổi thọ hiệu lực theo km</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.EffectiveLifespanMonths">
            <summary>Tuổi thọ hiệu lực theo tháng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.KmUsed">
            <summary>Số km đã dùng; null khi không tính được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.KmRemaining">
            <summary>Số km còn lại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.DaysUsed">
            <summary>Số ngày đã dùng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.DaysRemaining">
            <summary>Số ngày còn lại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.DueDate">
            <summary>Hạn theo thời gian</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.DueDateStr">
            <summary>Hạn theo thời gian để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.KmPercent">
            <summary>Tỷ lệ tiêu hao theo km (%)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.TimePercent">
            <summary>Tỷ lệ tiêu hao theo thời gian (%)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.UsagePercent">
            <summary>Tỷ lệ tiêu hao để hiển thị = lớn hơn trong hai tiêu chí</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.Level">
            <summary>Mức cảnh báo; null khi bộ phận còn khoẻ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.LevelStr">
            <summary>Mức cảnh báo để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.ConditionNote">
            <summary>Ghi chú của engine khi một tiêu chí không tính được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.LastReplacedAt">
            <summary>Ngày thay gần nhất; null khi vẫn là nguyên bản nhà máy</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.LastReplacedAtStr">
            <summary>Ngày thay gần nhất để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckComponentConditionItem.LastReplacedGarage">
            <summary>Garage của lần thay gần nhất</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.ComponentHistoryItem">
            <summary>
            Một dòng lịch sử của một bộ phận: lần bảo dưỡng nào đã chạm tới nó và làm gì.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.ComponentHistoryItem.TruckMaintenanceId">
            <summary>Lần bảo dưỡng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.ComponentHistoryItem.Title">
            <summary>Tiêu đề lần bảo dưỡng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.ComponentHistoryItem.StartTime">
            <summary>Thời điểm bắt đầu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.ComponentHistoryItem.StartTimeStr">
            <summary>Thời điểm bắt đầu để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.ComponentHistoryItem.Odo">
            <summary>ODO tại thời điểm bảo dưỡng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.ComponentHistoryItem.ActionType">
            <summary>Hành động lên bộ phận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.ComponentHistoryItem.ActionTypeStr">
            <summary>Hành động để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.ComponentHistoryItem.LineCost">
            <summary>Chi phí riêng của dòng công việc</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.ComponentHistoryItem.GarageName">
            <summary>Garage — ưu tiên tên trong danh mục, không có thì lấy chuỗi nhập tay của bản ghi cũ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.ComponentHistoryItem.UserId">
            <summary>Người thực hiện</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.ComponentHistoryItem.HasInvoice">
            <summary>Có hoá đơn hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.ComponentHistoryItem.InvoiceUrl">
            <summary>Đường dẫn hoá đơn của bản ghi cũ (chỉ đọc, form mới không ghi vào đây)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckProfileItem">
            <summary>
            Hồ sơ tình trạng một xe: thông tin xe + ODO + lưới bộ phận.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckProfileItem.Truck">
            <summary>Thông tin xe và số liệu tổng hợp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckProfileItem.Components">
            <summary>Các bộ phận đang lắp kèm tình trạng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckItem.LastRefillOdo">
            <summary>
            Giá trị ODO gần nhất khi đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckItem.MediaItems">
            <summary>
            Danh sách media (ảnh đăng ký, đăng kiểm)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMediaItem">
            <summary>
            Item hiển thị media xe tải
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceItem.EndTimeStr">
            <summary>Rỗng khi bản ghi không có thời điểm kết thúc — cột NOT NULL nên giá trị trống là 01/01/0001, đừng bày ra cho người dùng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceItem.NextTimeStr">
            <summary>
            Rỗng khi bản ghi chưa hẹn kỳ sau — xem ghi chú ở <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceItem.EndTimeStr"/>.
            </summary>
            <remarks>
            Cũng rỗng khi kỳ sau không muộn hơn lúc bắt đầu: màn ghi nhận gửi <c>StartTime</c>
            vào ô này khi người dùng bỏ trống (cột NOT NULL nên phải có giá trị), mà "kỳ bảo
            dưỡng sau đúng bằng lúc đang bảo dưỡng" thì không mang nghĩa gì — hiện ra chỉ làm
            người vận hành tưởng xe đã tới hạn.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceItem.GarageId">
            <summary>Garage chọn từ danh mục; null với bản ghi cũ nhập garage bằng chuỗi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceItem.Odo">
            <summary>Chỉ số ODO của xe tại thời điểm bảo dưỡng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceMediaItem">
            <summary>
            Một tệp đính kèm (hoá đơn / ảnh hiện trạng) của một lần bảo dưỡng — thay cho trường chuỗi
            <c>TruckMaintenance.InvoiceUrl</c> cũ (nợ BD-4). Trường cũ chỉ còn hiển thị, không ghi mới.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceMediaItem.TruckMaintenanceId">
            <summary>Lần bảo dưỡng chứa tệp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceMediaItem.MediaId">
            <summary>Khoá bảng Media dùng chung</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceMediaItem.MediaUrl">
            <summary>URL công khai để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceMediaItem.MediaType">
            <summary>Loại tệp: hoá đơn hay ảnh hiện trạng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceMediaItem.MediaTypeStr">
            <summary>Tên hiển thị loại tệp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceMediaItem.DisplayOrder">
            <summary>Thứ tự hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceMediaItem.IsPdf">
            <summary>
            Tệp là PDF (hoá đơn quét) — view dựng icon + tên tệp thay cho thẻ ảnh.
            </summary>
            <remarks>Tính từ tệp đã nằm trên đĩa, không phải từ content-type client khai lúc tải lên.</remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceMediaItem.FileName">
            <summary>Tên tệp để hiển thị (chỉ có với PDF; tệp ảnh trả chuỗi rỗng)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceSaveResult">
            <summary>
            Kết quả lưu một lần bảo dưỡng — thêm <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceSaveResult.Id"/> để màn mới tải hoá đơn lên ngay sau khi tạo.
            Kế thừa <see cref="T:Lada.Framework.DTO.BaseResult"/> nên chữ ký service không đổi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintenanceSaveResult.Id">
            <summary>Id bản ghi vừa tạo/cập nhật; 0 khi thất bại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintLinkItem.TruckMaintAttributeId">
            <summary>Hạng mục theo danh mục cũ; null với dòng chỉ gắn bộ phận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintLinkItem.TruckComponentId">
            <summary>Bộ phận trên xe mà dòng công việc này chạm tới; null với dòng lịch sử</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintLinkItem.ActionType">
            <summary>Hành động lên bộ phận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintLinkItem.ActionTypeStr">
            <summary>Tên hành động để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckMaintLinkItem.LineCost">
            <summary>Chi phí riêng của dòng công việc</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions">
            <summary>
            Lớp mở rộng cho các phương thức ánh xạ giữa các đối tượng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.MapTo``2(``0)">
            <summary>
            Ánh xạ từ đối tượng nguồn sang đối tượng đích.
            </summary>
            <typeparam name="TSource">Loại của đối tượng nguồn.</typeparam>
            <typeparam name="TDestination">Loại của đối tượng đích.</typeparam>
            <param name="source">Đối tượng nguồn.</param>
            <returns>Đối tượng đích.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.MapTo``2(``0,``1)">
            <summary>
            Ánh xạ từ đối tượng nguồn sang đối tượng đích đã tồn tại.
            </summary>
            <typeparam name="TSource">Loại của đối tượng nguồn.</typeparam>
            <typeparam name="TDestination">Loại của đối tượng đích.</typeparam>
            <param name="source">Đối tượng nguồn.</param>
            <param name="destination">Đối tượng đích đã tồn tại.</param>
            <returns>Đối tượng đích đã được cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Finance.Expense)">
            <summary>
            Chuyển đổi đối tượng Expense sang ExpenseItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToModel(Lada.Framework.Data.Domains.Finance.Expense)">
            <summary>
            Chuyển đổi đối tượng Expense sang ExpenseModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Finance.BankAccount)">
            <summary>
            Chuyển đổi đối tượng BankAccount sang BankAccountItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Finance.BankTransaction)">
            <summary>
            Chuyển đổi đối tượng BankTransaction sang BankTransactionItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Finance.BankStatementImport)">
            <summary>
            Chuyển đổi đối tượng BankStatementImport sang BankStatementImportItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Finance.VatInvoice)">
            <summary>
            Chuyển đổi đối tượng VatInvoice sang VatInvoiceItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.VatInvoiceModel)">
            <summary>
            Chuyển đổi đối tượng VatInvoiceModel sang VatInvoice.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToModel(Lada.Framework.Data.Domains.Categories.Agency)">
            <summary>
            Chuyển đổi đối tượng Agency sang AgencyModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Categories.Agency)">
            <summary>
            Chuyển đổi đối tượng Agency sang AgencyItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyModel)">
            <summary>
            Chuyển đổi đối tượng AgencyModel sang Agency.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(System.Collections.Generic.List{Lada.Framework.Data.Domains.Categories.Agency})">
            <summary>
            Chuyển đổi danh sách đối tượng Agency sang danh sách AgencyItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToModel(Lada.Framework.Data.Domains.Crm.Customer)">
            <summary>
            Chuyển đổi đối tượng Customer sang CustomerModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Crm.Customer)">
            <summary>
            Chuyển đổi đối tượng Customer sang CustomerItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToSugItem(Lada.Framework.Data.Domains.Crm.Customer)">
            <summary>
            Chuyển đổi đối tượng Customer sang CustomerSugItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerModel)">
            <summary>
            Chuyển đổi đối tượng CustomerModel sang Customer.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToModel(Lada.Framework.Data.Domains.Crm.CustomerAddress)">
            <summary>
            Chuyển đổi đối tượng CustomerAddress sang CustomerAddressModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Crm.CustomerAddress)">
            <summary>
            Chuyển đổi đối tượng CustomerAddress sang CustomerAddressItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel)">
            <summary>
            Chuyển đổi đối tượng CustomerAddressModel sang CustomerAddress.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.LeadModel)">
            <summary>
            Chuyển đổi đối tượng Lead sang LeadModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToOptionItem(Lada.Framework.Data.Domains.Identity.User)">
            <summary>
            Chuyển đổi đối tượng User sang UserOptionItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToStaffItem(Lada.Framework.Data.Domains.Identity.User)">
            <summary>
            Chuyển đổi đối tượng User sang StaffItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToStaffModel(Lada.Framework.Data.Domains.Identity.User)">
            <summary>
            Chuyển đổi đối tượng User sang StaffModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Identity.Role)">
            <summary>
            Chuyển đổi đối tượng Role sang RoleItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToModel(Lada.Framework.Data.Domains.Identity.Role)">
            <summary>
            Chuyển đổi đối tượng Role sang RoleModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderAddressModel)">
            <summary>
            Chuyển đổi đối tượng OrderAddressModel sang OrderAddress.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToModel(Lada.Framework.Data.Domains.Orders.OrderAddress)">
            <summary>
            Chuyển đổi đối tượng OrderAddress sang OrderAddressModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToUpdateModel(Lada.Framework.Data.Domains.Orders.OrderAddress)">
            <summary>
            Chuyển đổi đối tượng OrderAddress sang UpdateOrderAddressModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Orders.OrderAddress)">
            <summary>
            Chuyển đổi đối tượng OrderAddress sang OrderAddressItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(System.Collections.Generic.List{Lada.Framework.Data.Domains.Orders.OrderAddress})">
            <summary>
            Chuyển đổi danh sách đối tượng OrderAddress sang danh sách OrderAddressItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel)">
            <summary>
            Chuyển đổi đối tượng OrderPackageModel sang OrderPackage.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToModel(Lada.Framework.Data.Domains.Orders.OrderPackage)">
            <summary>
            Chuyển đổi đối tượng OrderPackage sang OrderPackageModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Orders.OrderPackage)">
            <summary>
            Chuyển đổi đối tượng OrderPackage sang OrderPackageItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToResponseItem(Lada.Framework.Data.Domains.Orders.OrderPackage)">
            <summary>
            Chuyển đổi đối tượng OrderPackage sang OrderPackageResponseItem (với chuyển đổi đơn vị).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(System.Collections.Generic.List{Lada.Framework.Data.Domains.Orders.OrderPackage})">
            <summary>
            Chuyển đổi danh sách đối tượng OrderPackage sang danh sách OrderPackageItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToResponseItem(System.Collections.Generic.List{Lada.Framework.Data.Domains.Orders.OrderPackage})">
            <summary>
            Chuyển đổi danh sách đối tượng OrderPackage sang danh sách OrderPackageResponseItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderTrackModel)">
            <summary>
            Chuyển đổi đối tượng OrderTrackModel sang OrderTrack.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Orders.OrderTrack)">
            <summary>
            Chuyển đổi đối tượng OrderTrack sang OrderTrackItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(System.Collections.Generic.List{Lada.Framework.Data.Domains.Orders.OrderTrack})">
            <summary>
            Chuyển đổi danh sách đối tượng OrderTrack sang danh sách OrderTrackItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderTimeTrackModel)">
            <summary>
            Chuyển đổi đối tượng OrderTimeTrackModel sang OrderTimeTrack.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderFinModel)">
            <summary>
            Chuyển đổi đối tượng OrderFinModel sang OrderFin.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Orders.OrderFin)">
            <summary>
            Chuyển đổi đối tượng OrderFin sang OrderFinItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToUpdateModel(Lada.Framework.Data.Domains.Orders.OrderFin)">
            <summary>
            Chuyển đổi đối tượng OrderFin sang UpdateOrderFinModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderOpsModel)">
            <summary>
            Chuyển đổi đối tượng OrderOpsModel sang OrderOps.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Orders.OrderOps)">
            <summary>
            Chuyển đổi đối tượng OrderOps sang OrderOpsItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToOpsOrderItem(Lada.Framework.Data.Domains.Orders.OrderOps)">
            <summary>
            Chuyển đổi đối tượng OrderOps sang OpsOrderItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToModel(Lada.Framework.Data.Domains.Orders.Order)">
            <summary>
            Chuyển đổi đối tượng Order sang OrderModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel)">
            <summary>
            Chuyển đổi đối tượng OrderModel sang Order.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Orders.Order)">
            <summary>
            Chuyển đổi đối tượng Order sang OrderItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToOpsItem(Lada.Framework.Data.Domains.Orders.Order)">
            <summary>
            Chuyển đổi đối tượng Order sang OpsOrderItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToDetailModel(Lada.Framework.Data.Domains.Orders.Order)">
            <summary>
            Chuyển đổi đối tượng Order sang OrderDetailModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToPriceDetailModel(Lada.Framework.Data.Domains.Finance.Quotations.Price)">
            <summary>
            Chuyển đổi đối tượng Price sang PriceDetailModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Finance.Wallets.Wallet)">
            <summary>
            Chuyển đổi đối tượng Price sang PriceDetailModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToModel(Lada.Framework.Data.Domains.Finance.Wallets.Wallet)">
            <summary>
            Chuyển đổi đối tượng Wallet sang WalletDetailModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel)">
            <summary>
            Chuyển đổi đối tượng TruckModel sang Truck.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToModel(Lada.Framework.Data.Domains.Trucks.Truck)">
            <summary>
            Chuyển đổi đối tượng Truck sang TruckModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Trucks.Truck)">
            <summary>
            Chuyển đổi đối tượng Truck sang TruckItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(System.Collections.Generic.List{Lada.Framework.Data.Domains.Trucks.Truck})">
            <summary>
            Chuyển đổi danh sách đối tượng Truck sang danh sách TruckItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckActivityModel)">
            <summary>
            Chuyển đổi đối tượng TruckActivityModel sang TruckActivity.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Trucks.TruckActivity)">
            <summary>
            Chuyển đổi đối tượng TruckActivity sang TruckActivityItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(System.Collections.Generic.List{Lada.Framework.Data.Domains.Trucks.TruckActivity})">
            <summary>
            Chuyển đổi danh sách đối tượng TruckActivity sang danh sách TruckActivityItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Trucks.TruckAsset)">
            <summary>
            Chuyển đổi đối tượng TruckAsset sang TruckAssetItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(System.Collections.Generic.List{Lada.Framework.Data.Domains.Trucks.TruckAsset})">
            <summary>
            Chuyển đổi danh sách đối tượng TruckAsset sang danh sách TruckAssetItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckAssetModel)">
            <summary>
            Chuyển đổi đối tượng TruckAssetModel sang TruckAsset.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecAttributeModel)">
            <summary>
            Chuyển đổi đối tượng TruckSpecAttributeModel sang TruckSpecAttribute.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Trucks.TruckSpecAttribute)">
            <summary>
            Chuyển đổi đối tượng TruckSpecAttribute sang TruckSpecAttributeItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(System.Collections.Generic.List{Lada.Framework.Data.Domains.Trucks.TruckSpecAttribute})">
            <summary>
            Chuyển đổi danh sách đối tượng TruckSpecAttribute sang danh sách TruckSpecAttributeItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.GarageModel)">
            <summary>
            Chuyển đổi đối tượng GarageModel sang Garage.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Trucks.Garage)">
            <summary>
            Chuyển đổi đối tượng Garage sang GarageItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(System.Collections.Generic.List{Lada.Framework.Data.Domains.Trucks.Garage})">
            <summary>
            Chuyển đổi danh sách Garage sang danh sách GarageItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel)">
            <summary>
            Chuyển đổi đối tượng TruckComponentTypeModel sang TruckComponentType.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Trucks.TruckComponentType)">
            <summary>
            Chuyển đổi đối tượng TruckComponentType sang TruckComponentTypeItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(System.Collections.Generic.List{Lada.Framework.Data.Domains.Trucks.TruckComponentType})">
            <summary>
            Chuyển đổi danh sách TruckComponentType sang danh sách TruckComponentTypeItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintAttributeModel)">
            <summary>
            Chuyển đổi đối tượng TruckMaintAttributeModel sang TruckMaintAttribute.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Trucks.TruckMaintAttribute)">
            <summary>
            Chuyển đổi đối tượng TruckMaintAttribute sang TruckMaintAttributeItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(System.Collections.Generic.List{Lada.Framework.Data.Domains.Trucks.TruckMaintAttribute})">
            <summary>
            Chuyển đổi danh sách đối tượng TruckMaintAttribute sang danh sách TruckMaintAttributeItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintLinkModel)">
            <summary>
            Chuyển đổi đối tượng TruckMaintLinkModel sang TruckMaintLink.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Trucks.TruckMaintLink)">
            <summary>
            Chuyển đổi đối tượng TruckMaintLink sang TruckMaintLinkItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(System.Collections.Generic.List{Lada.Framework.Data.Domains.Trucks.TruckMaintLink})">
            <summary>
            Chuyển đổi danh sách đối tượng TruckMaintLink sang danh sách TruckMaintLinkItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel)">
            <summary>
            Chuyển đổi đối tượng TruckMaintenanceModel sang TruckMaintenance.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Trucks.TruckMaintenance)">
            <summary>
            Chuyển đổi đối tượng TruckMaintenance sang TruckMaintenanceItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(System.Collections.Generic.List{Lada.Framework.Data.Domains.Trucks.TruckMaintenance})">
            <summary>
            Chuyển đổi danh sách đối tượng TruckMaintenance sang danh sách TruckMaintenanceItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecificationModel)">
            <summary>
            Chuyển đổi đối tượng TruckSpecificationModel sang TruckSpecification.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(Lada.Framework.Data.Domains.Trucks.TruckSpecification)">
            <summary>
            Chuyển đổi đối tượng TruckSpecification sang TruckSpecificationItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToItem(System.Collections.Generic.List{Lada.Framework.Data.Domains.Trucks.TruckSpecification})">
            <summary>
            Chuyển đổi danh sách đối tượng TruckSpecification sang danh sách TruckSpecificationItem.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToDriverFinOrderModel(Lada.Framework.Data.Domains.Orders.Order,System.Int32)">
            <summary>
            Chuyển đổi Order sang DriverFinOrderModel với logic tùy chỉnh cho userId
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.MappingExtensions.ToDriverFinOrderItem(Lada.Framework.Data.Domains.Orders.Order,System.Int32)">
            <summary>
            Chuyển đổi Order sang DriverFinOrderItem với logic tùy chỉnh cho userId (cho search có phân trang)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsAccountModel">
            <summary>
            Model cập nhật phần cấu hình nội bộ của một tài khoản quảng cáo.
            Thông tin gốc (tên, tiền tệ, múi giờ) do nền tảng quyết định — chỉ đồng bộ về, không sửa từ LADA.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsAccountModel.IsActive">
            <summary>Có đưa tài khoản này vào các job đồng bộ định kỳ không</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidLevel">
            <summary>Cấp đối tượng được đổi giá thầu hàng loạt.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidLevel.Group">
            <summary>Nhóm quảng cáo (<c>ad_group.cpc_bid_micros</c>)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidLevel.Keyword">
            <summary>Từ khoá (<c>ad_group_criterion.cpc_bid_micros</c>)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel">
            <summary>
            Yêu cầu đổi giá thầu hàng loạt cho nhóm quảng cáo hoặc từ khoá.
            <para>
            Dùng cho <b>cả</b> <c>bulk-bid/preview</c> và <c>bulk-bid/apply</c>: xem trước và ghi thật
            phải nhận đúng một hình dạng dữ liệu, nếu không bảng xem trước sẽ không nói về thứ sắp ghi.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel.Level">
            <summary>Đổi giá thầu của nhóm quảng cáo hay của từ khoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel.EntityIds">
            <summary>
            Id nhóm hoặc Id từ khoá (theo <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel.Level"/>). Tối đa 500; có Id không tồn tại,
            đã xoá, hoặc khác nền tảng là từ chối cả lô (plan §3.9).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel.Operation">
            <summary>Phép tính áp lên giá thầu cũ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel.Value">
            <summary>
            Giá trị của phép tính: số tiền với <c>Set</c>/<c>IncreaseAmount</c>/<c>DecreaseAmount</c>,
            phần trăm với <c>IncreasePercent</c>/<c>DecreasePercent</c>. Luôn dương.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel.MinBid">
            <summary>Sàn tuỳ chọn — kẹp sau khi tính</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel.MaxBid">
            <summary>Trần tuỳ chọn — kẹp sau khi tính</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel.ExpectedOldBids">
            <summary>
            Giá thầu cũ mà <b>bảng xem trước đã hiện</b> cho từng dòng — hàng rào chống lệch giữa hai
            bước (sổ nợ N-31).
            <para>
            Vấn đề: <c>apply</c> tính lại giá từ giá đang có trong LADA. Người dùng gõ chữ xác nhận cho
            bảng "5.000 → 6.000 ₫", nhưng nếu giữa hai bước có ai đổi giá — hoặc chính lô đó vừa chạy
            một lần — thì <c>apply</c> tính từ giá mới và ghi ra con số khác con số đã xác nhận. Bảng
            xác nhận phải <b>ràng buộc</b> kết quả, không chỉ minh hoạ nó.
            </para>
            <para>
            Bỏ trống (hoặc thiếu dòng nào) = không kiểm dòng đó, giữ nguyên hành vi cũ: <c>preview</c>
            là nơi dựng ra bảng nên tự nó không có gì để đối chiếu. Giao diện luôn gửi đủ khi
            <c>apply</c> vì nút ghi chỉ mở sau khi đã xem trước.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidExpectation">
            <summary>
            Giá thầu cũ của một dòng tại thời điểm xem trước — dùng để phát hiện dữ liệu đã đổi giữa
            bước xem trước và bước ghi thật.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidExpectation.EntityId">
            <summary>Id nhóm hoặc Id từ khoá, khớp một phần tử của <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel.EntityIds"/></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidExpectation.OldBid">
            <summary>
            Giá thầu cũ đã hiện trên bảng xem trước. <c>null</c> là một giá trị <b>có nghĩa</b>
            ("đang kế thừa giá thầu nhóm"), không phải "không biết" — dòng đang kế thừa mà lúc ghi đã
            có giá riêng cũng là một thay đổi phải chặn.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidExpectation.ExpectedToChange">
            <summary>
            Bảng xem trước có xếp dòng này vào nhóm <b>sẽ đổi được</b> không.
            <para>
            Ràng buộc giá cũ thôi <b>chưa đủ</b> (finding <c>review-giai-doan</c> GĐ E). Ca lọt: một
            nhóm đang <c>SyncStatus != Synced</c> thì bước xem trước xếp là "bỏ qua — chưa đẩy lên
            nền tảng", nên ô xác nhận nói "muốn đổi giá thầu của 4 dòng" và người dùng gõ chữ cho
            đúng 4 dòng đó. Nếu giữa hai bước có ai bấm đồng bộ, nhóm thành <c>Synced</c> mà
            <c>CpcBid</c> không đổi → giá cũ vẫn khớp, hàng rào không thấy gì, và dòng thứ 5 được
            ghi tiền lên nền tảng mà không để lại dấu hiệu nào trong kết quả.
            </para>
            <para>
            <c>null</c> = client không khai, không kiểm — giữ đúng hợp đồng "không gửi thì không
            kiểm" của cả <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel.ExpectedOldBids"/>. Mặc định <c>false</c> sẽ
            biến mọi lời gọi cũ thành "bỏ qua sạch cả lô".
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkStatusModel">
            <summary>
            Yêu cầu bật / tạm dừng nhiều chiến dịch trong một lượt.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkStatusModel.Ids">
            <summary>Tối đa 500 Id; có Id không tồn tại hoặc đã xoá là từ chối cả lô (plan §3.9)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkStatusModel.Status">
            <summary>
            Trạng thái đích — chỉ nhận <see cref="F:Lada.Framework.Data.Enums.AdsEntityStatus.Enabled"/> hoặc
            <see cref="F:Lada.Framework.Data.Enums.AdsEntityStatus.Paused"/>. Xoá hàng loạt cố ý không đi đường này.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCampaignModel">
            <summary>
            Model tạo / cập nhật chiến dịch nháp trong LADA (chưa đẩy lên nền tảng).
            Wizard gửi cả cây: chiến dịch → nhóm → mẫu quảng cáo → targeting trong một lần lưu,
            vì tách nhiều lần lưu sẽ để lại chiến dịch không có nhóm nếu người dùng bỏ giữa đường.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCampaignModel.AdsAccountId">
            <summary>Tài khoản quảng cáo sẽ chạy chiến dịch</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCampaignModel.BudgetAmount">
            <summary>Ngân sách theo đơn vị tiền tệ của tài khoản (không phải micros)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCampaignModel.Groups">
            <summary>Danh sách nhóm quảng cáo</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsGroupModel">
            <summary>
            Nhóm quảng cáo trong model chiến dịch.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsGroupModel.Id">
            <summary>Id nhóm — Guid.Empty nghĩa là nhóm mới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsGroupModel.CpcBid">
            <summary>Giá thầu CPC tối đa theo đơn vị tiền tệ của tài khoản</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsGroupModel.CreativeIds">
            <summary>Các mẫu quảng cáo dùng trong nhóm này</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsGroupModel.Targeting">
            <summary>Targeting của nhóm</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsTargetingModel">
            <summary>
            Targeting của một nhóm quảng cáo.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsTargetingModel.Keywords">
            <summary>
            Từ khoá. Cú pháp giống Google Ads Editor: <c>[chính xác]</c>, <c>"khớp cụm"</c>,
            không dấu = khớp cụm (an toàn hơn khớp rộng về chi phí).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsTargetingModel.LocationIds">
            <summary>Mã vị trí của nền tảng (Google geo target constant id)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsTargetingModel.LanguageIds">
            <summary>Mã ngôn ngữ của nền tảng (Google language constant id)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBudgetChangeModel">
            <summary>
            Model đổi ngân sách của một chiến dịch đã đẩy lên nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBudgetChangeModel.DailyBudget">
            <summary>Ngân sách/ngày mới theo đơn vị tiền tệ của tài khoản</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsConnectionModel">
            <summary>
            Model tạo mới / cập nhật kết nối nền tảng quảng cáo.
            Các field mật (ClientSecret, DeveloperToken) nếu gửi lên còn chứa "***"
            thì service giữ nguyên giá trị đang lưu trong DB.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsConnectionModel.Name">
            <summary>Tên hiển thị của kết nối</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsConnectionModel.Platform">
            <summary>Nền tảng quảng cáo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsConnectionModel.ClientId">
            <summary>OAuth Client ID</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsConnectionModel.ClientSecret">
            <summary>OAuth Client Secret — SECRET</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsConnectionModel.DeveloperToken">
            <summary>Developer token (Google Ads, 22 ký tự) — SECRET</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsConnectionModel.LoginCustomerId">
            <summary>ID tài khoản quản lý (login-customer-id, không dấu gạch ngang)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsConnectionModel.RedirectUri">
            <summary>Redirect URI đã đăng ký với nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsConnectionModel.ApiVersion">
            <summary>Phiên bản API (Google: v25)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsConnectionModel.ExtraCredentials">
            <summary>
            Các credential đặc thù nền tảng mà cột chung không cover.
            Key trùng <c>AdsCredentialField.Key</c> do Capabilities khai báo.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeModel">
            <summary>
            Model tạo mới / cập nhật mẫu quảng cáo.
            Headline / description nhận dạng mảng, service tự serialize sang JSON của entity.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeModel.Platform">
            <summary>Nền tảng đích — quyết định giới hạn ký tự khi validate</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeModel.MarketingContentId">
            <summary>Nội dung AI Marketing nguồn (để truy vết ngược)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeModel.PostId">
            <summary>Bài viết CMS nguồn</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeFromContentModel">
            <summary>
            Yêu cầu tạo mẫu quảng cáo từ một nội dung nguồn.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeFromContentModel.Platform">
            <summary>Nền tảng đích — mặc định Google</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeFromContentModel.FinalUrl">
            <summary>
            URL đích của quảng cáo. Với bài CMS, để trống thì service tự dựng từ slug.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeFromContentModel.SaveAsCreative">
            <summary>
            true = lưu luôn thành mẫu trong LADA; false = chỉ trả gợi ý cho wizard hiển thị.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsIssueDismissModel">
            <summary>
            Bỏ qua một lô mục cùng loại việc. <c>EntityType</c> không nhận từ client — suy từ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsIssueDismissModel.Type"/>
            ở máy chủ, để client không thể ghi bản ghi lệch loại.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsIssueDismissModel.EntityIds">
            <summary>Id các mục (Guid chiến dịch, int tài khoản / kết nối, mã cố định) — tối đa 500, có Id lạ là từ chối cả lô</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsIssueDismissModel.Days">
            <summary>Số ngày bỏ qua, bỏ trống = 30 (Q1)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsIssueUndismissModel">
            <summary>
            Hiện lại các mục đã bỏ qua. <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsIssueUndismissModel.EntityIds"/> bỏ trống = hiện lại <b>mọi</b> mục còn hạn
            của loại đó — hành động này chỉ gỡ ẩn, không chạm dữ liệu đồng bộ nên không cần hàng rào Id.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordModel">
            <summary>
            Dữ liệu thêm/sửa một từ khoá <b>trong LADA</b>.
            <para>
            Lưu bằng model này KHÔNG gọi ra nền tảng: dòng mới là bản nháp
            (<see cref="F:Lada.Framework.Data.Enums.AdsSyncStatus.Local"/>), dòng đã có trên nền tảng bị sửa thì thành
            <see cref="F:Lada.Framework.Data.Enums.AdsSyncStatus.OutOfSync"/>. Muốn nền tảng biết thì phải đi tiếp bước
            xem trước rồi đẩy — đó là chỗ duy nhất tiêu tiền.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordModel.Id">
            <summary><c>Guid.Empty</c> nghĩa là từ khoá mới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordModel.AdsCampaignId">
            <summary>Chiến dịch chứa từ khoá — bắt buộc, kể cả với từ khoá cấp nhóm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordModel.AdsGroupId">
            <summary>
            Nhóm chứa từ khoá. Bỏ trống (null) nghĩa là từ khoá phủ định <b>cấp chiến dịch</b>.
            Bỏ trống mà <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordModel.IsNegative"/> = false là dữ liệu sai — Google không có từ khoá
            thường ở cấp chiến dịch, service sẽ báo lỗi chứ không tự đổi cấp.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordModel.IsNegative">
            <summary>Từ khoá phủ định hay từ khoá nhắm mục tiêu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordModel.Text">
            <summary>Nội dung từ khoá, không kèm dấu ngoặc của kiểu khớp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordModel.MatchType">
            <summary>Kiểu khớp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordModel.CpcBid">
            <summary>
            Giá thầu CPC riêng cho từ khoá. Bỏ trống = dùng giá thầu của nhóm.
            Không áp dụng cho từ khoá phủ định (phủ định không có giá thầu).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordBulkModel">
            <summary>
            Thêm nhiều từ khoá một lần bằng cách dán danh sách — mỗi dòng một từ khoá.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordBulkModel.AdsGroupId">
            <summary>null = phủ định cấp chiến dịch</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordBulkModel.MatchType">
            <summary>Kiểu khớp áp cho cả lô</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordBulkModel.Texts">
            <summary>
            Danh sách nội dung từ khoá. Dòng trắng bị bỏ qua; dòng trùng nhau (sau khi chuẩn hoá)
            bị gộp lại và <b>báo rõ số lượng đã gộp</b>, không âm thầm bỏ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleBulkSyncModel">
            <summary>Kéo lịch từ nền tảng về cho nhiều chiến dịch — chỉ đọc, không đổi gì trên tài khoản quảng cáo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleBulkSyncModel.CampaignIds">
            <summary>Tối đa 500 Id; có Id không tồn tại hoặc đã xoá là từ chối cả lô (plan §3.9)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleBulkTemplateModel">
            <summary>
            Model áp một mẫu lịch cho nhiều chiến dịch một lượt.
            <para>
            Dùng body (không phải query string) vì danh sách id có thể dài tới hàng chục phần tử.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleBulkTemplateModel.CampaignIds">
            <summary>
            Các chiến dịch cần áp. Có giới hạn số lượng một lô — xem
            <c>AdsScheduleService.MaxBulkCampaigns</c>. Vượt giới hạn thì báo lỗi,
            không âm thầm cắt bớt.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleBulkTemplateModel.TemplateKey">
            <summary>Khoá mẫu lịch — xem <c>AdsScheduleTemplates</c></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleBulkTemplateModel.BidModifier">
            <summary>
            % chung theo dạng hệ số Google (1.2 = +20%). <c>null</c> = dùng % của mẫu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleBulkTemplateModel.PushToPlatform">
            <summary>
            <c>false</c> = chỉ lưu nháp trong LADA. <c>true</c> = lưu nháp rồi đẩy lên nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleBulkTemplateModel.ValidateOnly">
            <summary>
            <c>true</c> = dry-run: nhờ nền tảng kiểm tra cả lô mà không ghi thật.
            Chỉ có nghĩa khi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleBulkTemplateModel.PushToPlatform"/> bằng <c>true</c>.
            <para>
            UI phải chạy dry-run trước rồi mới cho đẩy thật — áp sai lịch cho hàng chục chiến dịch
            cùng lúc là sự cố tốn tiền, không phải lỗi nhỏ.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleModel">
            <summary>
            Model tạo / cập nhật một khung giờ chạy quảng cáo trong LADA (bản nháp, chưa đẩy lên nền tảng).
            <para>
            Lưu ở đây KHÔNG gọi ra nền tảng: dòng được đánh <c>SyncStatus = OutOfSync</c> rồi chờ
            người dùng bấm "Đẩy lên nền tảng". Tách hai bước là cố ý — sửa lịch là đổi giá thầu,
            phải xem trước rồi mới ghi.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleModel.Id">
            <summary>Id khung giờ — <c>Guid.Empty</c> nghĩa là khung giờ mới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleModel.AdsCampaignId">
            <summary>Chiến dịch chứa khung giờ (ad schedule là criterion cấp chiến dịch)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleModel.DayOfWeek">
            <summary>Thứ trong tuần áp dụng khung giờ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleModel.StartHour">
            <summary>Giờ bắt đầu, 0–23</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleModel.StartMinute">
            <summary>Phút bắt đầu — chỉ nhận 0, 15, 30, 45</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleModel.EndHour">
            <summary>Giờ kết thúc, 1–24 (24 = hết ngày)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleModel.EndMinute">
            <summary>Phút kết thúc — chỉ nhận 0, 15, 30, 45</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleModel.BidModifier">
            <summary>
            Hệ số điều chỉnh giá thầu, lưu **đúng dạng hệ số của Google**: <c>1.2</c> = +20%,
            <c>0.5</c> = -50%. Người dùng gõ "+20" thì frontend phải đổi sang 1.2 trước khi gửi.
            <para>
            <c>null</c> = không điều chỉnh (Google hiện "—"). Đây là giá trị khác hẳn với 0.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.AI.AiProviderModel">
            <summary>
            Model DTO để tạo mới hoặc cập nhật AI Provider.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.AI.PromptTemplateModel">
            <summary>
            Model DTO để tạo mới hoặc cập nhật Prompt Template.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.CreateAppConfigModel">
            <summary>
            Model cho tạo mới AppConfig
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.UpdateAppConfigModel">
            <summary>
            Model cho cập nhật AppConfig
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.SearchAppConfigModel">
            <summary>
            Model cho search AppConfig
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.AppConfigResultModel">
            <summary>
            Model kết quả cho AppConfig
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.BulkUpdateAppConfigModel">
            <summary>
            Model cho bulk update AppConfig
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.AppConfigCacheStatusModel">
            <summary>
            Model cho cache status
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.MobileAppGateModel">
            <summary>
            Cấu hình màn hình chặn truy cập bằng điện thoại của app khách hàng (Lada.App).
            Mỗi thuộc tính tương ứng một khoá trong bảng AppConfig (tiền tố <c>MobileApp.</c>).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.MobileAppGateModel.Enabled">
            <summary>Bật chặn truy cập từ điện thoại. Tắt thì app khách chạy bình thường trên mọi thiết bị.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.MobileAppGateModel.IosUrl">
            <summary>Link tải app trên App Store (iOS).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.MobileAppGateModel.AndroidUrl">
            <summary>Link tải app trên CH Play (Android).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.MobileAppGateModel.QrImageUrl">
            <summary>
            Ảnh QR do quản trị tải lên. Có ảnh thì app khách hiển thị đúng ảnh này,
            bỏ trống thì app tự sinh QR từ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.MobileAppGateModel.QrTargetUrl"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.MobileAppGateModel.QrTargetUrl">
            <summary>
            Link mà mã QR trỏ tới khi app tự sinh QR (thường là trang tải app chung,
            tự điều hướng sang store theo hệ điều hành). Bỏ trống thì app dùng link Android.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.MobileAppGateModel.Title">
            <summary>Tiêu đề thông báo trên màn hình chặn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.MobileAppGateModel.Message">
            <summary>Nội dung thông báo trên màn hình chặn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.MobileAppGateModel.AllowContinue">
            <summary>
            Cho phép khách bấm "Tiếp tục trên trình duyệt" để bỏ qua màn hình chặn.
            Mặc định tắt — chặn cứng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Operations.FailModel.Reason">
            <summary>
            Lý do fail
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Operations.FailModel.Type">
            <summary>
            Loại cập nhật fail: lấy hàng, giao hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Operations.PickupModel.CollectedAmount">
            <summary>
            Số lái xe THỰC THU của người gửi khi lấy (Ví bưu cục v2 — E1): chỉ dùng khi bên lấy bật ví và đơn Người gửi trả / Thu 2 đầu;
            bỏ trống = bằng cước thu người gửi trên đơn; biên 0–150 % cước tạm tính, ngoài biên từ chối lấy. Đơn LADA thuần bỏ qua.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Warehouses.InboundModel.Weights">
            <summary>
            Cân thật từng đơn (gram) đo tại kho — Ví bưu cục v2: dùng chốt cước chính thức khi kho LADA nhập đơn có chi nhánh bật ví tham gia;
            bắt buộc khi AppConfig <c>FranchiseWallet.InboundWeightRequired</c> bật, thiếu thì chốt theo Σ cân kiện. Đơn LADA thuần bỏ qua.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Warehouses.InboundWeightModel">
            <summary>Cân thật của một đơn lúc nhập kho.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Warehouses.InboundWeightModel.WeightGram">
            <summary>Gram, &gt; 0.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Warehouses.OutboundModel">
            <summary>
            Model xuất kho trung chuyển
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Warehouses.OutboundModel.UserId">
            <summary>
            Mã người dùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Warehouses.OutboundModel.NextAgencyId">
            <summary>
            Trạm kế tiếp
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Warehouses.OutboundModel.OrderIds">
            <summary>
            Danh sách đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Warehouses.OutboundModel.UpdatedBy">
            <summary>
            Cập nhật bởi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Warehouses.OutboundModel.UpdatedByUserName">
            <summary>
            Cập nhật bởi
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AddLocationsToAgencyModel">
            <summary>
            Model để cập nhật danh sách location cho agency
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AddLocationsToAgencyModel.AgencyId">
            <summary>
            ID của đại lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AddLocationsToAgencyModel.LocationIds">
            <summary>
            Danh sách LocationId cần gán cho agency (chỉ phường/xã - Level 3)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AddLocationsToAgencyModel.UpdatedBy">
            <summary>
            ID người cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AddLocationsToAgencyModel.UpdatedByUserName">
            <summary>
            Tên người cập nhật
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyCoverageModel">
            <summary>
            Model cập nhật vùng phủ cho chi nhánh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyCoverageModel.AgencyId">
            <summary>
            Mã Agency
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyModel.Name">
            <summary>
            Tên chi nhánh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyModel.Description">
            <summary>
            Mô tả
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyModel.Code">
            <summary>
            Mã chi nhánh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyModel.ParentId">
            <summary>
            Đại lý cha
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyModel.RepresentativeId">
            <summary>
            Người đại diện pháp lý (người của đại lý)
            Nếu là phòng ban của LADA thì giá trị là 0
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyModel.ManagerName">
            <summary>
            Tên cán bộ quản lý (để hiển thị frontend)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyModel.Status">
            <summary>
            Trạng thái Agency
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyModel.CompanyName">
            <summary>
            Tên doanh nghiệp
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyModel.CompanyTaxCode">
            <summary>
            Mã số thuế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyModel.CompanyAddress">
            <summary>
            Địa chỉ công ty / xuất hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.EndPointsModel.StartId">
            <summary>
            Id của phường/xã gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.EndPointsModel.EndId">
            <summary>
            Id của phường/xã giao
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.EndPointsModel.Distance">
            <summary>
            Khoảng cách đầu cuối
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.EndPointsModel.LevelType">
            <summary>
            Loại cấp hành chính (2 cấp / 3 cấp).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.LocationModel.ParentId">
            <summary>
            Danh mục cha
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.LocationModel.Level">
            <summary>
            1: Tỉnh / thành phố, 2: Quận / huyện, 3: Phường / xã
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.LocationModel.Surcharge">
            <summary>
            Phụ phí khu vực (VND) của phường/xã. AreaSurchargeResolver tra trực tiếp
            cột này để ra phụ phí lấy/giao, nên thiếu trường ở đây là engine luôn tính 0.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.CategoryModel.Name">
            <summary>
            Tên danh mục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.CategoryModel.Description">
            <summary>
            Mô tả danh mục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.CategoryModel.DisplayOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.CategoryModel.ParentId">
            <summary>
            Danh mục cha
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.CategoryModel.IsFeatured">
            <summary>
            Là danh mục nổi bật hay không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.CategoryModel.ContentType">
            <summary>
            Loại danh mục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.CategoryModel.Icon">
            <summary>
            Mã icon Material (VD: "two_wheeler", "kitchen").
            Chỉ dùng cho ContentType = GoodsType.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.CategoryModel.ContentCategoryCode">
            <summary>
            Mã nhánh nội dung cấp 2 (A1, B3, F2...) để kho nội dung AI đăng bài vào đúng danh mục này.
            Bỏ trống với danh mục không thuộc kế hoạch nội dung.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryConfigModel">
            <summary>
            Model tạo/cập nhật cấu hình tính giá của danh mục hàng hóa (Admin)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryConfigModel.CategoryId">
            <summary>
            FK → Category (ContentType = GoodsType). Mỗi danh mục chỉ có 1 cấu hình.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryConfigModel.PricingMode">
            <summary>
            Cách áp giá thuộc tính vào cước đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryConfigModel.Note">
            <summary>
            Ghi chú nội bộ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryConfigModel.Attributes">
            <summary>
            Danh sách thuộc tính động kèm lựa chọn
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryAttributeModel">
            <summary>
            Model tạo/cập nhật thuộc tính động của danh mục hàng hóa
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryAttributeModel.Name">
            <summary>
            Tên hiển thị (VD: "Loại xe")
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryAttributeModel.Code">
            <summary>
            Mã slug (chỉ chữ thường / số / gạch ngang), không trùng trong cùng cấu hình
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryAttributeModel.Unit">
            <summary>
            Đơn vị đo, chỉ dùng cho NumberRange
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryAttributeModel.IsPriceAxis">
            <summary>
            Thuộc tính này có phải trục cột của bảng giá riêng theo tuyến không
            </summary>
            <remarks>
            ⚠️ Bật cờ này là <b>đổi cách tính tiền của cả danh mục</b>: danh mục chuyển từ tính theo trọng
            lượng sang tra ô bảng giá theo (tuyến, danh mục, lựa chọn trục). Cần xác nhận rõ ràng trên UI.
            Ràng buộc "tối đa 1 trục và phải là chọn một" kiểm ở tầng service bằng
            <see cref="T:Lada.Framework.Infrastructures.Services.PriceAxisRule"/>.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryAttributeModel.Options">
            <summary>
            Lựa chọn / khoảng giá trị kèm giá
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsAttributeOptionModel">
            <summary>
            Model tạo/cập nhật lựa chọn kèm giá của một thuộc tính
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsAttributeOptionModel.Price">
            <summary>
            Giá khi chọn lựa chọn này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsAttributeOptionModel.Weight">
            <summary>
            Trọng lượng quy ước khi chọn lựa chọn này (kg), 0 = không khai.
            Chỉ điền vào cân của kiện, không tính tiền — xem <c>GoodsAttributeOption.Weight</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsAttributeOptionModel.MinValue">
            <summary>
            Biên dưới (chỉ NumberRange), null = mở biên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsAttributeOptionModel.MaxValue">
            <summary>
            Biên trên (chỉ NumberRange), null = mở biên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostModel.Thumbnail">
            <summary>
            Ảnh đại diện (WebP)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostModel.OgImage">
            <summary>
            Ảnh đại diện dạng JPEG cho Open Graph / Social Media sharing
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostModel.Title">
            <summary>
            Tiêu đề bài viết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostModel.ShortDescription">
            <summary>
            Mô tả ngắn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostModel.Description">
            <summary>
            Nội dung bài viết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostModel.Status">
            <summary>
            Trạng thái bài viết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostModel.Visibility">
            <summary>
            Trạng thái bài viết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostModel.IsFeatured">
            <summary>
            Là bài viết nổi bật hay không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostModel.AgencyId">
            <summary>
            Bưu cục mà bài viết nói về (<c>Agency</c> LadaBranch/Franchise). <b>null = client không gửi → giữ nguyên</b>;
            0 = bỏ gắn; &gt; 0 = gắn. Form bài viết trước GĐ B1 chưa có ô này (bẫy DTO nullable, docs/plan-buu-cuc.md §7).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostModel.PostCategoryModels">
            <summary>
            Danh mục bài viết
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductBlockModel">
            <summary>
            Một khối nội dung của trang dịch vụ (dùng trong ProductModel.Blocks).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductBlockModel.Title">
            <summary>
            Tiêu đề khối, đồng thời là mục TOC trên trang. Có thể để trống.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductBlockModel.Payload">
            <summary>
            JSON theo schema từng loại block — service validate trước khi ghi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel.Thumbnail">
            <summary>
            Ảnh đại diện (WebP)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel.OgImage">
            <summary>
            Ảnh đại diện dạng JPEG cho Open Graph / Social Media sharing
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel.Name">
            <summary>
            Tên dịch vụ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel.ShortDescription">
            <summary>
            Mô tả ngắn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel.IsFeatured">
            <summary>
            Là sản phẩm nổi bật hay không?
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel.TOC">
            <summary>
            Table of Content
            Từ thẻ H3 => H6
            Tự sinh trong khi thêm mới / cập nhật bài viết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel.RouteFromCityId">
            <summary>
            Tỉnh đi của trang tuyến (<c>Location</c> Level 1 LevelType 2). <b>null = client không gửi → giữ nguyên</b>;
            0 = bỏ; &gt; 0 = đặt. Form Dịch vụ trước GĐ B1 chưa có ô này nên không được coi null là "xoá"
            (bẫy DTO nullable, docs/plan-buu-cuc.md §7).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel.RouteToCityId">
            <summary>Tỉnh đến của trang tuyến — cùng quy ước null/0/&gt;0 với <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel.RouteFromCityId"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel.Blocks">
            <summary>
            Các khối nội dung của trang dịch vụ, sắp theo SortOrder.
            Ghi theo kiểu replace-all như Tags/Categories, NHƯNG phân biệt:
            null = client không gửi trường này → giữ nguyên blocks hiện có
            (client cũ chưa biết blocks không được phép xoá dữ liệu);
            list rỗng = chủ ý xoá hết blocks.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel.SystemName">
            <summary>
            Tên hệ thống
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel.Title">
            <summary>
            Tiêu đề bài viết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel.IncludeInFooterColumn1">
            <summary>
            Gets or sets the value indicating whether this topic should be included in footer (column 1)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel.IncludeInFooterColumn2">
            <summary>
            Gets or sets the value indicating whether this topic should be included in footer (column 1)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel.IncludeInFooterColumn3">
            <summary>
            Gets or sets the value indicating whether this topic should be included in footer (column 1)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel.IncludeInFooterBottom">
            <summary>
            Hiển thị phần dưới cùng footer
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel.Description">
            <summary>
            Nội dung bài viết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel.Status">
            <summary>
            Trạng thái bài viết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel.Visibility">
            <summary>
            Trạng thái xem bài viết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel.Blocks">
            <summary>
            Khối nội dung ĐANG SỬA của topic có bộ khối (xem <c>GET api/Topic/BlockProfile</c>). Null = client không gửi →
            không đụng khối hiện có; GetById cũng trả null khi topic chưa có khối nào. Gửi danh sách thì cả bộ phải qua
            luật của bộ khối (vd. đúng 1 Form đăng ký). Topic không có bộ khối mà gửi danh sách khác rỗng → bị từ chối.
            Lưu cùng topic trong một transaction; sửa khối KHÔNG đổi trang công khai cho tới khi xuất bản.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel.PublishedAt">
            <summary>Chỉ đọc — lần xuất bản khối gần nhất. Client gửi lên cũng bị bỏ qua.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel.PublishedByUserName">
            <summary>Chỉ đọc — người xuất bản khối gần nhất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel.HasUnpublishedChanges">
            <summary>
            Chỉ đọc — bản đang sửa khác bản đã xuất bản (máy chủ so nội dung, xem <c>PublishedBlocks.SameContent</c>); FE
            hiện nhãn "Có thay đổi chưa xuất bản". False với topic không có bộ khối.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel.DraftVersion">
            <summary>
            Chỉ đọc — dấu phiên bản bản đang sửa (<c>PublishedBlocks.Fingerprint</c>). Nút "Xuất bản" gửi lại dấu này; có
            người lưu khối sau khi mở màn thì máy chủ từ chối thay vì xuất bản thứ người duyệt chưa xem. Null với topic không
            có bộ khối.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordModel.Slug">
            <summary>
            Gets or sets the slug
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordModel.EntityName">
            <summary>
            Tên thực thể và cũng là tên controller luôn
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordUpdateModel">
            <summary>
            Model để cập nhật thông tin cơ bản của UrlRecord
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordUpdateModel.Id">
            <summary>
            Id của UrlRecord cần cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordUpdateModel.MetaTitle">
            <summary>
            Meta title
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordUpdateModel.MetaDescription">
            <summary>
            Meta description
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordUpdateModel.MetaKeywords">
            <summary>
            Meta keywords
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordUpdateModel.IncludeInSiteMap">
            <summary>
            Có bao gồm trong sitemap hay không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordUpdateModel.Priority">
            <summary>
            Độ ưu tiên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordUpdateModel.Frequency">
            <summary>
            Mật độ cập nhật
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRedirectModel">
            <summary>
            Dữ liệu form thêm/sửa một luật chuyển hướng URL.
            </summary>
            <remarks>
            <b>Các <c>DataAnnotations</c> ở đây chỉ chặn cái rẻ tiền</b> — trống, quá dài, mã HTTP lạ. Luật
            thật (chuẩn hoá đường dẫn, chặn chuyển hướng ra tên miền ngoài, chặn chuỗi và vòng, tắt cờ
            sitemap) nằm ở tầng service, vì chúng phải đọc chính bảng đó và bảng <c>UrlRecord</c>. Đừng nhân
            đôi chúng lên đây: hai bản sao sẽ lệch nhau, và bản nào cũng trông như bản đúng.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRedirectModel.Id">
            <summary>Khoá; <c>null</c> hoặc <c>0</c> nghĩa là thêm mới.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRedirectModel.UpdatedBy">
            <summary>Người thực hiện — controller ghi từ token, form không gửi lên.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRedirectModel.UpdatedByUserName">
            <summary>Người thực hiện — controller ghi từ token, form không gửi lên.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Connect.ConnectLoginViewModel">
            <summary>Trang đăng nhập OAuth (/connect/login) — tài khoản LADA, dùng cho luồng cấp quyền MCP.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Connect.ConnectLoginViewModel.ReturnUrl">
            <summary>Đường dẫn quay lại /connect/authorize?… sau khi đăng nhập — chỉ nhận đường dẫn cục bộ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Connect.ConnectConsentViewModel">
            <summary>Trang đồng ý (/connect/authorize): client nào, user nào, xin quyền gì.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Connect.ConnectConsentViewModel.ResourceName">
            <summary>Tên mặt MCP đang xin kết nối ("LADA Express — kho nội dung AI", "LADA Express — số liệu vận hành").</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Connect.ConnectConsentViewModel.Parameters">
            <summary>Toàn bộ tham số OAuth của yêu cầu — chép lại thành input ẩn để POST giữ nguyên yêu cầu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Connect.ConnectDeniedViewModel">
            <summary>Trang thông báo từ chối / lỗi của luồng OAuth.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenCreateModel">
            <summary>Payload tạo token truy cập cá nhân (PAT) cho MCP — quản trị tạo hộ một user (plan §3.4).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenCreateModel.UserId">
            <summary>User mà token đại diện — không được là Founder, phải có ≥ 1 role ContentStore.*.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenCreateModel.Name">
            <summary>Tên gợi nhớ, ≤ 100 ký tự: "Claude Code máy Thắng".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenCreateModel.Scopes">
            <summary>Scope: content:read và/hoặc content:write.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenCreateModel.ExpiresInDays">
            <summary>Số ngày hiệu lực, 1..365; bỏ trống = 90.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenCreateResultModel">
            <summary>Kết quả tạo token — <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenCreateResultModel.PlainToken"/> chỉ trả về MỘT lần, không lưu và không tra lại được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenCreateResultModel.PlainToken">
            <summary>Chuỗi token lada_cs_… — sao chép ngay, server chỉ giữ hash.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenRevokeModel">
            <summary>Lý do thu hồi (tuỳ chọn).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenItem">
            <summary>Một token trong danh sách quản trị — không bao giờ chứa chuỗi token hay hash.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenItem.Prefix">
            <summary>16 ký tự đầu để nhận ra token.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenItem.IsActive">
            <summary>Chưa thu hồi và chưa hết hạn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenValidation">
            <summary>Kết quả kiểm một chuỗi token lúc xác thực /mcp — service, không phải HTTP.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAccessTokenValidation.FailureReason">
            <summary>Lý do từ chối (log server; không trả nguyên văn cho client ngoài 401).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleModel">
            <summary>
            Payload tạo bài nháp 4 phần (đặc tả §5.2 create_article_draft, Phụ lục A) — bản REST PascalCase.
            Enum nhận cả số lẫn tên (Newtonsoft mặc định). Dự án bật nullable nên [ApiController] coi thuộc tính
            không có dấu ? là bắt buộc (400 kèm tên trường): trường đặc tả bắt buộc để không-null, trường tuỳ chọn để ?.
            Service vẫn kiểm hình thức lần nữa (VALIDATION_ERROR) vì MCP (GĐ C) không đi qua MVC.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleModel.TopicCode">
            <summary>Mã đề bài, dạng W2-01 (regex ^W[0-9]{1,2}-[0-9]{2}$).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleModel.Slug">
            <summary>Slug không dấu ^[a-z0-9]+(-[a-z0-9]+)*$, ≤ 200.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleModel.AltTitles">
            <summary>Đúng 2 tiêu đề thay thế.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleModel.MetaDescription">
            <summary>≤ 320; > 155 chỉ cảnh báo mềm.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleModel.BodyMarkdown">
            <summary>
            Thân bài Markdown viết trọn, KHÔNG để ô chờ [[CẦN …]] (cơ chế ô chờ bỏ từ 2026-09-12); ≤ 200 KB.
            Số chưa có thì viết định tính và ghi khoản còn thiếu vào Brief.DataNeeded.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleModel.Images">
            <summary>Bộ ảnh — ≥ 1, đúng 1 ThumbnailOg.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleModel.DraftedBy">
            <summary>"claude-routine" hoặc tên người.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleBriefModel">
            <summary>Phần (a) BRIEF. Khoá lạ giữ trong Extra để không mất dữ liệu trợ lý gửi thêm.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleBriefModel.LateralLinks">
            <summary>≥ 2 link ngang hàng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleBriefModel.DataNeeded">
            <summary>
            Số liệu bài cần mà trợ lý không tra được — mỗi khoản một dòng, nói rõ chờ ai chốt. Đây là chỗ thay cho
            ô chờ [[CẦN …]] đã bỏ; danh sách này hiện ở tab Brief của màn duyệt để người duyệt biết phải hỏi ai.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleBriefModel.Branch">
            <summary>Chỉ bài BranchNews — điều kiện đăng §3.3d(4) đọc Address/Phone/OpeningHours.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleBriefModel.SubjectConsent">
            <summary>Feature/CaseStudy — điều kiện đăng §3.3d(5).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentFaqModel">
            <summary>Một cặp câu hỏi/trả lời FAQ — tách riêng để xuất FAQPage.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleFooterModel">
            <summary>Chân trang bài — hai dòng hồ sơ tác giả/người kiểm tra nằm ở đây (Phụ lục C đặc tả).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleFooterModel.Notes">
            <summary>
            Dòng chân trang không khớp nhãn nào khi nhập từ file .md — giữ lại để không mất chữ của người viết.
            Null khi không có (không serialize thừa).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageModel">
            <summary>Một dòng bộ ảnh (đặc tả §4.6) — prompt, chưa phải file.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageModel.OrderNo">
            <summary>1 = ảnh đại diện; duy nhất trong bài.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageModel.H2Key">
            <summary>Slug H2 mà ảnh minh hoạ; null với thumbnail.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageModel.NoneReason">
            <summary>Bắt buộc khi Decision = None.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageModel.FrameCode">
            <summary>E1, E2a… ^[A-E][1-6][a-d]?$</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageModel.Lane">
            <summary>"A" brand kit (mặc định) · "B" nền trơn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageModel.TextOnImage">
            <summary>null = không chữ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentSelfScoreModel">
            <summary>Phần (d) phiếu tự chấm — cấu trúc bắt buộc đặc tả §4.7. Khoá Sections giữ nguyên "A_facts"… vì là dữ liệu, không phải tên thuộc tính.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentSelfScoreModel.ReviewerTodos">
            <summary>Đúng 3 việc người duyệt phải sửa.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleCreateResultModel">
            <summary>Output của create_article_draft (đặc tả §5.2).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleCreateResultModel.ImageCounts">
            <summary>Khoá = tên enum ContentImageDecision: AiPrompt, ManualCanva, RealPhoto, None — luôn đủ 4 khoá.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleDetailModel">
            <summary>Bài đầy đủ trả về cho GetById / GetByTopicCode: 4 phần đã parse JSON + ảnh.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleDetailModel.ImageReferences">
            <summary>
            Ảnh tham chiếu thương hiệu đang bật — thứ người tạo ảnh phải đính kèm khi chạy prompt làn A.
            Kèm sẵn trong chi tiết bài để màn ảnh không phải gọi thêm một lượt nữa.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleRenderModel">
            <summary>Output của render_article.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleRenderModel.Format">
            <summary>"html" | "markdown".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleRenderModel.Content">
            <summary>Thân bài (+ FAQ nối cuối) ở định dạng yêu cầu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentStyleBaseModel">
            <summary>Payload lưu một phiên bản khối STYLE BASE / DO NOT.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentStyleBaseModel.Id">
            <summary>0 = tạo mới.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentStyleBaseModel.Code">
            <summary>Mã phiên bản, khớp <c>ContentImage.StyleBaseVersion</c> (ví dụ "laneA-2026-08-29").</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentStyleBaseModel.Lane">
            <summary>"A" hoặc "B".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentStyleBaseModel.StyleBaseText">
            <summary>Khối STYLE BASE — bắt buộc, đây là lý do tồn tại của bản ghi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentStyleBaseModel.IsDefault">
            <summary>Bản mặc định của làn. Bật bản này thì bản mặc định cũ của cùng làn tự tắt.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageFrameModel">
            <summary>Payload lưu một khuôn ảnh.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageReferenceModel">
            <summary>Payload lưu một ảnh tham chiếu thương hiệu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageReferenceModel.AssetUrl">
            <summary>Đường dẫn ảnh đã tải lên qua PictureController — bắt buộc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageReferenceModel.Lane">
            <summary>"A", "B" hoặc để trống nếu dùng cho mọi làn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishMode">
            <summary>
            Bài xuất bản ra <c>Post</c> ở trạng thái nào (plan §7.11 — Q6 chốt 2026-09-06).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishMode.WaitToPublish">
            <summary>Mặc định: <c>Post</c> vào hàng chờ, người trong CMS cũ bấm đăng như mọi bài khác.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishMode.PublishNow">
            <summary>
            Đăng thẳng lên website. <b>Đòi role <c>Post.Publish</c> ở tầng service</b>, không phải ở giao diện:
            MCP và PAT cũng đi qua đúng hàm này.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishModel">
            <summary>Yêu cầu xuất bản một bài sang CMS.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishModel.Mode">
            <summary>Mặc định <see cref="F:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishMode.WaitToPublish"/> (§7.11).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishModel.DryRun">
            <summary>
            <b>Mặc định TRUE, và đó là chủ ý.</b> GĐ E đã cắn đúng lỗi ngược lại: một đường "xem trước" mặc định
            an toàn mà vẫn ghi thật (spec §13.8). Ở đây hậu quả lớn hơn hẳn — ghi nhầm là một bài rác trên
            website đang phục vụ khách. Người gọi muốn ghi thật phải nói ra.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishModel.CmsCategoryId">
            <summary>
            Danh mục CMS. Bỏ trống thì lấy <c>ContentArticle.CmsCategoryId</c>, vẫn trống thì tra danh mục
            mang đúng mã nhánh nội dung của bài (<c>Category.ContentCategoryCode</c> = <c>CategoryL2</c>),
            cuối cùng mới tới <c>AppConfig ContentStore.DefaultCategoryId</c> (§7.10).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResultModel">
            <summary>Kết quả một lượt xuất bản — cùng một hình dạng cho lượt soát thử và lượt ghi thật.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResultModel.DryRun">
            <summary>true = chưa ghi một dòng nào.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResultModel.Slug">
            <summary>Slug bài — cũng là đường dẫn công khai <c>/{slug}</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResultModel.PostId">
            <summary>Id <c>Post</c> vừa tạo; null ở lượt soát thử.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResultModel.CmsCategorySource">
            <summary>
            Vì sao ra danh mục đó: "chọn trên bài", "khớp mã nhánh nội dung \"A2\"", hay
            "AppConfig ContentStore.DefaultCategoryId". Người duyệt đọc dòng này ở lượt soát thử để biết
            bài sắp rơi vào danh mục mặc định hay vào đúng nhánh của nó — hai chuyện trông giống hệt nhau
            nếu chỉ nhìn tên danh mục.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResultModel.Tags">
            <summary>
            Tên tag sẽ ghi (soát thử) hoặc đã ghi (thật) vào <c>PostTag</c>, theo đúng thứ tự: từ khoá chính
            trước, từ khoá phụ sau. Đã chuẩn hoá chữ thường như <c>TagService</c> của CMS.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResultModel.ValidFrom">
            <summary>Mốc đăng, luôn ghi ở +07:00 tường minh (§4.7 câu 3).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResultModel.ImageCount">
            <summary>Số ảnh thật sự được chèn vào thân bài (đã duyệt và có file).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResultModel.Html">
            <summary>HTML cuối cùng sẽ ghi vào <c>Post.Description</c> — trả cả ở lượt ghi thật để đối chiếu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResultModel.Toc">
            <summary>Mục lục sinh từ H3 ở máy chủ, sẽ ghi vào <c>Post.TOC</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResultModel.KhongCoAnh">
            <summary>Bài duyệt bằng cờ <c>PublishWithoutImages</c> nên lên website không có ảnh đại diện.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResultModel.SanitizerRemovedCount">
            <summary>Số lần sanitizer phải cắt. Khác 0 ở một bài bình thường là dấu hiệu đáng xem lại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResultModel.Actions">
            <summary>
            Việc sẽ ghi (soát thử) hoặc đã ghi (thật), theo đúng thứ tự. Đây là thứ người bấm đọc để biết
            lượt này chạm vào những bảng nào của CMS.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResyncModel">
            <summary>Yêu cầu đồng bộ lại ảnh của một bài <b>đã xuất bản</b> sang bài viết CMS của nó.</summary>
            <remarks>
            Đường sửa sau, cho đúng một tình huống: bài đã đăng rồi mới thấy ảnh không sang cùng (ảnh nộp muộn,
            hoặc ảnh rơi vì luật lọc cũ đòi <c>Approved</c>). Không tạo <c>Post</c> mới, không đụng slug, danh mục,
            FAQ hay trạng thái bài.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResyncModel.DryRun">
            <summary>Mặc định TRUE, cùng lý do với <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishModel.DryRun"/>: đây cũng là đường ghi ra website.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResyncResultModel">
            <summary>Kết quả một lượt đồng bộ lại ảnh — cùng hình dạng cho soát thử và ghi thật.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResyncResultModel.PostId">
            <summary>Bài viết CMS đang được sửa.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResyncResultModel.DryRun">
            <summary>true = chưa ghi một dòng nào.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResyncResultModel.KhongCoAnh">
            <summary>Bài không có ảnh đại diện dùng được — <c>Post.Thumbnail</c> giữ nguyên giá trị đang có.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResyncResultModel.ThumbnailDaDoi">
            <summary>Ảnh đại diện / OG của <c>Post</c> khác với ảnh trong kho ⇒ lượt này ghi lại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResyncResultModel.ThanBaiDaDoi">
            <summary>Thân bài dựng lại khác thân bài đang nằm trong <c>Post</c> ⇒ lượt này ghi lại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResyncResultModel.ThanBaiBiSuaTay">
            <summary>
            <c>Post.Description</c> không còn khớp bản do kho sinh ra — ai đó đã sửa bài trong CMS.
            Khi cờ này bật, lượt đồng bộ <b>không</b> đụng thân bài (chỉ ảnh đại diện), để không xoá công sửa tay.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResyncResultModel.ImageCount">
            <summary>Số ảnh chèn được vào thân bài dựng lại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResyncResultModel.Html">
            <summary>HTML thân bài sẽ ghi (hoặc đã ghi). Rỗng khi lượt này không đụng thân bài.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResyncResultModel.Actions">
            <summary>Việc sẽ ghi (soát thử) hoặc đã ghi (thật), theo đúng thứ tự.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishCategoryItem">
            <summary>Một danh mục CMS chọn được cho bài — đủ để dựng ô chọn ở màn đăng, không hơn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishCategoryItem.IsDefault">
            <summary>Danh mục sẽ dùng nếu người bấm không chọn gì (<c>ContentStore.DefaultCategoryId</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishCategoryItem.ContentCategoryCode">
            <summary>
            Mã nhánh nội dung gắn cho danh mục này (A1, B3, F2…), null nếu chưa gắn. Ô chọn ở màn đăng in nó
            cạnh tên để người bấm thấy ngay danh mục nào ứng với nhánh của bài — và thấy cả danh mục nào còn
            chưa ai gắn mã.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishSyncResultModel">
            <summary>Kết quả một lượt chạy job đồng bộ trạng thái đăng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishSyncResultModel.Checked">
            <summary>Số bài có <c>PostId</c> và <c>Post.Status = Published</c> nhưng bài còn ở <c>Approved</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleUpdateModel">
            <summary>
            Payload <c>update_article</c> (đặc tả §5.2). Mọi trường trong <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleUpdateModel.Patch"/> đều tuỳ chọn:
            null = không đụng tới, có giá trị = thay cả trường (không hợp nhất từng phần tử mảng).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleUpdateModel.ArticleId">
            <summary>Một trong hai: Id bài hoặc mã đề. Gửi cả hai thì Id thắng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleUpdateModel.ExpectedVersion">
            <summary>Số phiên bản người sửa đang cầm; lệch bản hiện tại → 409 VERSION_CONFLICT.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleUpdateModel.ChangeNote">
            <summary>Ghi chú thay đổi, vào <c>ContentArticleVersion.ChangeNote</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticlePatchModel">
            <summary>Các trường sửa được của bài — trùng danh sách đặc tả §5.2 patch.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleUpdateResultModel">
            <summary>Kết quả sửa bài: bản mới sau khi lưu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleUpdateResultModel.VersionNo">
            <summary>Số phiên bản mới (= bản cũ + 1).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleStatusModel">
            <summary>Payload <c>set_article_status</c> (đặc tả §5.2).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleStatusModel.Reason">
            <summary>Lý do — bắt buộc khi chuyển sang Tạm giữ / Từ chối / Chờ dữ liệu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleApproveModel">
            <summary>
            Payload duyệt đăng (§3.3d) — đường ghi RIÊNG, gác bằng <c>ContentStore.Approve</c> thay vì
            <c>ContentStore.Edit</c> của <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleStatusModel"/>.
            <para>
            Ba trường ghi đè là <b>quyết định của người duyệt</b>, chỉ lưu khi bài thật sự qua đủ 8 điều kiện:
            gửi cờ mà bài còn thiếu điều kiện khác thì máy chủ trả 422 và <b>không ghi gì</b>.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleApproveModel.PublishWithoutImages">
            <summary>Đăng khi bộ ảnh chưa duyệt xong (§3.3d(6)) — bật thì <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleApproveModel.PublishWithoutImagesReason"/> bắt buộc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleApproveModel.PublishWithoutImagesReason">
            <summary>Vì sao chấp nhận đăng thiếu ảnh — vào cột cùng tên, hiện lại trên màn duyệt.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleApproveModel.OverrideNote">
            <summary>Ghi chú bỏ qua ngưỡng điểm tự chấm (§3.3d(8)) — có ghi chú thì điểm dưới 80 vẫn duyệt được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleApproveModel.Reason">
            <summary>Ghi chú duyệt, vào <c>ContentArticle.StatusReason</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleRevokeApprovalModel">
            <summary>Payload rút lại bài đã duyệt (Approved → PendingReview) — cũng cần <c>ContentStore.Approve</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleRevokeApprovalModel.Reason">
            <summary>Lý do rút lại — bắt buộc, để lịch sử nói được vì sao bài rời khỏi hàng chờ đăng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicStatusModel">
            <summary>Payload <c>update_topic_status</c> (đặc tả §5.1) — <c>Drafted</c> bắt buộc kèm ArticleId.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentSlugCheckModel">
            <summary>Kết quả <c>check_slug</c> (đặc tả §5.3).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentSlugCheckModel.Suggestion">
            <summary>Slug trống gần nhất dạng <c>slug-2</c>; null khi slug đang trống hoặc thử 20 lần đều bận.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentSlugCheckModel.TakenBy">
            <summary>Ai đang giữ slug: "ContentArticle #12" hoặc "UrlRecord" (kể cả bản xoá mềm của CMS).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentSlugCheckModel.Message">
            <summary>Giải thích cho người đọc khi slug sai định dạng hoặc không gợi ý được.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAuthorModel">
            <summary>
            Hồ sơ tác giả — dữ liệu E-E-A-T đứng tên trên bài, không nhất thiết là tài khoản hệ thống.
            Điều kiện đăng §3.3d(2) đòi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAuthorModel.ProfileUrl"/> không rỗng nên đây là trường phải nhập.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAuthorModel.Id">
            <summary>0 = tạo mới.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAuthorModel.UserId">
            <summary>Tài khoản người dùng tương ứng, nếu người này có tài khoản.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAuthorListRequest">
            <summary>Tham số <c>list_people</c> (đặc tả §5.3).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAuthorListRequest.RoleTitle">
            <summary>Lọc theo chức danh, so khớp chứa chuỗi không phân biệt hoa thường.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAuthorListRequest.IsActive">
            <summary>Mặc định chỉ người còn hoạt động.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAuthorListRequest.Limit">
            <summary>Mặc định 50, tối đa 200.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticlePeopleModel">
            <summary>Gán tác giả / người kiểm tra cho một bài.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentRunLogModel">
            <summary>Payload <c>append_run_log</c> (đặc tả §5.1).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentRunLogModel.Scores">
            <summary>Điểm tự chấm từng bài trong lượt — trung bình tính ở server.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentRunLogModel.PlaceholdersTotal">
            <summary>
            DI SẢN — tổng số ô chờ theo loại. Cơ chế ô chờ bỏ từ 2026-09-12, trường này chỉ còn để đọc lại nhật ký
            những lượt chạy cũ; lượt mới bỏ trống.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImportResultModel">
            <summary>Kết quả nhập một lượt: mỗi file một dòng, thành công hay không đều có dòng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImportResultModel.CreatedTopicCodes">
            <summary>Đề bài được tạo mới trong lượt này (file có mã đề chưa có trong hàng đợi).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImportFileResultModel">
            <summary>Một file trong lượt nhập.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImportFileResultModel.ErrorCode">
            <summary>Mã lỗi khi thất bại (mã của parser hoặc của CreateDraft).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImportFileResultModel.Errors">
            <summary>Vi phạm cứng kèm dòng — người sửa file đọc thẳng danh sách này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImportFileResultModel.SlugSuggestion">
            <summary>Gợi ý slug khi slug trùng — người nhập tự quyết, server không đổi im lặng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentStoreIssueModel">
            <summary>Bản sao gọn của <c>ContentStoreIssue</c> để trả trong kết quả nhập (giữ nguyên vị trí).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageStatusModel">
            <summary>
            Cập nhật một dòng ảnh sau khi nộp file (đặc tả §5.3 <c>set_image_status</c>). Mỗi trường null = không đụng tới.
            Chỉ chạm bốn cột kết quả — mọi thông số ảnh (khuôn, làn, prompt, kích thước) vẫn thuộc <c>update_article</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageStatusModel.AssetUrl">
            <summary>URL ảnh đã tải lên (từ <c>PictureController</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageStatusModel.OgAssetUrl">
            <summary>URL bản JPEG cho OG — chỉ ảnh <c>ThumbnailOg</c> mới có.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageStatusModel.QaNote">
            <summary>Ghi chú kiểm ảnh, vào <c>ContentImage.QaChecklistJson</c> dạng <c>{ "note": "..." }</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishCheckModel">
            <summary>
            Kết quả kiểm điều kiện đăng (§3.3d) — CHỈ ĐỌC ở GĐ D: màn chi tiết hiện danh sách còn thiếu,
            không có nút duyệt. GĐ E nối đúng lớp kiểm này vào <c>set_article_status(Approved)</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishCheckModel.Ready">
            <summary>Không còn điều kiện nào thiếu (không có nghĩa là đã duyệt — duyệt là GĐ E).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishCheckModel.Checks">
            <summary>Đủ 7 điều kiện §3.3d theo thứ tự, mỗi điều kiện đạt hay không kèm lý do.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishCheckModel.Missing">
            <summary>Chỉ những điều kiện chưa đạt — để giao diện hiện nhanh.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishCheckItemModel">
            <summary>Một điều kiện đăng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishCheckItemModel.Rule">
            <summary>Mã cố định để giao diện gắn hành động: AUTHOR_PROFILE, CHECKER, BRANCH_INFO, SUBJECT_CONSENT, IMAGES, CONTENT_GATE, SELF_SCORE.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishCheckItemModel.Detail">
            <summary>Câu nói rõ thiếu gì khi chưa đạt; rỗng khi đạt.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImportFolderModel">
            <summary>Tham số nhập cả thư mục — đường dẫn đưa qua tham số, không hard-code trong code.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImportFolderModel.Path">
            <summary>Đường dẫn tuyệt đối tới thư mục chứa file .md trên máy chạy API.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImportFolderModel.DryRun">
            <summary>Chỉ đọc, không ghi gì — để soát trước khi nhập thật.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicModel">
            <summary>Một đề bài trong payload create_topics (đặc tả §5.1).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicModel.TopicCode">
            <summary>W2-03 — ^W[0-9]{1,2}-[0-9]{2}$.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicModel.WeekNo">
            <summary>Bỏ trống thì suy từ TopicCode (W2-03 → 2).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicModel.CategoryL2">
            <summary>A2, B2, F1… ^[A-F][0-9]$ — CategoryL1 suy từ ký tự đầu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicModel.SortOrder">
            <summary>Bỏ trống thì xếp sau đề cuối cùng đang có.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicModel.Notes">
            <summary>Tuỳ chọn — dấu ? để [ApiController] không coi là bắt buộc (dự án bật nullable).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicListRequest">
            <summary>Tham số list_topics (đặc tả §5.1): trả theo SortOrder tăng dần.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicListRequest.ExcludeL2">
            <summary>Mã L2 loại trừ, ví dụ ["F2"] khi F2 chưa mở bán.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicListRequest.Limit">
            <summary>Mặc định 20, tối đa 100.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicCreateResultModel">
            <summary>Kết quả tạo hàng loạt: đề hợp lệ được tạo, đề trùng mã / sai định dạng bị từ chối từng dòng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.McpClientRegistrationRequest">
            <summary>
            Yêu cầu đăng ký client động (RFC 7591) tới <c>POST /connect/register</c> — Claude.ai / Cowork / ChatGPT gửi
            khi người dùng thêm connector. Tên trường theo RFC, không theo quy ước PascalCase của REST.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.McpClientRegistrationResponse">
            <summary>Phản hồi 201 của đăng ký client động (RFC 7591 §3.2.1).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.McpClientRegistrationError">
            <summary>Lỗi 400 theo RFC 7591 §3.2.2: <c>invalid_redirect_uri</c> hoặc <c>invalid_client_metadata</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.BulkAssignManagerModel">
            <summary>
            Model chứa thông tin gán người quản lý hàng loạt cho khách hàng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel">
            <summary>
            CallLog Model - DTO cho tạo/cập nhật cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.HistoryID">
            <summary>
            Call number - mỗi cuộc gọi có một số, nội bộ của 3CX
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.CallID">
            <summary>
            Call ID - định danh duy nhất của cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.Duration">
            <summary>
            Thời gian cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.TimeStart">
            <summary>
            Thời gian bắt đầu cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.TimeAnswered">
            <summary>
            Thời gian trả lời
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.TimeEnd">
            <summary>
            Thời gian kết thúc cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.ReasonTerminated">
            <summary>
            Lý do cuộc gọi bị chấm dứt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.FromNo">
            <summary>
            Số điện thoại nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.ToNo">
            <summary>
            Số điện thoại đích
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.FromDN">
            <summary>
            Distinguished name của người gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.ToDN">
            <summary>
            Distinguished name của đích
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.DialNo">
            <summary>
            Số được quay
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.ReasonChanged">
            <summary>
            Lý do thay đổi trong cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.FinalNumber">
            <summary>
            Số cuối cùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.FinalDN">
            <summary>
            Distinguished name của số cuối cùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.BillCode">
            <summary>
            Mã thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.BillRate">
            <summary>
            Tỷ lệ thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.BillCost">
            <summary>
            Chi phí của cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.BillName">
            <summary>
            Tên tỷ lệ của biến thể thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.Chain">
            <summary>
            Tất cả các điểm cuối tham gia vào cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.FromType">
            <summary>
            Loại nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.ToType">
            <summary>
            Loại đích
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.FinalType">
            <summary>
            Loại đích cuối cùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.FromDispName">
            <summary>
            Tên hiển thị nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.ToDispName">
            <summary>
            Tên hiển thị đích
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.FinalDispName">
            <summary>
            Tên hiển thị đích cuối cùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.MissedQueueCalls">
            <summary>
            Danh sách các agent hàng đợi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.CallType">
            <summary>
            Loại cuộc gọi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.LeadStatus">
            <summary>
            Trạng thái Lead
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel.StatusContent">
            <summary>
            Nội dung trạng thái
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel">
            <summary>
            Đối tượng đại diện cho thông tin địa chỉ của khách hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel.Address">
            <summary>
            Địa chỉ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel.FullAddress">
            <summary>
            Địa chỉ đầy đủ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel.CityId">
            <summary>
            Id của tỉnh/thành phố.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel.DistrictId">
            <summary>
            Id của quận/huyện.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel.WardId">
            <summary>
            Id của phường/xã.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel.ContactPhoneNumber">
            <summary>
            Số điện thoại liên hệ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel.ContactName">
            <summary>
            Tên người liên hệ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel.Lat">
            <summary>
            Latitude của địa chỉ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel.Long">
            <summary>
            Longitude của địa chỉ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel.AddressType">
            <summary>
            Loại địa chỉ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel.Note">
            <summary>
            Ghi chú.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel.CustomerId">
            <summary>
            Id của khách hàng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel">
            <summary>
            Model tạo/cập nhật tài khoản ngân hàng khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel.Id">
            <summary>
            ID (0 nếu tạo mới)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel.AccountNumber">
            <summary>
            Số tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel.AccountHolderName">
            <summary>
            Tên chủ tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel.BankCode">
            <summary>
            Mã ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel.BankName">
            <summary>
            Tên ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel.BranchName">
            <summary>
            Tên chi nhánh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel.BranchAddress">
            <summary>
            Địa chỉ chi nhánh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel.IsDefault">
            <summary>
            Có phải tài khoản mặc định
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel.UpdatedBy">
            <summary>
            Người cập nhật (sẽ được set từ controller)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel.UpdatedByUsername">
            <summary>
            Tên người cập nhật (sẽ được set từ controller)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel.Validate">
            <summary>
            Validate model
            </summary>
            <returns></returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.ComplaintProcessModel">
            <summary>
            Model thao tác xử lý khiếu nại phía nhân viên (tiếp nhận / phản hồi / giải quyết).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.ComplaintProcessModel.StaffResponse">
            <summary>
            Phản hồi của nhân viên cho khách (bắt buộc khi phản hồi; khi giải quyết phải có sẵn hoặc truyền kèm)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.ManagerChangeRequestProcessModel">
            <summary>
            Model duyệt/từ chối yêu cầu đổi nhân viên phụ trách.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.ManagerChangeRequestProcessModel.NewManagerId">
            <summary>
            Nhân viên phụ trách mới (bắt buộc khi duyệt, bỏ qua khi từ chối)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.ManagerChangeRequestProcessModel.ProcessedNote">
            <summary>
            Ghi chú khi duyệt/từ chối (bắt buộc khi từ chối để khách biết lý do)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerModel.FullName">
            <summary>
            Họ và tên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerModel.PhoneNumber">
            <summary>
            Số điện thoại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerModel.Address">
            <summary>
            Địa chỉ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerModel.Email">
            <summary>
            Địa chỉ email
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerModel.ZaloContact">
            <summary>
            Liên hệ zalo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerModel.FacebookContact">
            <summary>
            Liên hệ zalo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerModel.UseCustomPriceList">
            <summary>
            Khách có bảng giá riêng. Bật → engine tra bảng giá riêng trước, thiếu thì mượn bảng mặc định
            (QĐ-2). Tắt → luôn dùng bảng mặc định.
            </summary>
            <remarks>
            Cờ này cũng <b>bỏ phụ phí khu vực</b> — xem <c>AreaSurchargeResolver.cs:77</c>. Đó là chủ ý
            đã chốt: khách có bảng giá riêng đã tính trọn phí vận chuyển trong giá, phụ phí khu vực là
            phần dư. Ai "sửa" hành vi này sẽ thu khách hai lần.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerPropModel">
            <summary>
            Lớp dùng để cập nhật từng thông tin của khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerPropModel.PropType">
            <summary>
            Loại thông tin cần cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerPropModel.Value">
            <summary>
            Giá trị cần cập nhật
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerSetPasswordModel">
            <summary>
            Thông tin đặt lại mật khẩu cho tài khoản đăng nhập của khách hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerSetPasswordModel.CustomerId">
            <summary>
            Id của KHÁCH HÀNG (không phải Id người dùng).
            Backend tự tra ra tài khoản đăng nhập gắn với khách hàng này — nhờ vậy quyền
            <c>Customer.SetPassword</c> không thể dùng để đổi mật khẩu của nhân viên hay quản trị.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerSetPasswordModel.Password">
            <summary>
            Mật khẩu mới.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.LeadStatusModel.FullName">
            <summary>
            Họ và tên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.LeadStatusModel.PhoneNumber">
            <summary>
            Số điện thoại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.LeadStatusModel.Message">
            <summary>
            Thông tin cần hỗ trợ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.LeadStatusModel.SourcePath">
            <summary>
            Đường dẫn gửi
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.RegisterCustomerAccountModel">
            <summary>
            Thông tin tạo tài khoản đăng nhập cho một khách hàng đã có hồ sơ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.RegisterCustomerAccountModel.CustomerId">
            <summary>
            Id của khách hàng cần tạo tài khoản.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.RegisterCustomerAccountModel.UserName">
            <summary>
            Tên đăng nhập.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.RegisterCustomerAccountModel.Password">
            <summary>
            Mật khẩu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.RegisterCustomerAccountModel.ConfirmPassword">
            <summary>
            Xác nhận mật khẩu.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.UpdateCustomerAddressCoordModel">
             <summary>
             Thông tin cập nhật định vị (toạ độ) cho một địa chỉ trong sổ địa chỉ khách hàng.
            
             Tách khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel"/> vì đây là thao tác riêng: chỉ ghi
             Lat/Long, KHÔNG đụng tới tỉnh/phường nên không ảnh hưởng tới cước hay bưu cục
             dự kiến của các đơn dùng địa chỉ này. Cùng dạng với
             <c>UpdateOrderAddressCoordModel</c> của địa chỉ đơn hàng.
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.UpdateCustomerAddressCoordModel.Id">
            <summary>
            Id của địa chỉ khách hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.UpdateCustomerAddressCoordModel.Lat">
            <summary>
            Vĩ độ. Để null (cả Lat và Long) nghĩa là xoá định vị đang có.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.UpdateCustomerAddressCoordModel.Long">
            <summary>
            Kinh độ. Để null (cả Lat và Long) nghĩa là xoá định vị đang có.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.VatInfoModel">
            <summary>
            Model thông tin xuất hóa đơn VAT (dùng cho cả tạo mới và cập nhật)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.VatInfoModel.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.VatInfoModel.CompanyName">
            <summary>
            Tên công ty/cá nhân
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.VatInfoModel.TaxCode">
            <summary>
            Mã số thuế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.VatInfoModel.InvoiceEmail">
            <summary>
            Email nhận hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.VatInfoModel.Address">
            <summary>
            Địa chỉ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.VatInfoModel.ContactName">
            <summary>
            Người liên hệ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.VatInfoModel.ContactPhone">
            <summary>
            Điện thoại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.VatInfoModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.VatInfoModel.IsDefault">
            <summary>
            Có phải mặc định không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DashboardModel.CurrentAttendance">
            <summary>
            Thông tin chấm công hiện tại (nếu đã check-in nhưng chưa check-out)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DashboardModel.HasCheckedInToday">
            <summary>
            Đã check-in hôm nay chưa
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DashboardModel.HasCheckedOutToday">
            <summary>
            Đã check-out hôm nay chưa
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DashboardModel.TodayCheckInTime">
            <summary>
            Thời gian check-in hôm nay (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DashboardModel.TodayCheckOutTime">
            <summary>
            Thời gian check-out hôm nay (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DashboardModel.TodayCheckInOdo">
            <summary>
            ODO khi check-in hôm nay
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DashboardModel.TodayCheckOutOdo">
            <summary>
            ODO khi check-out hôm nay
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DashboardModel.CurrentTruck">
            <summary>
            Thông tin xe đang phụ trách (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DashboardModel.HasAssignedTruck">
            <summary>
            Có đang phụ trách xe nào không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DashboardModel.CurrentTruckLicensePlate">
            <summary>
            Biển số xe đang phụ trách
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DashboardModel.CurrentTruckAgencyName">
            <summary>
            Tên đại lý của xe đang phụ trách
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DashboardModel.CurrentTruckLatestOdo">
            <summary>
            ODO gần nhất của xe đang phụ trách
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppPickupModel">
            <summary>
            Model cập nhật trạng thái lấy hàng cho Driver App
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppPickupModel.AgencyId">
            <summary>
            ID đại lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppPickupModel.MediaList">
            <summary>
            Danh sách media (ảnh, video)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppPickupModel.CollectedAmount">
            <summary>
            Số lái xe THỰC THU của người gửi khi lấy (Ví bưu cục v2 — E1): chỉ dùng khi bên lấy bật ví và đơn Người gửi trả / Thu 2 đầu;
            null = bằng cước thu người gửi trên đơn (app chưa có ô nhập — GĐ E); biên 0–150 % cước tạm tính, ngoài biên từ chối lấy.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppDeliveryModel">
            <summary>
            Model cập nhật trạng thái giao hàng cho Driver App
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppDeliveryModel.AgencyId">
            <summary>
            ID đại lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppDeliveryModel.MediaList">
            <summary>
            Danh sách media (ảnh, video)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppReturnModel">
            <summary>
            Model cập nhật trạng thái trả hàng thành công cho Driver App
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppReturnModel.AgencyId">
            <summary>
            ID đại lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppReturnModel.MediaList">
            <summary>
            Danh sách media (ảnh, video) minh chứng trả hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailModel">
            <summary>
            Model cập nhật trạng thái thất bại cho Driver App
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailModel.Reason">
            <summary>
            Lý do thất bại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailModel.Type">
            <summary>
            Loại cập nhật thất bại: lấy hàng, giao hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailModel.MediaList">
            <summary>
            Danh sách media (ảnh, video) minh chứng thất bại (không bắt buộc)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailType">
            <summary>
            Enum loại thất bại cho Driver App
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailType.PickupFail">
            <summary>
            Lấy hàng thất bại
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailType.DeliveryFail">
            <summary>
            Giao hàng thất bại
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailType.ReturnFail">
            <summary>
            Trả hàng thất bại
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinModel">
            <summary>
            Model chứa thông tin tài chính của lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinModel.TotalSourceFee">
            <summary>
            Tổng số tiền cước lấy hàng (SourceFee) lái xe đang cầm
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinModel.TotalDestFee">
            <summary>
            Tổng số tiền cước giao hàng (DestFee) lái xe đang cầm
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinModel.TotalCollectAmount">
            <summary>
            Tổng số tiền thu hộ (COD) lái xe đang cầm
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinModel.TotalAmount">
            <summary>
            Tổng số tiền lái xe đang cầm (SourceFee + DestFee + CollectAmount)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinModel.WalletHeldAmount">
            <summary>
            Ví bưu cục v2 (V-40): tiền lái xe bưu cục nhượng quyền bật ví THU HÔM NAY (giờ VN) trên đơn Ví ghi — nộp cho bưu cục, KHÔNG nộp
            LADA, nên không nằm trong các tổng trên. Chỉ hôm nay vì stage đơn Ví ghi không bao giờ rời "Lái xe đang cầm". App hiện băng khi &gt; 0.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinModel.WalletHeldOrderCount">
            <summary>Số đơn Ví ghi lái xe thu tiền hôm nay (đi cùng <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinModel.WalletHeldAmount"/>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinModel.HasPendingSlip">
            <summary>
            Có phiếu chuyển tiền đang chờ duyệt không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinModel.PendingSlip">
            <summary>
            Thông tin phiếu đang chờ duyệt (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinModel.RecentOrders">
            <summary>
            Danh sách 10 đơn gần đây nhất mà lái xe đang cầm tiền
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinOrderModel">
            <summary>
            Model chứa thông tin đơn hàng mà lái xe đang cầm tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinOrderModel.OrderId">
            <summary>
            ID của đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinOrderModel.OrderCode">
            <summary>
            Mã đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinOrderModel.SourceFee">
            <summary>
            Số tiền cước lấy hàng (SourceFee) của đơn này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinOrderModel.DestFee">
            <summary>
            Số tiền cước giao hàng (DestFee) của đơn này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinOrderModel.CollectAmount">
            <summary>
            Số tiền thu hộ (COD) của đơn này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinOrderModel.TotalAmount">
            <summary>
            Tổng số tiền của đơn này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinOrderModel.CreatedDate">
            <summary>
            Ngày tạo đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverFinOrderModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.ReorderModel">
            <summary>
            Model sắp xếp thứ tự đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.ReorderModel.Items">
            <summary>
            Danh sách thứ tự đơn hàng mới
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.ReorderItem">
            <summary>
            Item sắp xếp thứ tự đơn hàng (OrderId + vị trí mới)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.ReorderItem.OrderId">
            <summary>
            ID đơn hàng (OrderOps Id)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.ReorderItem.DisplayOrder">
            <summary>
            Thứ tự hiển thị mới
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchModel">
            <summary>
            Yêu cầu tải giọng đọc cho một loạt câu chỉ dẫn (<c>POST api/Tts/Batch</c>).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchModel.Texts">
            <summary>
            Các câu cần đọc, ĐÃ chuẩn hoá ở app (plan §3.5.5), theo thứ tự cần trước → cần sau.
            Tối đa <c>Tts:MaxTextsPerBatch</c> câu, mỗi câu tối đa <c>Tts:MaxTextLength</c> ký tự.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchModel.Have">
            <summary>
            Hash những câu app ĐÃ có file trên máy — server vẫn trả dòng kết quả cho câu đó nhưng
            không gửi lại bytes âm thanh. Không bắt buộc.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchResult">
            <summary>Kết quả <c>POST api/Tts/Batch</c>.</summary>
            <remarks>
            <c>Result == Success</c>: mọi câu hợp lệ đã có âm thanh — trừ câu bị nguồn từ chối riêng lẻ
            (<c>ErrorCode = "Rejected"</c>) hoặc đang chờ nguồn tự host sinh nền (<c>"Pending"</c>); hai loại
            đó vẫn tính là Success, app bỏ câu im lặng. <c>Result == Failed</c> kèm <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchResult.ErrorCode"/>
            khi lỗi ở tầng nguồn/hạn mức: app chuyển nút loa sang lỗi, nhưng các dòng đã <c>Ready</c> vẫn dùng được.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchResult.ErrorCode">
            <summary>
            Mã lỗi cấp lượt gọi, rỗng khi không lỗi. Một trong <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsErrorCodes"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchResult.VoiceKey">
            <summary>
            Nhận diện giọng đang dùng — đổi giọng/engine/nguồn trên server thì chuỗi này đổi, app bỏ các
            file giọng cũ thay vì trộn hai giọng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchResult.Items">
            <summary>Kết quả từng câu, cùng thứ tự với <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchModel.Texts"/>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchItem">
            <summary>Kết quả của một câu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchItem.Text">
            <summary>Câu đã chuẩn hoá khoảng trắng — chính chuỗi được đọc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchItem.Hash">
            <summary>Khoá cache (sha256 hex) — app lưu file theo khoá này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchItem.Ready">
            <summary>Đã có âm thanh ở server.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchItem.Audio">
            <summary>
            Bytes âm thanh (JSON: base64). <c>null</c> khi chưa sẵn sàng hoặc khi hash nằm trong
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchModel.Have"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchItem.ErrorCode">
            <summary>Mã lỗi riêng câu này khi chưa sẵn sàng, rỗng khi sẵn sàng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsErrorCodes">
            <summary>Mã lỗi của gateway giọng đọc — app rẽ nhánh theo mã, không theo câu chữ.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsErrorCodes.Invalid">
            <summary>
            Yêu cầu sai: cả lượt (số câu ngoài 1…60 → HTTP 400) hoặc RIÊNG một câu (rỗng, quá dài, ký tự
            cấm → dòng đó mang mã này, các câu khác vẫn xử lý).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsErrorCodes.NotConfigured">
            <summary>Server chưa có khoá nguồn giọng (VieNeu Cloud hoặc sidecar tự host), hoặc khoá bị từ chối.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsErrorCodes.QuotaExhausted">
            <summary>Hết token / gói hết hạn (VieNeu Cloud 403).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsErrorCodes.RateLimited">
            <summary>Nguồn giới hạn tần suất hoặc hạn mức ngày (429), hoặc hàng đợi sidecar đầy.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsErrorCodes.Unavailable">
            <summary>Nguồn lỗi hoặc không kết nối được.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsErrorCodes.Timeout">
            <summary>Nguồn quá thời gian chờ.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsErrorCodes.BudgetExceeded">
            <summary>Vượt trần ký tự câu mới trong ngày (của người dùng hoặc toàn server).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsErrorCodes.Rejected">
            <summary>Nguồn từ chối riêng câu này.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsErrorCodes.Pending">
            <summary>
            Câu chưa có ở nguồn tự host, đã xếp hàng sinh nền (RTF ≈ 2, không sinh lúc xe chạy). Chỉ ở
            cấp CÂU, không bao giờ làm cả lượt thất bại. Đã kiểm code app 2026-09-28: dòng không
            <c>Ready</c> bị bỏ qua im lặng, không vào <c>Have</c> nên tự được hỏi lại ở lượt sau — app
            không cần sửa.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsStatusResult">
            <summary>
            Ảnh chụp trạng thái gateway giọng đọc cho người vận hành (<c>GET api/Tts/Status</c>): nguồn đang có
            hiệu lực, năm khoá AppConfig đã nạp (khoá bí mật che), kết quả thăm dò sidecar và một lượt tổng hợp
            thử qua đúng đường app đi. Có vì backend production chỉ ghi log ra console (IIS không giữ) — không
            có endpoint này thì "app không tải được giọng" không biết hỏng ở tầng nào (đợt tự host 2026-09-28).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsStatusResult.Engine">
            <summary>Tên lớp engine đang có hiệu lực: <c>VieNeuCloudEngine</c> hay <c>VieNeuSelfHostEngine</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsStatusResult.IsConfigured">
            <summary>Engine có khoá/địa chỉ để gọi được không. <c>false</c> = app sẽ nhận <c>NotConfigured</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsStatusResult.CacheKey">
            <summary>Khoá cache của nguồn (thành phần hash) — đổi giọng/phiên bản/nguồn là đổi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsStatusResult.VoiceKey">
            <summary>Nhận diện giọng app nhận về — khác giá trị app đang giữ là app bỏ chỉ mục cũ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsStatusResult.AppConfig">
            <summary>Giá trị AppConfig theo khoá (khoá bí mật che, chỉ còn độ dài và 4 ký tự đầu); trống = chưa có / rơi về appsettings.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsStatusResult.Effective">
            <summary>Giá trị đang dùng sau khi hợp nhất AppConfig + appsettings (khoá che).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsStatusResult.CacheDir">
            <summary>Thư mục cache mp3 của backend (<c>Tts:CacheDir</c> hoặc <c>{ContentRoot}/App_Data/tts-cache</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsStatusResult.CacheWritable">
            <summary>Tiến trình tạo được thư mục và ghi/xoá được một file thử trong đó. <c>false</c> = mọi câu có âm thanh sẽ Unavailable.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsStatusResult.CacheWriteError">
            <summary>Lỗi khi thử ghi (loại ngoại lệ + thông điệp), rỗng khi ghi được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsStatusResult.CacheFileCount">
            <summary>Số file âm thanh đang có trong cache (đếm tới 100.000).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsStatusResult.SidecarHealth">
            <summary>Kết quả <c>GET {BaseUrl}/health</c> của sidecar (chỉ khi nguồn tự host): mã HTTP + thân cắt ngắn, hoặc lỗi kết nối.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsStatusResult.Probe">
            <summary>Kết quả lượt tổng hợp thử qua <c>TtsCacheService</c> với một câu cố định.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsProbeResult">
            <summary>Một lượt thử <c>BatchAsync</c> với câu <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsProbeResult.Text"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsProbeResult.Text">
            <summary>Câu thử — đoạn cố định sidecar sinh sẵn nên bình thường phải <c>Ready</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsProbeResult.Result">
            <summary>Success / Failed của lượt.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsProbeResult.ErrorCode">
            <summary>Mã lỗi cấp lượt, rỗng khi không lỗi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsProbeResult.ItemErrorCode">
            <summary>Mã lỗi riêng câu thử (ví dụ <c>Pending</c>), rỗng khi sẵn sàng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsProbeResult.Ready">
            <summary>Câu thử đã có âm thanh.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsProbeResult.AudioBytes">
            <summary>Số byte âm thanh trả về (0 khi chưa sẵn sàng hoặc app đã có).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsProbeResult.ElapsedMs">
            <summary>Thời gian lượt thử, mili giây.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsProbeResult.Message">
            <summary>Thông điệp của gateway (câu chữ cho người vận hành).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Email.EmailAccountModel">
            <summary>
            Model tài khoản gửi email (dùng cho cả tạo mới và cập nhật).
            Lưu ý: <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Email.EmailAccountModel.Password"/> và <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Email.EmailAccountModel.SecretKey"/> khi CẬP NHẬT để trống
            nghĩa là GIỮ NGUYÊN giá trị (đã mã hóa) cũ — chỉ ghi đè khi nhập giá trị mới.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Email.EmailAccountModel.Name">
            <summary>
            Tên gợi nhớ (VD: "SES chính - Singapore").
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Email.EmailAccountModel.ProviderType">
            <summary>
            Loại nhà cung cấp: SMTP / SES / Mock.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Email.EmailAccountModel.Password">
            <summary>Mật khẩu SMTP (giá trị thô mới nhập; để trống khi sửa = giữ nguyên).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Email.EmailAccountModel.SecretKey">
            <summary>Secret key SES (giá trị thô mới nhập; để trống khi sửa = giữ nguyên).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Email.EmailAccountModel.IsDefault">
            <summary>Tài khoản gửi mặc định (chỉ 1 tài khoản mặc định).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Email.EmailAccountModel.SortOrder">
            <summary>Thứ tự ưu tiên fallback (nhỏ hơn = thử trước).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Email.EmailAccountModel.IsActive">
            <summary>Đang bật để dùng hay không.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Email.EmailTestSendModel">
            <summary>
            Model yêu cầu gửi email thử để kiểm tra cấu hình một tài khoản.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Email.EmailTestSendModel.Id">
            <summary>ID tài khoản gửi cần kiểm tra.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Email.EmailTestSendModel.ToEmail">
            <summary>Email người nhận thử.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportModel">
            <summary>
            Model để tạo mới báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportModel.Url">
            <summary>
            URL trang web xảy ra lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportModel.ErrorDescription">
            <summary>
            Nội dung mô tả lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportModel.ReporterName">
            <summary>
            Tên người báo lỗi (nếu không đăng nhập)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportModel.ReporterEmail">
            <summary>
            Email người báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportModel.ReporterPhone">
            <summary>
            Số điện thoại người báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportModel.BrowserInfo">
            <summary>
            Thông tin trình duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportModel.DeviceInfo">
            <summary>
            Thông tin thiết bị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportModel.Images">
            <summary>
            Danh sách hình ảnh lỗi
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportUpdateModel">
            <summary>
            Model để cập nhật báo lỗi (dành cho admin)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportUpdateModel.Id">
            <summary>
            ID báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportUpdateModel.Status">
            <summary>
            Trạng thái xử lý báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportUpdateModel.AdminNote">
            <summary>
            Ghi chú từ admin khi xử lý
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BalanceAdjustmentModel">
            <summary>
            Model để điều chỉnh số dư ví (cân ví)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BalanceAdjustmentModel.DesiredBalance">
            <summary>
            Số dư mong muốn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BalanceAdjustmentModel.Reason">
            <summary>
            Lý do điều chỉnh
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountModel">
            <summary>
            Model cho tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountModel.AccountName">
            <summary>
            Tên tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountModel.AccountNumber">
            <summary>
            Số tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountModel.BankId">
            <summary>
            ID thông tin ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountModel.ManagerUserId">
            <summary>
            Người quản lý tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountModel.AutoUpdateBalance">
            <summary>
            Có tự động cập nhật số dư không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountModel.CanCollectCod">
            <summary>
            Tài khoản có thể thu hộ COD (tài khoản nhận cước)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountDetailModel">
            <summary>
            Model chi tiết tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountDetailModel.BankName">
            <summary>
            Tên ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountDetailModel.BankCode">
            <summary>
            Mã ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountDetailModel.ManagerUserName">
            <summary>
            Tên người quản lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountDetailModel.ManagerFullName">
            <summary>
            Họ tên người quản lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountDetailModel.LastBalanceUpdate">
            <summary>
            Ngày cập nhật số dư cuối cùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountDetailModel.LastTransactionDate">
            <summary>
            Ngày giao dịch cuối cùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountDetailModel.TransactionCount">
            <summary>
            Số lượng giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountDetailModel.CurrentBalance">
            <summary>
            Số dư hiện tại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountDetailModel.MonthlyIncome">
            <summary>
            Tổng tiền vào trong tháng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountDetailModel.MonthlyOutcome">
            <summary>
            Tổng tiền ra trong tháng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportModel">
            <summary>
            Model cho import sao kê ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportModel.BankAccountId">
            <summary>
            ID tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportModel.ExcelFile">
            <summary>
            File Excel sao kê
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportModel.OverwriteExisting">
            <summary>
            Có ghi đè dữ liệu trùng lặp không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportModel.FromDate">
            <summary>
            Ngày bắt đầu lọc dữ liệu (optional)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportModel.ToDate">
            <summary>
            Ngày kết thúc lọc dữ liệu (optional)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportModel.AutoCategorize">
            <summary>
            Có tự động phân loại giao dịch không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportModel.UpdateAccountBalance">
            <summary>
            Có cập nhật số dư tài khoản không
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportResult">
            <summary>
            Kết quả import sao kê ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportResult.ImportId">
            <summary>
            ID import
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportResult.TotalRows">
            <summary>
            Tổng số dòng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportResult.ProcessedRows">
            <summary>
            Số dòng xử lý thành công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportResult.ErrorRows">
            <summary>
            Số dòng lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportResult.SkippedRows">
            <summary>
            Số dòng bỏ qua
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportResult.DuplicateRows">
            <summary>
            Số dòng trùng lặp
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportResult.ErrorMessages">
            <summary>
            Danh sách thông báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportResult.WarningMessages">
            <summary>
            Danh sách cảnh báo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportResult.ImportedTransactions">
            <summary>
            Danh sách giao dịch đã import
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportResult.ProcessingTimeMs">
            <summary>
            Thời gian xử lý (milliseconds)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportResult.FinalBalance">
            <summary>
            Số dư tài khoản sau khi import
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportResult.FirstTransactionDate">
            <summary>
            Ngày giao dịch đầu tiên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportResult.LastTransactionDate">
            <summary>
            Ngày giao dịch cuối cùng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportSearchModel">
            <summary>
            Model tìm kiếm import sao kê
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportSearchModel.Keyword">
            <summary>
            Từ khóa tìm kiếm
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportSearchModel.BankAccountId">
            <summary>
            ID tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportSearchModel.BankCode">
            <summary>
            Mã ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportSearchModel.ImportStatus">
            <summary>
            Trạng thái import
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportSearchModel.ImportDateFrom">
            <summary>
            Ngày import từ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportSearchModel.ImportDateTo">
            <summary>
            Ngày import đến
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportSearchModel.ImportedByUserId">
            <summary>
            Người thực hiện import
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementParseResult">
            <summary>
            Kết quả parse file sao kê
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementParseResult.IsSuccess">
            <summary>
            Có thành công không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementParseResult.ErrorMessage">
            <summary>
            Thông báo lỗi chính
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementParseResult.ErrorMessages">
            <summary>
            Danh sách thông báo lỗi chi tiết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementParseResult.TotalRows">
            <summary>
            Tổng số dòng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementParseResult.ProcessedRows">
            <summary>
            Số dòng xử lý thành công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementParseResult.ErrorRows">
            <summary>
            Số dòng lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementParseResult.Transactions">
            <summary>
            Danh sách giao dịch đã parse
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel">
            <summary>
            Model cho giao dịch ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel.BankAccountId">
            <summary>
            ID tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel.TransactionCode">
            <summary>
            Mã giao dịch từ ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel.TransactionDate">
            <summary>
            Ngày giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel.CreditAmount">
            <summary>
            Số tiền ghi có (tiền vào)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel.DebitAmount">
            <summary>
            Số tiền ghi nợ (tiền ra)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel.Balance">
            <summary>
            Số dư sau giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel.Description">
            <summary>
            Nội dung giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel.DetailedTime">
            <summary>
            Thời gian giao dịch chi tiết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel.ProcessStatus">
            <summary>
            Trạng thái xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel.TransactionType">
            <summary>
            Loại giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel.ReferenceNumber">
            <summary>
            Mã tham chiếu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel.CounterpartyName">
            <summary>
            Tên người gửi/nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel.CounterpartyAccount">
            <summary>
            Số tài khoản người gửi/nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel.CounterpartyBank">
            <summary>
            Ngân hàng của người gửi/nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionModel.ProcessNote">
            <summary>
            Ghi chú xử lý
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionSearchModel">
            <summary>
            Model tìm kiếm giao dịch ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionSearchModel.Keyword">
            <summary>
            Từ khóa tìm kiếm
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionSearchModel.BankAccountId">
            <summary>
            ID tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionSearchModel.TransactionCode">
            <summary>
            Mã giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionSearchModel.TransactionDateFrom">
            <summary>
            Ngày giao dịch từ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionSearchModel.TransactionDateTo">
            <summary>
            Ngày giao dịch đến
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionSearchModel.AmountFrom">
            <summary>
            Số tiền từ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionSearchModel.AmountTo">
            <summary>
            Số tiền đến
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionSearchModel.TransactionDirection">
            <summary>
            Loại giao dịch (Credit/Debit)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionSearchModel.ProcessStatus">
            <summary>
            Trạng thái xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionSearchModel.TransactionType">
            <summary>
            Loại giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankTransactionSearchModel.ImportId">
            <summary>
            ID import
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CancelReconciliationModel">
            <summary>
            Model hủy đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CancelReconciliationModel.ReconciliationId">
            <summary>
            ID đối soát cần hủy
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CancelReconciliationModel.CancelReason">
            <summary>
            Lý do hủy đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CancelReconciliationModel.Note">
            <summary>
            Ghi chú bổ sung
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CancelReconciliationModel.CancelledBy">
            <summary>
            Người hủy (sẽ được set từ controller)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CancelReconciliationModel.CancelledByUsername">
            <summary>
            Tên người hủy (sẽ được set từ controller)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CancelReconciliationModel.CancelledTime">
            <summary>
            Thời gian hủy (sẽ được set từ service)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CancelReconciliationModel.CreateOrderTrack">
            <summary>
            Có tạo OrderTrack không (mặc định true)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CancelReconciliationModel.SendNotification">
            <summary>
            Có gửi thông báo không (mặc định false)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CancelReconciliationModel.Validate">
            <summary>
            Validate model
            </summary>
            <returns>Danh sách lỗi validation</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeModel">
            <summary>
            Model để kiểm tra giá cước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeModel.SourceWardId">
            <summary>
            Phường / xã nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeModel.DestWardId">
            <summary>
            Phường / xã đích
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeModel.Distance">
            <summary>
            Khoảng cách
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeModel.Weight">
            <summary>
            Trọng lượng (Kg)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeModel.GoodsCategoryId">
            <summary>
            Danh mục hàng hóa khách chọn (Category có ContentType = GoodsType).
            Null = không phân loại, giữ nguyên cách báo giá cũ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeModel.GoodsAttributes">
            <summary>
            Lựa chọn thuộc tính hàng hóa. Client chỉ gửi lựa chọn, giá luôn resolve từ DB.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeModel.GoodsLines">
            <summary>
            Các loại hàng của đơn, mỗi món một dòng. Rỗng = đơn một loại hàng ⇒ dùng
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeModel.Weight"/> / <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeModel.GoodsCategoryId"/> / <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeModel.GoodsAttributes"/> như trước.
            </summary>
            <remarks>
            Gửi danh sách này thì ba trường trên <b>không còn được dùng để tra cước</b> — xem
            <c>OrderFeeCalculationRequest.GoodsLines</c>.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeGoodsLineModel">
            <summary>
            Một loại hàng trong lần báo giá: loại hàng + trọng lượng tính cước + lựa chọn thuộc tính của nó.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeGoodsLineModel.GoodsCategoryId">
            <summary>
            Loại hàng của món. <c>null</c> / <c>0</c> = không khai ⇒ backend điền loại mặc định cho riêng món này.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeGoodsLineModel.Weight">
            <summary>
            Trọng lượng tính cước của món, đơn vị <b>Kg</b> — giống <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeModel.Weight"/>,
            controller quy đổi sang gram khi dựng request.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeGoodsLineModel.GoodsAttributes">
            <summary>Lựa chọn thuộc tính hàng hóa của riêng món này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CheckFeeGoodsLineModel.Name">
            <summary>Tên hàng hóa — chỉ để ghi vào căn cứ dòng phí, không tham gia phép tính.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CopyPriceListModel">
            <summary>
            Model sao chép bảng giá từ một phạm vi nguồn sang phạm vi đích.
            </summary>
            <remarks>
            <para>
            <b>Chặn copy chéo hình dạng:</b> bảng giá chung là <i>tuyến × khoảng trọng lượng</i>, bảng loại
            hàng là <i>tuyến × lựa chọn trục</i> — khác hình dạng, không nhân bản được. Nên
            <c>SourceGoodsCategoryId</c> và <c>TargetGoodsCategoryId</c> phải cùng <c>null</c> hoặc cùng có giá
            trị (hai loại hàng khác nhau thì ok, miễn đều là bảng loại hàng).
            </para>
            <para>
            ⚠️ <b>Đừng nhầm với <c>InitGoodsCategoryPriceMatrix</c></b> — chức năng đó sinh mới bằng tích
            Descartes <c>routes × options</c> với <c>Value = BaseValue * factor</c>. Chức năng này copy dòng
            <c>Price</c> thật từ phạm vi nguồn.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CopyPriceListModel.SourceCustomerId">
            <summary>Khách nguồn. <c>0</c> = khách mặc định.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CopyPriceListModel.SourceGoodsCategoryId">
            <summary>Loại hàng nguồn. <c>null</c> = bảng giá chung theo cân.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CopyPriceListModel.TargetCustomerId">
            <summary>Khách đích. <c>0</c> = khách mặc định.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CopyPriceListModel.TargetGoodsCategoryId">
            <summary>Loại hàng đích. <c>null</c> = bảng giá chung theo cân.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CopyPriceListModel.PriceType">
            <summary>Loại giá (FixPrice / StepPrice / …).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CopyPriceListModel.OverwriteExisting">
            <summary>
            <c>true</c> = đè ô đã có ở đích. <b>Mặc định <c>false</c></b> — bỏ qua ô đã tồn tại, không
            đè im lặng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CopyPriceListModel.AdjustPercent">
            <summary>
            Tỷ lệ điều chỉnh giá, tính theo phần trăm. <c>null</c> = copy nguyên giá. <c>10</c> = tăng 10%.
            <c>-5</c> = giảm 5%.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel">
            <summary>
            Model tạo đối soát mới
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.FromDate">
            <summary>
            Từ ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.ToDate">
            <summary>
            Đến ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.OrderIds">
            <summary>
            Danh sách ID đơn hàng được chọn để đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.Note">
            <summary>
            Ghi chú đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.BankAccountNumber">
            <summary>
            Số tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.BankAccountHolderName">
            <summary>
            Tên chủ tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.BankCode">
            <summary>
            Mã ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.BankName">
            <summary>
            Tên ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.BankBranchName">
            <summary>
            Tên chi nhánh ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.BankBranchAddress">
            <summary>
            Địa chỉ chi nhánh ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.TransferInfo">
            <summary>
            Thông tin chuyển khoản bổ sung
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.AutoConfirm">
            <summary>
            Tự động xác nhận sau khi tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.Type">
            <summary>
            Loại phiếu đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.VatInfoId">
            <summary>
            ID thông tin xuất hóa đơn VAT (tùy chọn)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.CreatedBy">
            <summary>
            Người tạo (sẽ được set từ controller)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.CreatedByUsername">
            <summary>
            Tên người tạo (sẽ được set từ controller)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel.Validate">
            <summary>
            Validate model
            </summary>
            <returns></returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateDriverTransferSlipModel">
            <summary>
            Model tạo phiếu chuyển tiền lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateDriverTransferSlipModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateDriverTransferSlipModel.Files">
            <summary>
            Ảnh chuyển khoản (1 file required)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.RejectDriverTransferSlipModel">
            <summary>
            Model từ chối phiếu chuyển tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.RejectDriverTransferSlipModel.SlipId">
            <summary>
            ID phiếu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.RejectDriverTransferSlipModel.Reason">
            <summary>
            Lý do từ chối
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseHistoryModel.ExpenseId">
            <summary>
            ID của chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseHistoryModel.Status">
            <summary>
            Trạng thái chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseHistoryModel.Reason">
            <summary>
            Lý do từ chối (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseHistoryModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseModel.Description">
            <summary>
            Mô tả chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseModel.Note">
            <summary>
            Ghi chú cho chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseModel.Amount">
            <summary>
            Số tiền chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseModel.ExpenseCategoryId">
            <summary>
            Danh mục chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseModel.ExpenseCategoryName">
            <summary>
            Tên danh mục chi phí (chỉ đọc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseModel.Status">
            <summary>
            Trạng thái chi phí (chỉ đọc - được set tự động)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseModel.PaymentMethod">
            <summary>
            Phương thức thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseModel.ApprovedBy">
            <summary>
            UserId của người duyệt (chỉ đọc - được lấy từ ExpenseCategory)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseModel.RejectReason">
            <summary>
            Lý do từ chối (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseModel.UserBankAccountId">
            <summary>
            ID tài khoản ngân hàng nhận tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseModel.UserBankAccountInfo">
            <summary>
            Thông tin tài khoản ngân hàng (chỉ đọc)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.FuelCardStatementModel">
            <summary>
            Model tạo/cập nhật kỳ sao kê thẻ xăng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PayStatementModel">
            <summary>
            Model thanh toán kỳ sao kê (xác nhận đã thanh toán)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.VehicleLoanModel">
            <summary>
            Model tạo/cập nhật hợp đồng vay xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.VehicleLoanModel.Trucks">
            <summary>
            Danh sách xe trong hợp đồng (tạo/sửa)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.VehicleLoanModel.InterestPeriods">
            <summary>
            Các giai đoạn lãi suất (nếu rỗng → dùng InterestRate cố định)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PayLoanInstallmentModel">
            <summary>
            Model xác nhận thanh toán kỳ trả góp
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.InitializeDebtModel">
            <summary>
            Model khởi tạo dư nợ hiện tại cho thẻ xăng dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.InitializeDebtModel.CurrentDebt">
            <summary>
            Dư nợ hiện tại (lấy từ sao kê ngân hàng)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.InitializeDebtModel.CutoffDate">
            <summary>
            Ngày bắt đầu theo dõi (các giao dịch từ ngày này sẽ được gom vào kỳ mới)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.LoanSettlementModel">
            <summary>
            Model tạo/cập nhật tất toán khoản vay
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.LoanSettlementFeeModel">
            <summary>
            Model khoản phí tất toán
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PaySettlementFeeModel">
            <summary>
            Model xác nhận thanh toán 1 khoản phí tất toán
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceListModel">
            <summary>
            Payload ghi MA TRẬN giá theo loại hàng: tuyến (hàng) × lựa chọn thuộc tính trục (cột).
            </summary>
            <remarks>
            <para>
            <b>Vì sao không nhồi vào <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceListModel"/>.</b> Bảng giá chung có hình dạng
            tuyến × khoảng trọng lượng nên <c>PriceDetailModel</c> mang <c>MinWeight</c>/<c>MaxWeight</c> và
            <b>không</b> có chỗ cho <c>GoodsCategoryId</c> / <c>OptionId</c>. Hai bảng khác hình dạng, không
            nhân bản được cho nhau. Thêm field tuỳ chọn vào DTO cũ nghĩa là mọi nơi đọc nó phải tự đoán đang
            cầm bảng nào — đúng loại nhập nhằng đã sinh ra nợ PSVC ở đường bảng giá chung.
            </para>
            <para>
            <b>Xoá là cờ tường minh, không phải phép trừ.</b> Đường bảng giá chung suy ra "dòng cần xoá" bằng
            <c>đang có trong DB</c> − <c>có trong payload</c>, tức giả định payload luôn chứa đủ mọi dòng người
            dùng nhìn thấy. Giả định đó vỡ là mất dữ liệu im lặng. Ở đây ô nào cần xoá thì phải mang
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceCellModel.Xoa"/> = <c>true</c>; ô vắng mặt là ô KHÔNG ĐỤNG TỚI. Nhờ vậy
            lưu từng phần ma trận (từng tuyến, hoặc client đang lọc) an toàn theo thiết kế. Xem
            <c>PriceMatrixRule</c>.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceListModel.GoodsCategoryId">
            <summary>
            Danh mục hàng hóa của bảng giá này. Bắt buộc &gt; 0 — <c>null</c>/0 là bảng giá CHUNG,
            thuộc đường <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceListModel"/>, không đi qua đây.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceListModel.CustomerId">
            <summary>
            Khách sở hữu bảng giá. <c>0</c> = khách mặc định — client cũ không gửi nên giữ hành vi cũ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceListModel.PriceType">
            <summary>
            Loại giá áp cho các ô trong lô này. Ô ma trận bình thường là <see cref="F:Lada.Framework.Data.Enums.PriceType.FixPrice"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceListModel.Cells">
            <summary>
            Các ô giá cần tạo / sửa / xoá mềm trong lần lưu này.
            </summary>
            <remarks>
            Rỗng = không có gì để lưu, KHÔNG phải "xoá sạch bảng giá". Muốn xoá cả bảng thì dùng endpoint
            xoá bảng giá riêng của danh mục — thao tác đó đưa danh mục về tính theo trọng lượng nên phải
            nhìn thấy rõ trên URL, không được là hệ quả phụ của một lần gửi payload rỗng.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceCellModel">
            <summary>
            Một ô của ma trận giá theo loại hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceCellModel.Id">
            <summary>
            Id ô giá trong DB. <c>0</c> = ô mới chưa lưu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceCellModel.RouteId">
            <summary>
            Tuyến — HÀNG của ma trận.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceCellModel.OptionId">
            <summary>
            Lựa chọn của thuộc tính trục (<c>GoodsAttributeOption.Id</c>) — CỘT của ma trận.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceCellModel.Value">
            <summary>
            Giá của ô. <c>0</c> hợp lệ và có nghĩa: ô đã khởi tạo nhưng chưa khai giá.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceCellModel.StepWeight">
            <summary>
            Bước trọng lượng, chỉ có nghĩa với <see cref="F:Lada.Framework.Data.Enums.PriceType.RangeStepPrice"/>.
            </summary>
            <remarks>
            Ô ma trận thường là <c>FixPrice</c> nên để 0. Với dòng bước giá, 0 là một
            <c>DivideByZeroException</c> nằm sẵn trên đường tiền — <c>PriceMatrixRule.ValidateStepWeight</c>
            chặn đúng chỗ đó, và chỉ chặn ở nhánh có phép chia.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceCellModel.Xoa">
            <summary>
            Đánh dấu xoá mềm ô này.
            </summary>
            <remarks>
            ⚠️ Xoá ô CUỐI CÙNG của một danh mục làm cả danh mục rơi khỏi nhánh bảng giá riêng về nhánh
            tính theo trọng lượng — engine chọn trục bằng <c>EXISTS(Price WHERE GoodsCategoryId = C AND
            IsDeleted = 0)</c>. Đơn vẫn ra tiền, chỉ là sai giá, không lỗi nào bay lên. Service trả cảnh
            báo trong <c>BaseResult.Message</c> để UI hỏi lại người bấm.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.InitGoodsCategoryPriceMatrixModel">
            <summary>
            Payload khởi tạo ma trận giá cho một danh mục chưa có bảng giá riêng.
            </summary>
            <remarks>
            <para>
            <b>Không phải "sao chép bảng mặc định".</b> Bảng chung là tuyến × khoảng trọng lượng, bảng riêng là
            tuyến × option trục — khác hình dạng nên không nhân bản được. Ở đây sinh đủ ô rỗng theo option của
            thuộc tính trục, cho phép nhập một giá gốc + hệ số theo từng option để đỡ nhập tay.
            </para>
            <para>
            ⚠️ Đây là thao tác <b>đổi cách tính tiền của cả danh mục</b>: ô giá đầu tiên xuất hiện là danh mục
            chuyển từ nhánh trọng lượng sang nhánh bảng giá riêng ngay lập tức, mọi đơn sau đó tra bảng mới.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.InitGoodsCategoryPriceMatrixModel.GoodsCategoryId">
            <summary>
            Danh mục hàng hóa cần khởi tạo bảng giá riêng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.InitGoodsCategoryPriceMatrixModel.CustomerId">
            <summary>
            Khách sở hữu bảng giá sẽ sinh ra. <c>0</c> = khách mặc định — client cũ không gửi nên giữ
            hành vi cũ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.InitGoodsCategoryPriceMatrixModel.BaseValue">
            <summary>
            Giá gốc dùng cho mọi ô trước khi nhân hệ số. Để 0 thì sinh ma trận rỗng (mọi ô giá 0).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.InitGoodsCategoryPriceMatrixModel.OptionFactors">
            <summary>
            Hệ số riêng theo từng option trục, nhân với <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.InitGoodsCategoryPriceMatrixModel.BaseValue"/>.
            </summary>
            <remarks>
            Option không khai hệ số thì lấy hệ số 1. Danh sách rỗng = mọi option cùng giá gốc.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.InitGoodsCategoryPriceMatrixModel.RouteIds">
            <summary>
            Chỉ khởi tạo cho các tuyến này. Rỗng = mọi tuyến đang có.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceMatrixOptionFactorModel">
            <summary>
            Hệ số giá của một option trục khi khởi tạo ma trận.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceMatrixOptionFactorModel.OptionId">
            <summary>
            Lựa chọn của thuộc tính trục.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceMatrixOptionFactorModel.Factor">
            <summary>
            Hệ số nhân với giá gốc.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.IncomeHistoryModel.IncomeId">
            <summary>
            ID của doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.IncomeHistoryModel.Status">
            <summary>
            Trạng thái doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.IncomeHistoryModel.Reason">
            <summary>
            Lý do từ chối (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.IncomeHistoryModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.IncomeModel.Description">
            <summary>
            Mô tả doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.IncomeModel.Note">
            <summary>
            Ghi chú cho doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.IncomeModel.Amount">
            <summary>
            Số tiền doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.IncomeModel.IncomeCategoryId">
            <summary>
            Danh mục doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.IncomeModel.IncomeCategoryName">
            <summary>
            Tên danh mục doanh thu (chỉ đọc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.IncomeModel.Status">
            <summary>
            Trạng thái doanh thu (chỉ đọc - được set tự động)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.IncomeModel.ApprovedBy">
            <summary>
            UserId của người duyệt (chỉ đọc - được lấy từ IncomeCategory)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.IncomeModel.RejectReason">
            <summary>
            Lý do từ chối (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceListModel.GoodsCategoryId">
            <summary>
            Loại hàng của bảng giá. <c>null</c> = bảng giá CHUNG theo khoảng trọng lượng.
            </summary>
            <remarks>
            <para>
            Trường THÊM VÀO khi tổng quát hoá bảng giá v2: cùng với <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceListModel.CustomerId"/> và
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceListModel.PriceType"/> nó tạo thành bộ ba định danh phạm vi bảng giá.
            </para>
            <para>
            ⚠️ Client cũ không gửi trường này ⇒ nhận <c>null</c> ⇒ đúng bảng giá chung, tức <b>y hệt hành
            vi trước đây</b>. Đừng đổi mặc định thành một danh mục nào đó: đường lưu suy ra "dòng cần xoá"
            bằng phép trừ trong phạm vi, nên phạm vi sai là <b>xoá mềm dữ liệu của phạm vi khác</b> — đúng
            hình dạng của nợ PSVC.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceDetailModel.MinWeight">
            <summary>
            Khối lượng nhỏ nhất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceDetailModel.MaxWeight">
            <summary>
            Khối lượng lớn nhất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceDetailModel.Value">
            <summary>
            Giá trị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceDetailModel.PriceType">
            <summary>
            Loại giá
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel">
            <summary>
            Model chi tiết đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.Id">
            <summary>
            ID đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.Code">
            <summary>
            Mã đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.Customer">
            <summary>
            Thông tin khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.FromDate">
            <summary>
            Từ ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.ToDate">
            <summary>
            Đến ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.TransferDate">
            <summary>
            Ngày chuyển tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.TotalCodAmount">
            <summary>
            Tổng tiền COD
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.TotalFeeAmount">
            <summary>
            Tổng phí trừ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.NetAmount">
            <summary>
            Số tiền thực chuyển
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.OrderCount">
            <summary>
            Số lượng đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.Status">
            <summary>
            Trạng thái
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.StatusStr">
            <summary>
            Trạng thái dạng string
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.Type">
            <summary>
            Loại phiếu đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.TypeStr">
            <summary>
            Loại phiếu đối soát dạng string
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.VatInfoId">
            <summary>
            ID thông tin xuất hóa đơn VAT
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.VatInfo">
            <summary>
            Thông tin xuất hóa đơn VAT
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.BankAccount">
            <summary>
            Thông tin tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.CreatedByUsername">
            <summary>
            Người tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.CreatedTime">
            <summary>
            Ngày tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.ApprovedByUsername">
            <summary>
            Người phê duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.TransferredByUsername">
            <summary>
            Người chuyển tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.TransferInfo">
            <summary>
            Thông tin chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.Orders">
            <summary>
            Danh sách đơn hàng trong đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.CanEdit">
            <summary>
            Có thể chỉnh sửa không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.CanConfirm">
            <summary>
            Có thể xác nhận không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.CanTransfer">
            <summary>
            Có thể chuyển tiền không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationDetailModel.CanCancel">
            <summary>
            Có thể hủy không
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountInfo">
            <summary>
            Thông tin tài khoản ngân hàng trong đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountInfo.AccountNumber">
            <summary>
            Số tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountInfo.AccountHolderName">
            <summary>
            Tên chủ tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountInfo.BankCode">
            <summary>
            Mã ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountInfo.BankName">
            <summary>
            Tên ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountInfo.BranchName">
            <summary>
            Tên chi nhánh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountInfo.BranchAddress">
            <summary>
            Địa chỉ chi nhánh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountInfo.DisplayInfo">
            <summary>
            Thông tin hiển thị đầy đủ
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationFilterModel">
            <summary>
            Model filter cho tìm kiếm đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationFilterModel.Keyword">
            <summary>
            Từ khóa tìm kiếm (mã đối soát, tên khách hàng)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationFilterModel.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationFilterModel.Status">
            <summary>
            Trạng thái đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationFilterModel.FromCreatedDate">
            <summary>
            Từ ngày tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationFilterModel.ToCreatedDate">
            <summary>
            Đến ngày tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationFilterModel.FromTransferDate">
            <summary>
            Từ ngày chuyển tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationFilterModel.ToTransferDate">
            <summary>
            Đến ngày chuyển tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationFilterModel.FromAmount">
            <summary>
            Số tiền từ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationFilterModel.ToAmount">
            <summary>
            Số tiền đến
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationFilterModel.CreatedBy">
            <summary>
            Người tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationFilterModel.ApprovedBy">
            <summary>
            Người phê duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ReconciliationFilterModel.TransferredBy">
            <summary>
            Người chuyển tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.RouteModel.Name">
            <summary>
            Tên tuyến
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.RouteModel.Description">
            <summary>
            Mô tả tuyến
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.RouteModel.DistanceMin">
            <summary>
            Khoảng cách tối thiểu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.RouteModel.DistanceMax">
            <summary>
            Khoảng cách tối đa
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.RouteModel.DisplayOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionModel.Description">
            <summary>
            Mô tả giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionModel.Note">
            <summary>
            Ghi chú cho giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionModel.Amount">
            <summary>
            Số tiền giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionModel.CashAmount">
            <summary>
            Số tiền mặt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionModel.TransferAmount">
            <summary>
            Số tiền chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionModel.TransactionType">
            <summary>
            Loại giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionModel.TransactionDirection">
            <summary>
            Hướng giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionModel.TransactionDate">
            <summary>
            Ngày giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionModel.WalletId">
            <summary>
            ID ví nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionModel.RelatedWalletId">
            <summary>
            ID ví đích (nullable)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionModel.CostCategoryId">
            <summary>
            Danh mục chi phí (nullable)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionModel.Orders">
            <summary>
            Danh sách đơn hàng liên kết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionOrderModel.OrderId">
            <summary>
            ID đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionOrderModel.CodAmount">
            <summary>
            Số tiền COD
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionOrderModel.SourceFeeAmount">
            <summary>
            Cước nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransactionOrderModel.DestFeeAmount">
            <summary>
            Cước đích
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferReconciliationModel">
            <summary>
            Model thực hiện chuyển tiền đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferReconciliationModel.ReconciliationId">
            <summary>
            ID đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferReconciliationModel.TransferMethod">
            <summary>
            Phương thức chuyển tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferReconciliationModel.Note">
            <summary>
            Ghi chú chuyển tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferReconciliationModel.AdditionalInfo">
            <summary>
            Thông tin bổ sung (JSON hoặc text)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferReconciliationModel.CreateTransaction">
            <summary>
            Có tạo giao dịch tự động không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferReconciliationModel.SendNotification">
            <summary>
            Có gửi thông báo cho khách hàng không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferReconciliationModel.TransferredBy">
            <summary>
            Người thực hiện (sẽ được set từ controller)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferReconciliationModel.TransferredByUsername">
            <summary>
            Tên người thực hiện (sẽ được set từ controller)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferReconciliationModel.Validate">
            <summary>
            Validate model
            </summary>
            <returns></returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferMethod">
            <summary>
            Phương thức chuyển tiền
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferWalletModel">
            <summary>
            Model yêu cầu chuyển tiền giữa 2 ví
            Ví nguồn sẽ được lấy tự động từ người dùng đang đăng nhập
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferWalletModel.DestinationWalletId">
            <summary>
            ID ví đích (ví nhận tiền)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferWalletModel.Amount">
            <summary>
            Số tiền cần chuyển
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferWalletModel.Note">
            <summary>
            Ghi chú cho giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferWalletModel.RequestId">
            <summary>
            Request ID để đảm bảo idempotency (tránh chuyển tiền trùng khi retry)
            Nếu không truyền, hệ thống sẽ tự tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferWalletModel.UpdatedBy">
            <summary>
            Người thực hiện giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferWalletModel.UpdatedByUserName">
            <summary>
            Username người thực hiện giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferWalletModel.ProofImage">
            <summary>
            File ảnh chứng từ giao dịch chuyển tiền (bắt buộc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.WalletDetailModel.Id">
            <summary>
            ID ví
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.WalletDetailModel.Balance">
            <summary>
            Số dư
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.WalletDetailModel.WalletStatus">
            <summary>
            Trạng thái ví
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.WalletDetailModel.UserId">
            <summary>
            Id chủ sở hữu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.WalletDetailModel.UserName">
            <summary>
            Tên đăng nhập chủ sở hữu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.WalletDetailModel.FullName">
            <summary>
            Họ và tên chủ sở hữu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.WalletDetailModel.CanAdjustBalance">
            <summary>
            Người dùng hiện tại có được phép cân ví hay không (chỉ Founder)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ApproveTransferPaymentBillModel">
            <summary>
            Model để duyệt hóa đơn thanh toán chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ApproveTransferPaymentBillModel.TransferPaymentBillId">
            <summary>
            ID hóa đơn cần duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ApproveTransferPaymentBillModel.ApprovalNote">
            <summary>
            Ghi chú khi duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ApproveTransferPaymentBillModel.TransferInfo">
            <summary>
            Thông tin chuyển khoản (nội dung chuyển khoản, mã giao dịch, v.v.)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ApproveTransferPaymentBillModel.ApprovedBy">
            <summary>
            ID người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ApproveTransferPaymentBillModel.ApprovedByUsername">
            <summary>
            Tên người duyệt
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.BankModel">
            <summary>
            Model cho CRUD operations của Bank
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.BankModel.BankCode">
            <summary>
            Mã ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.BankModel.FullName">
            <summary>
            Tên đầy đủ ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.BankModel.BrandName">
            <summary>
            Tên thương hiệu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.BankModel.DisplayOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CancelTransferPaymentBillModel">
            <summary>
            Model hủy hóa đơn thanh toán chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CancelTransferPaymentBillModel.TransferPaymentBillId">
            <summary>
            ID hóa đơn cần hủy
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CancelTransferPaymentBillModel.CancelReason">
            <summary>
            Lý do hủy hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CancelTransferPaymentBillModel.Note">
            <summary>
            Ghi chú bổ sung
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CancelTransferPaymentBillModel.CancelledBy">
            <summary>
            Người hủy (sẽ được set từ controller)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CancelTransferPaymentBillModel.CancelledByUsername">
            <summary>
            Tên người hủy (sẽ được set từ controller)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CancelTransferPaymentBillModel.CancelledTime">
            <summary>
            Thời gian hủy (sẽ được set từ controller)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CancelTransferPaymentBillModel.CreateOrderTrack">
            <summary>
            Có tạo OrderTrack không (mặc định true)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CancelTransferPaymentBillModel.SendNotification">
            <summary>
            Có gửi thông báo không (mặc định false)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CancelTransferPaymentBillModel.Validate">
            <summary>
            Validate model
            </summary>
            <returns>Danh sách lỗi validation</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateTransferPaymentBillModel">
            <summary>
            Model để tạo hóa đơn thanh toán chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateTransferPaymentBillModel.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateTransferPaymentBillModel.OrderIds">
            <summary>
            Danh sách ID đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateTransferPaymentBillModel.Files">
            <summary>
            File ảnh chứng từ chuyển khoản (bắt buộc, đúng 1 ảnh)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateTransferPaymentBillModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateTransferPaymentBillModel.TransferInfo">
            <summary>
            Nội dung chuyển khoản
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel">
            <summary>
            Model xuất Excel phiếu đối soát khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel.FileName">
            <summary>
            Tên file Excel (không bao gồm extension)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel.CustomerReconciliationSlipIds">
            <summary>
            Danh sách ID phiếu đối soát cần xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel.FromDate">
            <summary>
            Ngày bắt đầu (để filter)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel.ToDate">
            <summary>
            Ngày kết thúc (để filter)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel.CustomerId">
            <summary>
            ID khách hàng (để filter)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel.Status">
            <summary>
            Trạng thái phiếu đối soát (để filter)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel.Type">
            <summary>
            Loại phiếu đối soát (để filter)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel.IncludeOrderDetails">
            <summary>
            Có bao gồm chi tiết đơn hàng không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel.IncludeApprovalInfo">
            <summary>
            Có bao gồm thông tin duyệt/hoàn thành không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel.IncludeNotes">
            <summary>
            Có bao gồm ghi chú không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel.FolderPath">
            <summary>
            Đường dẫn thư mục lưu file (tùy chọn)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel.Validate">
            <summary>
            Validate model
            </summary>
            <returns>Danh sách lỗi validation</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateCustomerReconciliationSlipModel">
            <summary>
            Model tạo phiếu đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateCustomerReconciliationSlipModel.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateCustomerReconciliationSlipModel.OrderIds">
            <summary>
            Danh sách ID đơn hàng được chọn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateCustomerReconciliationSlipModel.InternalNote">
            <summary>
            Ghi chú nội bộ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateCustomerReconciliationSlipModel.Files">
            <summary>
            File ảnh chứng từ (bắt buộc cho phiếu âm - khách chuyển khoản cho công ty)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateCustomerReconciliationSlipModel.BankAccountNumber">
            <summary>
            Số tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateCustomerReconciliationSlipModel.BankAccountHolderName">
            <summary>
            Tên chủ tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateCustomerReconciliationSlipModel.BankCode">
            <summary>
            Mã ngân hàng (VCB, TCB, VTB, etc.)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateCustomerReconciliationSlipModel.BankName">
            <summary>
            Tên ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateCustomerReconciliationSlipModel.BankBranchName">
            <summary>
            Tên chi nhánh ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateCustomerReconciliationSlipModel.BankBranchAddress">
            <summary>
            Địa chỉ chi nhánh ngân hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.RejectCustomerReconciliationSlipModel">
            <summary>
            Model từ chối phiếu
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CompleteCustomerReconciliationSlipModel">
            <summary>
            Model hoàn thành phiếu (xác nhận thanh toán)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CompleteCustomerReconciliationSlipModel.ProofImageUrl">
            <summary>
            Ảnh chứng từ (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CompleteCustomerReconciliationSlipModel.Note">
            <summary>
            Ghi chú thêm
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersExcelExportModel">
            <summary>
            Model xuất Excel danh sách đơn hàng nợ cước của khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersExcelExportModel.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersExcelExportModel.FileName">
            <summary>
            Tên file Excel (không bao gồm extension)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersExcelExportModel.IncludeCustomerInfo">
            <summary>
            Có bao gồm thông tin khách hàng không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersExcelExportModel.IncludeAddressInfo">
            <summary>
            Có bao gồm thông tin địa chỉ không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersExcelExportModel.IncludeStatusInfo">
            <summary>
            Có bao gồm thông tin trạng thái không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersExcelExportModel.IncludeFinancialInfo">
            <summary>
            Có bao gồm thông tin tài chính không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersExcelExportModel.FolderPath">
            <summary>
            Đường dẫn thư mục lưu file (tùy chọn)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersExcelExportModel.Validate">
            <summary>
            Validate model
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersModel">
            <summary>
            Model chứa thông tin khách hàng và danh sách đơn hàng có thể tạo hóa đơn thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersModel.Customer">
            <summary>
            Thông tin khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersModel.Orders">
            <summary>
            Danh sách đơn hàng có thể tạo hóa đơn thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersModel.TotalOrders">
            <summary>
            Tổng số đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersModel.TotalAmount">
            <summary>
            Tổng tiền TransferFee
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerInfoModel">
            <summary>
            Model thông tin khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerInfoModel.Id">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerInfoModel.FullName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerInfoModel.PhoneNumber">
            <summary>
            Số điện thoại khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerInfoModel.Email">
            <summary>
            Email khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerInfoModel.Address">
            <summary>
            Địa chỉ khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerInfoModel.UserName">
            <summary>
            Username khách hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExpenseCategoryModel">
            <summary>
            Model cho việc tạo/cập nhật danh mục chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExpenseCategoryModel.Code">
            <summary>
            Tên danh mục chi phí
            </summary>
            <summary>
            Mã danh mục chi phí chuẩn hóa theo TT133
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExpenseCategoryModel.Description">
            <summary>
            Mô tả danh mục chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExpenseCategoryModel.DisplayOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExpenseCategoryModel.ParentId">
            <summary>
            ID của danh mục cha (null nếu là danh mục gốc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExpenseCategoryModel.ApprovedBy">
            <summary>
            ID người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExpenseCategoryModel.ApprovedByUserName">
            <summary>
            Tên người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExpenseCategoryModel.AccountCode">
            <summary>
            Mã tài khoản
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExportOrderModel">
            <summary>
            Model đầu vào cho việc xuất Excel thông tin đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExportOrderModel.OrderIds">
            <summary>
            Danh sách ID đơn hàng cần xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExportOrderModel.OrderCodes">
            <summary>
            Danh sách mã đơn hàng cần xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExportOrderModel.FileName">
            <summary>
            Tên file Excel (không bao gồm extension)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExportOrderModel.FolderPath">
            <summary>
            Đường dẫn thư mục lưu file (tùy chọn)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExportOrderModel.IncludePackageDetails">
            <summary>
            Có bao gồm thông tin hàng hóa chi tiết không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExportOrderModel.IncludeAddressDetails">
            <summary>
            Có bao gồm thông tin địa chỉ chi tiết không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExportOrderModel.IncludeFinanceDetails">
            <summary>
            Có bao gồm thông tin tài chính chi tiết không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExportOrderModel.IncludeTimeDetails">
            <summary>
            Có bao gồm thông tin thời gian chi tiết không
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeCategoryModel">
            <summary>
            Model cho việc tạo/cập nhật danh mục doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeCategoryModel.Name">
            <summary>
            Tên danh mục doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeCategoryModel.Description">
            <summary>
            Mô tả danh mục doanh thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeCategoryModel.DisplayOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeCategoryModel.ParentId">
            <summary>
            ID của danh mục cha (null nếu là danh mục gốc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeCategoryModel.ApprovedBy">
            <summary>
            ID người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeCategoryModel.ApprovedByUserName">
            <summary>
            Tên người duyệt
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeExpenseReportRequest">
            <summary>
            Request model cho báo cáo thu chi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeExpenseReportRequest.FromDate">
            <summary>
            Ngày bắt đầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeExpenseReportRequest.ToDate">
            <summary>
            Ngày kết thúc
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel">
            <summary>
            Model xuất Excel phiếu đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel.FileName">
            <summary>
            Tên file Excel (không bao gồm extension)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel.ReconciliationIds">
            <summary>
            Danh sách ID phiếu đối soát cần xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel.FromDate">
            <summary>
            Ngày bắt đầu (để filter)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel.ToDate">
            <summary>
            Ngày kết thúc (để filter)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel.CustomerId">
            <summary>
            ID khách hàng (để filter)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel.Status">
            <summary>
            Trạng thái phiếu đối soát (để filter)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel.IncludeOrderDetails">
            <summary>
            Có bao gồm chi tiết đơn hàng không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel.IncludeTransferInfo">
            <summary>
            Có bao gồm thông tin chuyển khoản không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel.IncludeNotes">
            <summary>
            Có bao gồm ghi chú không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel.FolderPath">
            <summary>
            Đường dẫn thư mục lưu file (tùy chọn)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel.Validate">
            <summary>
            Validate model
            </summary>
            <returns>Danh sách lỗi validation</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateTaxInvoiceModel">
            <summary>
            Model tạo hóa đơn thuế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateTaxInvoiceModel.CustomerReconciliationSlipId">
            <summary>
            ID phiếu đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateTaxInvoiceModel.VatInfoId">
            <summary>
            ID thông tin VAT
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateTaxInvoiceModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UpdateTaxInvoiceStatusModel">
            <summary>
            Model cập nhật trạng thái hóa đơn thuế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UpdateTaxInvoiceStatusModel.TaxInvoiceId">
            <summary>
            ID hóa đơn thuế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UpdateTaxInvoiceStatusModel.Status">
            <summary>
            Trạng thái mới (2=Draft, 3=Issued)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UpdateTaxInvoiceStatusModel.InvoiceNumber">
            <summary>
            Số hóa đơn (bắt buộc khi status = Draft hoặc Issued)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UpdateTaxInvoiceStatusModel.InvoiceDate">
            <summary>
            Ngày xuất hóa đơn (bắt buộc khi status = Draft hoặc Issued)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UpdateTaxInvoiceStatusModel.Files">
            <summary>
            File PDF hóa đơn (bắt buộc khi hóa đơn chưa có file; nếu đã có thì bỏ trống để giữ file cũ)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel">
            <summary>
            Model chi tiết hóa đơn thanh toán chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.Code">
            <summary>
            Mã hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.CustomerPhone">
            <summary>
            Số điện thoại khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.CustomerEmail">
            <summary>
            Email khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.CustomerAddress">
            <summary>
            Địa chỉ khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.TotalAmount">
            <summary>
            Tổng tiền TransferFee
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.TotalAmountFormatted">
            <summary>
            Tổng tiền TransferFee (formatted)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.OrderCount">
            <summary>
            Số đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.Status">
            <summary>
            Trạng thái hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.StatusName">
            <summary>
            Tên trạng thái hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.Priority">
            <summary>
            Mức độ ưu tiên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.PriorityName">
            <summary>
            Tên mức độ ưu tiên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.CompanyBankAccountNumber">
            <summary>
            Số tài khoản ngân hàng công ty/đại lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.CompanyBankAccountHolderName">
            <summary>
            Tên chủ tài khoản công ty/đại lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.CompanyBankCode">
            <summary>
            Mã ngân hàng công ty/đại lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.CompanyBankName">
            <summary>
            Tên ngân hàng công ty/đại lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.CompanyBankBranchName">
            <summary>
            Tên chi nhánh ngân hàng công ty/đại lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.CompanyBankBranchAddress">
            <summary>
            Địa chỉ chi nhánh ngân hàng công ty/đại lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.TransferInfo">
            <summary>
            Thông tin chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.ApprovedBy">
            <summary>
            Người duyệt hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.ApprovedByUsername">
            <summary>
            Tên người duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.ApprovedDate">
            <summary>
            Ngày duyệt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.TransactionId">
            <summary>
            ID giao dịch liên kết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.Orders">
            <summary>
            Danh sách đơn hàng trong hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.MediaId">
            <summary>
            ID media chứng từ chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.MediaUrl">
            <summary>
            URL hình ảnh chứng từ chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.CanEdit">
            <summary>
            Có thể chỉnh sửa không (chỉ người tạo và trạng thái Draft)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.CanCancel">
            <summary>
            Có thể hủy không (chỉ người tạo và trạng thái Draft)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillDetailModel.CanApprove">
            <summary>
            Có thể duyệt không (role Accountant và trạng thái Draft)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel">
            <summary>
            Model xuất Excel phiếu chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel.FileName">
            <summary>
            Tên file Excel (không bao gồm extension)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel.TransferPaymentBillIds">
            <summary>
            Danh sách ID phiếu chuyển khoản cần xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel.FromDate">
            <summary>
            Ngày bắt đầu (để filter)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel.ToDate">
            <summary>
            Ngày kết thúc (để filter)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel.CustomerId">
            <summary>
            ID khách hàng (để filter)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel.Status">
            <summary>
            Trạng thái phiếu chuyển khoản (để filter)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel.IncludeOrderDetails">
            <summary>
            Có bao gồm chi tiết đơn hàng không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel.IncludeApprovalInfo">
            <summary>
            Có bao gồm thông tin duyệt không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel.IncludeNotes">
            <summary>
            Có bao gồm ghi chú không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel.FolderPath">
            <summary>
            Đường dẫn thư mục lưu file (tùy chọn)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel.Validate">
            <summary>
            Validate model
            </summary>
            <returns>Danh sách lỗi validation</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UserBankAccountModel">
            <summary>
            Model cho tài khoản ngân hàng người dùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UserBankAccountModel.UserId">
            <summary>
            ID người dùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UserBankAccountModel.AccountNumber">
            <summary>
            Số tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UserBankAccountModel.AccountHolderName">
            <summary>
            Tên chủ tài khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UserBankAccountModel.BankId">
            <summary>
            ID ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UserBankAccountModel.IsDefault">
            <summary>
            Có phải tài khoản mặc định không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UserBankAccountModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.VatInvoiceModel">
            <summary>
            Model để tạo/cập nhật hóa đơn VAT (nếu cần edit thủ công)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.VatInvoiceSearchRequest">
            <summary>
            Request model cho tìm kiếm hóa đơn VAT
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.VatInvoiceSearchRequest.Keyword">
            <summary>
            Từ khóa tìm kiếm (số hóa đơn, tên người bán/mua)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.VatInvoiceSearchRequest.FromDate">
            <summary>
            Từ ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.VatInvoiceSearchRequest.ToDate">
            <summary>
            Đến ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.VatInvoiceSearchRequest.SellerTaxCode">
            <summary>
            MST người bán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.VatInvoiceSearchRequest.BuyerTaxCode">
            <summary>
            MST người mua
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.VatInvoiceSearchRequest.Status">
            <summary>
            Tình trạng hóa đơn
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.ConfirmReceiveFuelCardModel">
            <summary>
            Model cho lái xe xác nhận nhận thẻ xăng dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.ConfirmReceiveFuelCardModel.HandoverId">
            <summary>
            ID bản ghi bàn giao
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.ConfirmReceiveFuelCardModel.Notes">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.ConfirmReceiveFuelCardModel.Files">
            <summary>
            Ảnh minh chứng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.ReturnFuelCardModel">
            <summary>
            Model cho lái xe trả thẻ xăng dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.ReturnFuelCardModel.FuelCardId">
            <summary>
            ID thẻ xăng dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.ReturnFuelCardModel.Notes">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.ReturnFuelCardModel.Files">
            <summary>
            Ảnh minh chứng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardModel.ResponsibleUserId">
            <summary>
            ID người phụ trách thẻ (nullable)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionHistoryImportModel">
            <summary>
            Model import lịch sử giao dịch thẻ xăng dầu từ Excel.
            File Excel phải có cột "Tài khoản thẻ/ Số thẻ" để hệ thống ánh xạ với thẻ tương ứng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionHistoryImportModel.File">
            <summary>
            File Excel chứa lịch sử giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionHistoryImportModel.FuelCardId">
            <summary>
            ID thẻ xăng dầu (khi import từ trang chi tiết thẻ).
            Nếu có, hệ thống sẽ gán tất cả giao dịch cho thẻ này thay vì tìm từ cột trong Excel.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionHistoryImportModel.OverwriteExisting">
            <summary>
            Có ghi đè giao dịch trùng không (optional, default: false)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionHistoryImportModel.FromDate">
            <summary>
            Lọc theo ngày bắt đầu (optional)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionHistoryImportModel.ToDate">
            <summary>
            Lọc theo ngày kết thúc (optional)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionImportModel">
            <summary>
            Model import sao kê thẻ tín dụng xăng dầu từ Excel
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionImportModel.FuelCardId">
            <summary>
            ID thẻ xăng dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionImportModel.File">
            <summary>
            File Excel sao kê
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionImportModel.StatementPeriodFrom">
            <summary>
            Kỳ sao kê từ ngày (optional)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionImportModel.StatementPeriodTo">
            <summary>
            Kỳ sao kê đến ngày (optional)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionUpdateModel">
            <summary>
            Model cập nhật giao dịch thẻ tín dụng xăng dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionUpdateModel.Id">
            <summary>
            ID giao dịch (GUID)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionUpdateModel.RawAmount">
            <summary>
            Số tiền gốc (có thể âm)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionUpdateModel.TransactionType">
            <summary>
            Loại giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionUpdateModel.Location">
            <summary>
            Địa điểm giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionUpdateModel.ProcessNote">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelQuotaPaymentModel">
            <summary>
            Model tạo phiếu thanh toán tiền dầu khoán cho lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelQuotaPaymentModel.DriverId">
            <summary>
            ID lái xe được thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelQuotaPaymentModel.PaidLiters">
            <summary>
            Số lít được thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelQuotaPaymentModel.FuelUnitPrice">
            <summary>
            Đơn giá dầu tại thời điểm thanh toán (VND/lít)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelQuotaPaymentModel.PaymentDate">
            <summary>
            Ngày thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelQuotaPaymentModel.PaymentMethod">
            <summary>
            Phương thức thanh toán (Tiền mặt, Chuyển khoản...)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelQuotaPaymentModel.PaymentReference">
            <summary>
            Mã tham chiếu thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelQuotaPaymentModel.Notes">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelQuotaPaymentModel.Status">
            <summary>
            Trạng thái (Pending, Approved, Paid, Cancelled)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillApproveModel">
            <summary>
            Model yêu cầu duyệt phiếu đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillApproveModel.Id">
            <summary>
            ID phiếu đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillApproveModel.FuelCardTransactionId">
            <summary>
            ID giao dịch thẻ xăng để đối soát (bắt buộc khi phiếu đổ bằng thẻ)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillApproveModel.PreviousOdo">
            <summary>
            ODO đổ dầu gần nhất (admin có thể điều chỉnh khi duyệt)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillApproveModel.CurrentOdo">
            <summary>
            ODO hiện tại (admin có thể điều chỉnh khi duyệt)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel">
            <summary>
            Model đổ dầu - Lái xe gửi thông tin đổ dầu với hình ảnh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.TruckId">
            <summary>
            ID xe tải (tự động lấy từ xe hiện tại của lái xe)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.FuelCardId">
            <summary>
            ID thẻ xăng dầu (nullable - có thể trả tiền mặt)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.DriverId">
            <summary>
            ID lái xe thực hiện đổ dầu (nullable - mặc định là người dùng hiện tại)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.FuelCardTransactionId">
            <summary>
            ID giao dịch thẻ tín dụng cần đối soát (nullable)
            Nếu có, hệ thống sẽ tự động liên kết giao dịch với lần đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.CurrentOdo">
            <summary>
            ODO hiện tại khi đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.PreviousOdo">
            <summary>
            ODO trước đó (bắt buộc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.Amount">
            <summary>
            Số tiền đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.UnitPrice">
            <summary>
            Đơn giá dầu (VND/lít)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.PaymentMethod">
            <summary>
            Phương thức thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.StationName">
            <summary>
            Tên cây xăng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.StationAddress">
            <summary>
            Địa chỉ cây xăng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.RefillTime">
            <summary>
            Thời gian đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.Notes">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.Files">
            <summary>
            Danh sách hình ảnh (ODO trước, ODO sau, cây dầu, hóa đơn)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.MediaTypes">
            <summary>
            Loại hình ảnh tương ứng (OdoBeforePhoto, OdoAfterPhoto, FuelPumpPhoto, FuelReceiptPhoto)
            Phải tương ứng 1-1 với Files
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel.ExistingMediaIds">
            <summary>
            Danh sách ID của media hiện có cần giữ lại khi update
            Dùng để tối ưu: chỉ upload ảnh mới, giữ lại ảnh cũ
            VD: [1, 2, 0, 4] nghĩa là giữ media ID 1,2,4 và upload ảnh mới cho vị trí thứ 3
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillRejectModel">
            <summary>
            Model yêu cầu từ chối phiếu đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillRejectModel.Id">
            <summary>
            ID phiếu đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillRejectModel.RejectReason">
            <summary>
            Lý do từ chối
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel">
            <summary>
            Model cập nhật thông tin đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel.Id">
            <summary>
            ID bản ghi đổ dầu cần cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel.TruckId">
            <summary>
            ID xe tải
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel.FuelCardId">
            <summary>
            ID thẻ xăng dầu (nullable - có thể trả tiền mặt)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel.DriverId">
            <summary>
            ID lái xe thực hiện đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel.CurrentOdo">
            <summary>
            ODO hiện tại khi đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel.PreviousOdo">
            <summary>
            ODO trước đó (bắt buộc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel.Amount">
            <summary>
            Số tiền đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel.UnitPrice">
            <summary>
            Đơn giá dầu (VND/lít)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel.ActualLiters">
            <summary>
            Số lít đổ thực tế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel.StationName">
            <summary>
            Tên trạm xăng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel.StationAddress">
            <summary>
            Địa chỉ trạm xăng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel.RefillTime">
            <summary>
            Thời gian đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel.Notes">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel">
            <summary>
            Model để tạo và cập nhật ứng viên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.FullName">
            <summary>
            Họ và tên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.PhoneNumber">
            <summary>
            Số điện thoại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.YearOfBirth">
            <summary>
            Năm sinh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.Address">
            <summary>
            Địa chỉ hiện tại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.Introduction">
            <summary>
            Giới thiệu về bản thân
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.Status">
            <summary>
            Trạng thái hồ sơ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.StatusStr">
            <summary>
            Tên trạng thái (chỉ đọc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.StatusContent">
            <summary>
            Nội dung đánh dấu trạng thái
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.AppointmentTime">
            <summary>
            Thời gian hẹn phỏng vấn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.JobId">
            <summary>
            ID vị trí tuyển dụng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.Source">
            <summary>
            Nguồn ứng viên
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.SourceStr">
            <summary>
            Tên nguồn ứng viên (chỉ đọc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.RecruiterId">
            <summary>
            ID người phụ trách tuyển hồ sơ này — để trống nếu ứng viên tự nộp và chưa ai nhận.
            Là căn cứ đếm của chỉ số KPI "Số ứng viên onboard".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.RecruiterName">
            <summary>
            Tên người phụ trách tuyển (chỉ đọc, service tra theo <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.RecruiterId"/>)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.OnboardedTime">
            <summary>
            Thời điểm hồ sơ chuyển sang trạng thái nhận việc (chỉ đọc, hệ thống tự đóng dấu)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.CvFile">
            <summary>
            File CV để upload (chỉ sử dụng khi tạo/cập nhật)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.CvFileName">
            <summary>
            Tên file CV gốc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.CvFilePath">
            <summary>
            Đường dẫn lưu trữ CV trong hệ thống (chỉ đọc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.CvFileSize">
            <summary>
            Kích thước file CV (bytes) (chỉ đọc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.CvFileSizeDisplay">
            <summary>
            Kích thước file CV hiển thị (chỉ đọc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.CvFileType">
            <summary>
            Loại file CV (pdf, doc, docx, jpg, png, etc.) (chỉ đọc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.CvFileUrl">
            <summary>
            URL để truy cập CV (chỉ đọc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.CvUploadedTime">
            <summary>
            Thời gian upload CV (chỉ đọc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.CvUploadedTimeDisplay">
            <summary>
            Thời gian upload CV hiển thị (chỉ đọc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.HasCv">
            <summary>
            Có CV hay không (chỉ đọc)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel.FormatFileSize(System.Int64)">
            <summary>
            Format kích thước file để hiển thị
            </summary>
            <param name="bytes">Kích thước tính bằng bytes</param>
            <returns>Chuỗi hiển thị kích thước file</returns>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateReviewModel.RecruiterId">
            <summary>
            ID người phụ trách tuyển hồ sơ này — để trống nghĩa là chưa ai nhận.
            </summary>
            <remarks>
            Đặt ở đây (màn đánh giá hồ sơ) vì đó là chỗ nhân sự thao tác trên hồ sơ đã tồn tại;
            màn tạo mới chỉ gán được lúc tạo. Thiếu đường này thì hồ sơ ứng viên tự nộp không bao giờ
            gán được người tuyển và chỉ số hr.onboard-count mất số (plan §7.6).
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateReviewModel.RecruiterName">
            <summary>
            Tên người phụ trách tuyển (chỉ đọc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CheckInOutModel.Odo">
            <summary>
            Số ODO hiện tại của xe (bắt buộc, >= 0)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreateSalaryAdvanceModel">
            <summary>
            Model tạo phiếu tạm ứng lương
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreateRefundModel">
            <summary>
            Model hoàn cọc trách nhiệm
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.DriverEvaluationModel">
            <summary>
            Model tạo/cập nhật Bảng đánh giá lái xe
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.DriverEvaluationDetailModel">
            <summary>
            Model điểm từng tiêu chí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.EmployeeSalaryConfigModel.SalaryMode">
            <summary>Chế độ lương — bắt buộc khi tạo/cập nhật cấu hình</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.EmployeeSalaryConfigModel.LunchAllowance">
            <summary>
            % hoa hồng từ doanh số cấp dưới (TeamLeader / BranchManager). Mặc định 2%.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel.Thumbnail">
            <summary>
            Ảnh đại diện (WebP)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel.OgImage">
            <summary>
            Ảnh đại diện dạng JPEG cho Open Graph / Social Media sharing
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel.Title">
            <summary>
            Tên công việc / chức danh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel.Description">
            <summary>
            Mô tả công việc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel.ExperienceRequirements">
            <summary>
            Yêu cầu kinh nghiệm (ví dụ: 2 năm c++)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel.WorkingAddress">
            <summary>
            Địa chỉ làm việc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel.JobType">
            <summary>
            Loại hình công việc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel.MinSalary">
            <summary>
            Mức lương tối thiểu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel.MaxSalary">
            <summary>
            Mức lương tối đa
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel.Department">
            <summary>
            Phòng ban
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel.Position">
            <summary>
            Vị trí ứng tuyển
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel.StartDate">
            <summary>
            Ngày bắt đầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel.EndDate">
            <summary>
            Ngày kết thúc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel.Email">
            <summary>
            Email tiếp nhận CV
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel.JobStatus">
            <summary>
            Trạng thái tin tuyển dụng: mở / đóng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreateLeaveRequestModel">
            <summary>
            Model tạo phiếu nghỉ phép
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.LeaveApprovalModel">
            <summary>
            Model duyệt / từ chối phiếu nghỉ phép
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.LeaveTypeModel">
            <summary>
            Model cấu hình loại nghỉ phép
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.HolidayModel">
            <summary>
            Model cấu hình ngày lễ
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.LeaveBalanceAdjustModel">
            <summary>
            Model điều chỉnh quỹ phép nhân viên
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualAttendanceModel">
            <summary>
            Mô hình chấm công thủ công (admin bổ sung khi nhân viên/lái xe quên chấm vào/ra).
            Giờ vào và giờ ra tách biệt, có thể bổ sung độc lập. ODO tùy chọn.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualAttendanceModel.Id">
            <summary>
            Id bản ghi chấm công. Null = tạo mới; có giá trị = cập nhật/bổ sung.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualAttendanceModel.UserId">
            <summary>
            Id nhân viên được chấm công.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualAttendanceModel.CheckInTime">
            <summary>
            Thời gian chấm vào (FE ghép ngày + giờ). Tùy chọn khi bổ sung.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualAttendanceModel.CheckOutTime">
            <summary>
            Thời gian chấm ra (FE ghép ngày + giờ). Tùy chọn khi bổ sung.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualAttendanceModel.CheckInOdo">
            <summary>
            Số ODO khi chấm vào (tùy chọn).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualAttendanceModel.CheckOutOdo">
            <summary>
            Số ODO khi chấm ra (tùy chọn).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualCheckOutModel">
            <summary>
            Mô hình chấm ra thủ công (admin bổ sung giờ ra cho bản ghi chưa có chấm ra),
            cho phép upload ảnh ODO bù. Dùng multipart/form-data.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualCheckOutModel.AttendanceId">
            <summary>
            Id bản ghi chấm công cần bổ sung giờ ra.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualCheckOutModel.CheckOutTime">
            <summary>
            Thời gian chấm ra (FE ghép ngày + giờ, hỗ trợ ca qua đêm).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualCheckOutModel.CheckOutOdo">
            <summary>
            Số ODO khi chấm ra (tùy chọn).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualCheckOutModel.MediaFiles">
            <summary>
            Ảnh ODO bù khi chấm ra (tùy chọn, nhiều ảnh).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreatePayrollModel">
            <summary>
            Model lập phiếu lương
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreatePayrollModel.Id">
            <summary>
            Nếu có Id → UPDATE phiếu lương đã tồn tại; null → CREATE mới
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreatePayrollModel.UserIds">
            <summary>
            Danh sách User IDs cần lập phiếu (hoặc null = tất cả)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreatePayrollModel.Month">
            <summary>
            Tháng lập phiếu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreatePayrollModel.Year">
            <summary>
            Năm lập phiếu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreatePayrollModel.HolidayDays">
            <summary>
            Số ngày Lễ trong tháng (KT nhập tay)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreatePayrollModel.AttendanceBonus">
            <summary>
            Công thực tế nhập tay (override dữ liệu chấm công).
            Nếu null → tự tính từ bảng Attendance.
            </summary>
            <summary>Thưởng chuyên cần (KT nhập tay, chỉ Office)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreatePayrollModel.PerformanceBonus">
            <summary>Thưởng hiệu suất (KT nhập tay, chỉ Office)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreatePayrollModel.ManualOvertimeKips">
            <summary>
            Số kíp vượt công nhập tay (override tự tính từ chấm công).
            Nếu null → tự tính từ bảng Attendance.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreatePayrollModel.OtherDeductions">
            <summary>
            Các khoản trừ khác (KT nhập tay khi lập phiếu lương).
            Loại: Fixed (VNĐ) hoặc Percentage (% GrossIncome trước thuế)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.PayrollConfirmModel">
            <summary>
            Model NLĐ xác nhận/từ chối phiếu lương
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.SalaryOtherDeductionModel.DeductionType">
            <summary>0 = Fixed (VNĐ), 1 = Percentage (% Gross)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.SalaryOtherDeductionModel.Value">
            <summary>Nếu Fixed = số tiền; nếu Percentage = % (VD: 5.0)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudienceModel">
            <summary>Một dòng đối tượng gửi lên (plan §3.3).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudienceModel.TargetId">
            <summary>Theo <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudienceModel.Kind"/>: Permission.Id / Agency.Id / giá trị AgencyType / User.Id; bỏ trống khi Tất cả.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudienceModel.IncludeChildren">
            <summary>Chỉ có nghĩa với Phòng ban / bưu cục: gồm cả đơn vị con.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsPostModel">
            <summary>
            Thông tin một bài (tạo khi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsPostModel.Id"/> = 0, sửa khi &gt; 0). GHI ĐÈ TOÀN BỘ: giao diện gửi đủ mọi trường;
            trường ngày để <c>null</c> nghĩa là bỏ trống (bẫy "không gửi" ≡ "muốn xoá", plan §7). Riêng
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsPostModel.Audiences"/>: <c>null</c> = giữ nguyên đối tượng đang có, mảng rỗng = bỏ hết; và
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsPostModel.AudienceScope"/>: <c>null</c> = giữ nguyên phạm vi đang có.
            Có hiệu lực ngay khi lưu kể cả với bài đã đăng; nội dung khối thì chỉ đổi khi "Đăng lại" (plan §6.3).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsPostModel.AudienceScope">
            <summary>
            Chỉ nhân viên LADA / Gồm cả bưu cục nhượng quyền (plan §6.6). <c>null</c> = giữ nguyên (bài mới: Chỉ nhân viên
            LADA). Người mức đơn vị bị ép phạm vi (§5 câu 12c) thì máy chủ bỏ qua giá trị này. Gửi lại đúng phạm vi đang có
            KHÔNG tính là đổi (máy chủ so giá trị) — chỉ đổi thật mới huỷ lịch của bài đang hẹn giờ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsBlocksModel">
            <summary>Bộ khối của bản đang sửa — thay cả bộ, thứ tự theo <c>SortOrder</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsPublishModel">
            <summary>Đăng ngay / hẹn giờ / đăng lại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsPublishModel.PublishAt">
            <summary>Mốc tương lai = hẹn giờ (chỉ bài chưa đăng); bỏ trống hoặc đã qua = đăng ngay.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsPublishModel.NotifyAgain">
            <summary>"Báo lại cho mọi người" khi Đăng lại — mặc định không gửi chuông lần hai (plan §6.3).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsPublishModel.ExpectedDraftVersion">
            <summary>Dấu bản đang sửa người đăng đã xem (<c>DraftVersion</c>); khác = có người lưu sau đó → từ chối.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudiencePreviewModel">
            <summary>Ước tính người nhận cho đối tượng đang chọn (chưa cần lưu bài).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudiencePreviewModel.AudienceScope">
            <summary>Phạm vi đang chọn trên form; <c>null</c> = Chỉ nhân viên LADA (hoặc phạm vi bị ép).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Itentity.PermissionModel.Name">
            <summary>
            Tên Permission Group
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Itentity.PermissionModel.Description">
            <summary>
            Mô tả Permission Group
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Itentity.PermissionModel.IsActive">
            <summary>
            Permission có đang hoạt động không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Itentity.PermissionModel.RoleIds">
            <summary>
            Danh sách Role IDs (chỉ dùng cho việc hiển thị, không dùng cho CreateOrUpdate)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Itentity.PermissionRoleModel.RoleIds">
            <summary>
            Danh sách Role IDs mới
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentAssignModel">
            <summary>
            Model chuyển cả bộ chỉ tiêu của một chủ thể trong một kỳ sang trạng thái Assigned (§7.8) —
            chặn cứng khi tổng trọng số ≠ 100%
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentAssignModel.SubjectKind">
            <summary>Loại chủ thể</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentAssignModel.SubjectId">
            <summary>User.Id hoặc Agency.Id theo SubjectKind</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentAssignModel.PeriodYear">
            <summary>Năm của kỳ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentAssignModel.PeriodMonth">
            <summary>Tháng của kỳ (1-12)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentCopyModel">
            <summary>
            Model copy bộ chỉ tiêu của một chủ thể từ kỳ trước sang kỳ mới (trạng thái Draft) —
            bỏ qua metric đã có chỉ tiêu ở kỳ đích
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentCopyModel.SubjectKind">
            <summary>Loại chủ thể</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentCopyModel.SubjectId">
            <summary>User.Id hoặc Agency.Id theo SubjectKind</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentCopyModel.FromPeriodYear">
            <summary>Năm kỳ nguồn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentCopyModel.FromPeriodMonth">
            <summary>Tháng kỳ nguồn (1-12)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentCopyModel.ToPeriodYear">
            <summary>Năm kỳ đích</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentCopyModel.ToPeriodMonth">
            <summary>Tháng kỳ đích (1-12)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentModel">
            <summary>
            Model giao/sửa một dòng chỉ tiêu KPI (kỳ tháng)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentModel.MetricId">
            <summary>Chỉ số được giao (KpiMetric.Id)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentModel.SubjectKind">
            <summary>Loại chủ thể</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentModel.SubjectId">
            <summary>User.Id hoặc Agency.Id theo SubjectKind</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentModel.PeriodYear">
            <summary>Năm của kỳ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentModel.PeriodMonth">
            <summary>Tháng của kỳ (1-12)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentModel.TargetValue">
            <summary>Giá trị mục tiêu — phải &gt; 0</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentModel.Weight">
            <summary>Trọng số %, thuộc (0, 100]</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentModel.CapPercent">
            <summary>Trần % hoàn thành khi tính điểm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentModel.Note">
            <summary>Ghi chú</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusPolicyModel">
            <summary>
            Đầu vào tạo/sửa mẫu bậc thang thưởng KPI (§7.5, §7.14).
            </summary>
            <remarks>
            Bậc gửi trọn bộ mỗi lần lưu (bám cách <c>EmployeeSalaryConfigService</c> xử lý
            <c>SalesCommissionTier</c>): service xoá bậc cũ rồi ghi lại theo danh sách này.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusPolicyTierModel">
            <summary>Một bậc của mẫu: điểm trong [MinScore, MaxScore) ⇒ tiền</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusPolicyTierModel.MaxScore">
            <summary>Null = "trở lên" (bậc cuối)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusSettingModel">
            <summary>
            Đầu vào tạo/sửa dòng cấu hình thưởng của MỘT nhân viên trong MỘT tháng (§7.14).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusSettingModel.ScoreSubjectKind">
            <summary>Nguồn điểm: bản thân (Employee) hay bưu cục/khu vực phụ trách (Agency)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusSettingModel.ScoreSubjectId">
            <summary>Bỏ trống khi nguồn điểm là bản thân — service tự điền bằng <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusSettingModel.UserId"/></summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusSettingBulkModel">
            <summary>
            Gán hàng loạt dòng cấu hình cho một kỳ — idempotent, dùng cho màn quản trị GĐ F (§7.14).
            </summary>
            <remarks>
            Hai kiểu dùng: (a) <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusSettingBulkModel.CopyFromMonth"/>/<see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusSettingBulkModel.CopyFromYear"/> để sao chép cấu hình
            của một tháng trước sang kỳ đích; (b) <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusSettingBulkModel.Items"/> để gửi thẳng danh sách. Gửi cả hai
            thì <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusSettingBulkModel.Items"/> được ghép thêm vào kết quả sao chép (dòng cùng nhân viên thì
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusSettingBulkModel.Items"/> thắng).
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusSettingBulkModel.UserIds">
            <summary>Chỉ áp cho những nhân viên này khi sao chép; để trống là mọi dòng của kỳ nguồn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusSettingBulkModel.OverwriteExisting">
            <summary>
            Ghi đè dòng đã có của kỳ đích. Mặc định <c>false</c>: chạy lại lần hai không đụng dòng ai
            đã chỉnh tay.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusRunModel">
            <summary>Tham số bảng tính thử / sinh thưởng cho một kỳ tháng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusRunModel.UserId">
            <summary>Lọc theo một nhân viên nhận thưởng; 0 = cả kỳ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusRunModel.ScoreSubjectKind">
            <summary>
            Lọc theo <b>chủ thể nguồn điểm</b> của dòng cấu hình — 0 nghĩa là không lọc.
            </summary>
            <remarks>
            Khác <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusRunModel.UserId"/> (người NHẬN tiền): đây là chủ thể mà điểm được lấy từ đó
            (<c>KpiBonusSetting.ScoreSubjectKind</c>/<c>ScoreSubjectId</c>). Đường chốt kỳ MỘT chủ thể
            dùng nó để giới hạn lần sinh thưởng đúng vào chủ thể vừa chốt — nếu không, một trưởng bưu
            cục chốt lại chỉ tiêu của nhân viên mình sẽ khởi động việc ghi/gỡ tiền cho cả công ty.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusRunModel.ScoreSubjectId">
            <summary>Xem <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusRunModel.ScoreSubjectKind"/>; 0 = không lọc theo chủ thể nguồn điểm</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiMetricModel">
            <summary>
            Model tạo/sửa chỉ số KPI
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiMetricModel.Code">
            <summary>Mã định danh duy nhất "nhom.ten-kebab" — không đổi sau khi đã có chỉ tiêu tham chiếu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiMetricModel.Name">
            <summary>Tên hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiMetricModel.Unit">
            <summary>Đơn vị đo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiMetricModel.Direction">
            <summary>Chiều đánh giá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiMetricModel.ApplicableTo">
            <summary>Áp cho loại chủ thể nào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiMetricModel.SourceType">
            <summary>Nguồn giá trị thực</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiMetricModel.SourceCode">
            <summary>Mã provider — bắt buộc khi SourceType = Auto</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiMetricModel.IsActive">
            <summary>Còn dùng để giao chỉ tiêu mới</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodCloseModel">
            <summary>
            Yêu cầu chốt kỳ (hoặc chốt lại) cho một chủ thể — đường thủ công của §3.4.
            </summary>
            <remarks>
            Cùng một model cho cả chốt lần đầu lẫn chốt lại: người dùng không phải biết kỳ đã chốt hay
            chưa, service tự nhận ra và tự áp cửa sổ <c>Kpi.RecloseWindowDays</c> khi là lần chốt thứ hai.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodCloseModel.SubjectKind">
            <summary>Loại chủ thể được chốt</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodCloseModel.SubjectId">
            <summary>Id chủ thể — User.Id hoặc Agency.Id theo SubjectKind</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodCloseModel.PeriodYear">
            <summary>Năm của kỳ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodCloseModel.PeriodMonth">
            <summary>Tháng của kỳ (1-12)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiManualValueModel">
            <summary>
            Nhập tay giá trị thực cho một chỉ tiêu trước khi chốt kỳ (§3.4).
            </summary>
            <remarks>
            Dùng cho chỉ số <c>SourceType = Manual</c>, và cho cả ca override số của engine khi nghiệp vụ
            có căn cứ. Job chốt kỳ **không ghi đè** giá trị nhập tay.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiManualValueModel.AssignmentId">
            <summary>Chỉ tiêu được nhập giá trị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiManualValueModel.ManualValue">
            <summary>Giá trị thực nhập tay</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiManualValueModel.ManualReason">
            <summary>Lý do nhập tay — bắt buộc (§3.9c, §3.10 để lại dấu vết)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodicReviewModel">
            <summary>
            Bản đánh giá KPI định kỳ quý/năm do người quản lý ghi (§7.1).
            </summary>
            <remarks>
            Không có trường <c>AggregatedScore</c>: điểm là số hệ thống tự tính và chỉ snapshot lúc
            chuyển <c>Final</c>. Cho client gửi điểm lên là mở đường ghi đè căn cứ tăng lương bằng tay.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodicReviewModel.Id">
            <summary>0 = tạo mới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodicReviewModel.PeriodType">
            <summary>Quarter hoặc Year</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodicReviewModel.PeriodIndex">
            <summary>Quý 1-4; bỏ qua (ghi 0) khi PeriodType = Year</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodicReviewModel.Rating">
            <summary>Xếp loại — danh mục do nghiệp vụ chốt, null = chưa xếp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodicReviewModel.ReviewNote">
            <summary>Nhận xét / điều chỉnh hướng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodicReviewModel.Recommendation">
            <summary>Đề xuất: giữ nguyên / điều chỉnh chỉ tiêu / tăng lương / thăng chức...</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodicReviewFinalizeModel">
            <summary>
            Yêu cầu chốt một bản đánh giá định kỳ sang <c>Final</c> — snapshot điểm tổng hợp tại thời điểm chốt.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor">
            <summary>Người thực hiện thao tác trên hồ sơ bưu cục — controller dựng từ JWT.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileCreateModel">
            <summary>Tạo hồ sơ nháp cho một <c>Agency</c> chưa có hồ sơ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileCreateModel.DisplayName">
            <summary>Tên hiển thị; bỏ trống thì server gợi ý từ tên chi nhánh (bỏ tiền tố "LADA", "Trung tâm"…).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel">
            <summary>
            Sửa hồ sơ theo nhóm trường. Server CHỈ ghi các nhóm trong <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel.Groups"/>; trong một nhóm được ghi, mọi trường
            lấy nguyên giá trị payload (null = xoá). Trường thuộc nhóm không liệt kê bị bỏ qua — "không gửi" ≠ "muốn xoá".
            Nhóm liệt kê mà người dùng không có quyền → 403 <c>FORBIDDEN_FIELD</c>, không âm thầm bỏ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel.ExpectedVersion">
            <summary>Số phiên bản client đang giữ — lệch thì 409 <c>VERSION_CONFLICT</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel.Groups">
            <summary>Nhóm muốn ghi: Core, Geo, Contact, Pause, Content, Commerce, ServiceArea, Seo.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileSetStatusModel">
            <summary>Chuyển trạng thái công bố (Published / Paused / Closed).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileSetStatusModel.RedirectToAgencyId">
            <summary>Khi đóng: bưu cục đích (đang công bố/tạm ngưng) cho 301.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileSetStatusModel.ConfirmRedirectToIndex">
            <summary>Khi đóng không chọn đích: xác nhận 301 về trang danh sách <c>/buu-cuc</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileSetStatusModel.ExpectedVersion">
            <summary>Có gửi thì lệch là 409.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileReopenModel">
            <summary>Mở lại hồ sơ đã đóng về nháp.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyHoursUpsertModel">
            <summary>Giờ làm việc đủ 7 ngày.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyHourModel.DayOfWeek">
            <summary>0 = Chủ nhật … 6 = Thứ bảy.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyHourExceptionUpsertModel">
            <summary>Thêm/sửa (hoặc gỡ khi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyHourExceptionUpsertModel.Remove"/>) ngoại lệ giờ của một ngày.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyRoutesSetModel">
            <summary>Thay toàn bộ danh sách tuyến của bưu cục.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyStaffUpsertModel">
            <summary>Thêm (Id = 0) hoặc sửa nhân sự hiển thị.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyStaffReorderModel">
            <summary>
            Sắp lại thứ tự MỌI nhân sự hiển thị của bưu cục trong MỘT phiên bản: <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyStaffReorderModel.Ids"/> theo thứ tự mới, phải đủ đúng tập
            nhân sự hiện có (khuôn <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaReorderModel"/>). Trước đây FE đổi chỗ bằng N lần <c>Staff/Upsert</c> — N
            phiên bản rác trong lịch sử và thứ tự ghi dở khi một lần giữa chừng hỏng (review B1).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaUploadModel">
            <summary>
            Tải MỘT ảnh lên (multipart/form-data). Nội dung file quyết định loại (JPEG/PNG/WebP theo magic bytes) — tên file,
            đuôi và content-type client gửi đều bị bỏ qua; tên lưu đĩa do server sinh.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaUploadModel.AltText">
            <summary>Mô tả ảnh (alt) — bắt buộc, tối đa 200 ký tự.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaUploadModel.IsRealPhoto">
            <summary>Ảnh chụp thật tại bưu cục (không phải ảnh minh hoạ) — điều kiện công bố #5 đòi ảnh bìa thật.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaUploadModel.IsApproved">
            <summary>
            Người có role <c>AgencyProfile.Media</c> chọn ảnh lên web ngay hay chờ duyệt; bỏ trống = duyệt luôn.
            Branch.Manager (phạm vi bưu cục của mình) gửi gì cũng thành chờ duyệt.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaUploadModel.SortOrder">
            <summary>Bỏ trống = xếp cuối nhóm ảnh cùng vai.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaUpdateModel">
            <summary>Sửa thông tin một ảnh (không đổi file, không đổi trạng thái duyệt).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaDeleteModel">
            <summary>Gỡ một ảnh (xoá mềm; gỡ luôn tham chiếu ảnh Open Graph / chân dung nhân sự).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaReorderModel">
            <summary>Sắp lại thứ tự MỌI ảnh của một vai: <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaReorderModel.Ids"/> theo thứ tự mới, phải đủ đúng tập ảnh của vai đó.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaApproveModel">
            <summary>Duyệt (hoặc bỏ duyệt) một ảnh để lên trang công khai.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileChangeSlugModel">
            <summary>Đổi slug; slug cũ vào lịch sử để trang công khai 301.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileRestoreModel">
            <summary>Khôi phục nội dung của một phiên bản cũ thành phiên bản MỚI.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestCreateModel">
            <summary>
            Branch.Manager gửi đề xuất sửa MỘT nhóm trường của bưu cục mình (GĐ D, plan §3.4 cột "đề xuất"). Chỉ đọc các
            trường của <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestCreateModel.FieldGroup"/>: Geo → toạ độ + Place ID; Content → <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestCreateModel.Intro"/> + <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestCreateModel.FaqJson"/>;
            ServiceArea → <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestCreateModel.ServiceAreaNote"/>; Routes → <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestCreateModel.Routes"/> (đủ danh sách, thay toàn bộ như
            <c>Routes/Set</c>); Staff → <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestCreateModel.Staff"/> (một thao tác trên một người, như <c>Staff/Upsert|Delete</c>).
            Nhóm ghi cả khối: trường trống = đề xuất xoá.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestCreateModel.RequestNote">
            <summary>Lời giải thích cho người duyệt, tối đa 1000 ký tự.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyStaffProposalAction">
            <summary>Thao tác trên một nhân sự hiển thị trong đề xuất. Giá trị số lưu trong <c>PayloadJson</c>, không đổi.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyStaffProposalAction.Upsert">
            <summary>Thêm (<c>Id = 0</c>) hoặc sửa (<c>Id</c> của nhân sự có sẵn) — như <c>Staff/Upsert</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyStaffProposalAction.Delete">
            <summary>Gỡ nhân sự <c>Id</c> — như <c>Staff/Delete</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyStaffProposalModel">
            <summary>Một thao tác nhân sự được đề xuất.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestApproveModel">
            <summary>Duyệt một đề xuất: áp vào hồ sơ qua đúng đường ghi sẵn có, luật nội dung chạy lại lúc duyệt.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestApproveModel.ExpectedVersion">
            <summary>
            Phiên bản hồ sơ người duyệt đang nhìn khi đọc bảng so sánh (<c>CurrentVersionNo</c> của dòng hàng đợi). Lệch
            → 409: cột "hiện tại" người duyệt thấy đã cũ. Không gửi = bỏ khoá có chủ đích.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestApproveModel.ReviewNote">
            <summary>Ghi chú của người duyệt (tuỳ chọn), vào ghi chú phiên bản.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestRejectModel">
            <summary>Từ chối một đề xuất — bắt buộc lý do để Branch.Manager biết sửa gì.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyHourExceptionBulkModel">
            <summary>
            Ngoại lệ giờ cho nhiều bưu cục một lần (nghỉ lễ, đổi giờ) — GĐ D. Một ngày (<see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyHourExceptionBulkModel.DateTo"/> trống) hoặc một
            khoảng tối đa 31 ngày; mỗi bưu cục có thay đổi được một phiên bản + nhật ký; tất cả trong một transaction.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyHourExceptionBulkModel.Remove">
            <summary>Gỡ ngoại lệ các ngày trong khoảng (sửa lần áp nhầm) thay vì đặt.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyWebReportQuery">
            <summary>Tham số báo cáo bưu cục (GĐ D) — query string của <c>GET Report</c> và <c>GET Report/Export</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyWebReportQuery.Month">
            <summary>Tháng <c>yyyy-MM</c>; trống = tháng hiện tại (giờ Việt Nam).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyWebReportQuery.AgencyId">
            <summary>Một bưu cục; trống/0 = mọi bưu cục trong phạm vi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyWebReportQuery.RegionId">
            <summary>Khu vực (node Region) — lấy bưu cục con cháu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseBusinessPlanUpdateModel">
            <summary>
            Sửa CẢ bộ tham số kế hoạch kinh doanh trong một lần (<c>POST api/FranchiseBusinessPlan/update</c>): đủ năm bậc phường
            + bộ tham số chung, kèm dấu <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseBusinessPlanUpdateModel.Stamp"/> nhận ở <c>GET get</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseBusinessPlanUpdateModel.Stamp">
            <summary>Dấu nhận ở <c>GET get</c> — khác dấu hiện tại = người khác vừa sửa.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseBusinessPlanSettingModel">
            <summary>Tham số chung. Tiền: đồng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseBusinessPlanPreviewModel">
            <summary>
            Tính thử (<c>POST api/FranchiseBusinessPlan/preview</c>): số phường mỗi bậc do người dùng gõ + tham số ĐANG SỬA (chưa
            lưu). <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseBusinessPlanPreviewModel.Tiers"/> / <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseBusinessPlanPreviewModel.Setting"/> null = dùng bộ đã lưu. Không nhận Id mã truy cập nào — xem thử không
            bao giờ đọc phường của một mã.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseBusinessPlanPreviewWardModel">
            <summary>Số phường của một bậc trong ô xem thử.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadStatusModel">
            <summary>
            Đổi trạng thái một đăng ký nhượng quyền, kèm ghi chú (thay ghi chú đang hiện; ghi chú cũ còn trong lịch sử).
            Giữ nguyên trạng thái mà đổi ghi chú = ghi thêm một dòng tiến độ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadStatusModel.StatusNote">
            <summary>Tối đa 2000 ký tự; rỗng = xoá ghi chú.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadStatusModel.AppointmentAt">
            <summary>
            Lịch hẹn gặp / khảo sát (plan cổng §6.29) — BẮT BUỘC khi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadStatusModel.Status"/> là
            <see cref="F:Lada.Framework.Data.Domains.Network.FranchiseLeadStatus.Meeting"/>, trong vòng một năm quanh hôm nay; bỏ giây. Trạng thái khác: bỏ qua, lịch
            đang có giữ nguyên.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadStatusModel.AppointmentPlace">
            <summary>Địa điểm hẹn, tối đa 200 ký tự; chỉ đọc khi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadStatusModel.Status"/> là Meeting — rỗng = xoá địa điểm.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadModel">
            <summary>
            Thông tin người đăng ký do nhân viên nhập — sửa một đăng ký đã có (<c>POST update</c>). Luật kiểm ở
            <c>FranchiseLeadService</c>, cùng chuẩn với form website trừ chỗ ghi ở từng trường.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadModel.FullName">
            <summary>2–100 ký tự.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadModel.PhoneNumber">
            <summary>Chuẩn hoá về <c>0xxxxxxxxx</c>; nhận cả số bàn 11 chữ số (người gọi tổng đài).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadModel.ProvinceCode">
            <summary>Mã trong <c>filter-options.Provinces</c> (<c>Location.Code</c> hoặc <c>khac</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadModel.Area">
            <summary>Tối đa 200 ký tự; bắt buộc khi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadModel.ProvinceCode"/> là <c>khac</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadModel.NotifyWhenOpen">
            <summary>Chỉ giữ khi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadModel.ProvinceCode"/> là <c>khac</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadModel.BusinessStatus">
            <summary>Mã trong <c>filter-options.BusinessStatuses</c>; rỗng = chưa hỏi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadModel.Occupation">
            <summary>Tối đa 200 ký tự.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadModel.Channel">
            <summary>
            Một giá trị trong <c>filter-options.ManualChannels</c>. Đăng ký đến từ form website giữ kênh Website — trường
            này bị bỏ qua.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadCreateModel">
            <summary>Nhập tay một đăng ký mới (<c>POST create</c>) cho người nhắn tin hoặc gọi tổng đài.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadCreateModel.Note">
            <summary>Ghi chú ban đầu, tối đa 2000 ký tự — vào <c>StatusNote</c> và dòng lịch sử đầu tiên.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadCreateModel.PicId">
            <summary>
            Người phụ trách — chỉ người có <c>FranchiseLead.Manage</c> chọn được (rỗng/0 = chưa giao). Người chỉ có
            <c>FranchiseLead.Search</c> luôn tự phụ trách đăng ký mình nhập: giao cho ai khác là chính họ không còn thấy nó.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadTimelineModel">
            <summary>
            Hỏi các đoạn trạng thái theo thời gian của nhiều đăng ký một lúc (biểu đồ Gantt trang lịch hẹn) — tối đa
            <c>FranchiseLeadService.MaxTimelineLeads</c> id; id ngoài phạm vi người gọi bị bỏ qua, không báo lỗi.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadAssignModel">
            <summary>Giao người phụ trách một đăng ký; <c>PicId</c> rỗng hoặc 0 = bỏ giao.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadAssignManyModel">
            <summary>
            Giao cùng một người phụ trách cho nhiều đăng ký (các dòng đang chọn trên một trang danh sách) — tối đa
            <c>FranchiseLeadService.MaxAssignLeads</c> id; <c>PicId</c> rỗng hoặc 0 = bỏ giao.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePackageTierUpdateModel">
            <summary>
            Sửa tham số CẢ bộ bậc gói vùng phủ trong một lần (<c>POST api/FranchisePackageTier/update</c>) — dải phường của các
            bậc dính vào nhau nên kiểm chung. Phải gửi đủ mọi bậc đang có, không thêm / bớt bậc.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePackageTierUpdateModel.Stamp">
            <summary>Dấu nhận ở <c>GET list</c> — khác dấu hiện tại = người khác vừa sửa.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionModel">
            <summary>
            Siêu dữ liệu của một mục Cổng nhượng quyền (<c>POST create</c> / <c>POST update</c>) — không chạm khối nội dung.
            Luật kiểm ở <c>FranchisePortalSectionService</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionModel.Title">
            <summary>2–256 ký tự.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionModel.Slug">
            <summary>
            Đoạn đường dẫn của mục; bỏ trống khi tạo thì sinh từ tiêu đề. Chữ thường không dấu, số, gạch nối; không
            trùng mục khác và không trùng đoạn dành riêng của cổng (<c>vao</c>, <c>thoat</c>…).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionModel.Summary">
            <summary>Tối đa 500 ký tự.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionModel.IconKey">
            <summary>Khoá icon trong bộ icon máy chủ trả (<c>GET form-options</c>); bỏ trống = không icon.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalReorderModel">
            <summary>Thứ tự mới của TOÀN BỘ mục cổng — mỗi mục đang có đúng một lần.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionBlocksModel">
            <summary>Bộ khối đang sửa của một mục (<c>POST {id}/blocks</c>) — thay TOÀN BỘ khối hiện có theo thứ tự <c>SortOrder</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionBlocksModel.Version">
            <summary>
            Dấu <c>DraftVersion</c> của bản đang sửa mà người lưu đã mở (từ <c>GET {id}/blocks</c>) — bắt buộc. Có người
            lưu khối sau đó thì lần lưu này bị từ chối (<c>DraftChanged = true</c>) thay vì đè mất bản của họ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalPublishModel">
            <summary>Xuất bản khối của một mục (<c>POST {id}/publish</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalPublishModel.Version">
            <summary>Dấu <c>DraftVersion</c> của bản đang sửa người bấm đã thấy (từ <c>GET {id}/blocks</c>) — bắt buộc.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAccessCodeCreateModel">
            <summary>Tạo mã truy cập cho một khách (<c>POST create</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAccessCodeCreateModel.FranchiseLeadId">
            <summary>
            Đăng ký nhượng quyền của khách — BẮT BUỘC từ GĐ L (plan §6.23): người tạo phải là người phụ trách đăng ký, và đăng
            ký chưa có mã chưa thu hồi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAccessCodeCreateModel.CustomerName">
            <summary>2–256 ký tự; bỏ trống thì lấy họ tên của đăng ký nhượng quyền.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAccessCodeCreateModel.CustomerPhone">
            <summary>Chuẩn hoá về <c>0xxxxxxxxx</c>; bỏ trống thì lấy số của đăng ký nhượng quyền.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAccessCodeCreateModel.ProvinceCodes">
            <summary>Mã tỉnh (<c>Location.Code</c>) sale ghi cho mã — nhãn lọc, không gác gì trên cổng (gắn giá bằng <c>POST {id}/price-scope</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAccessCodeCreateModel.Note">
            <summary>Tối đa 1000 ký tự.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionIdsModel">
            <summary>Các mục cần mở hoặc khoá cho một mã (<c>POST {id}/unlock</c>, <c>POST {id}/lock</c>).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalPriceScopeModel">
            <summary>
            Phạm vi giá sale gắn cho một mã (<c>POST {id}/price-scope</c>): các phường/xã — gói vùng phủ tự xếp theo số phường
            (GĐ K, plan cổng §6.17). Gửi danh sách trống = gỡ phạm vi giá.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalPriceScopeModel.PackageId">
            <summary>
            ĐÃ BỎ (gói "Toàn tỉnh / Cấp 1"). Chỉ còn để trang quản trị bản cũ gửi lên thì bị TỪ CHỐI, thay vì hiểu "không
            có phường" thành gỡ sạch phạm vi giá của khách.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalPriceScopeModel.WardIds">
            <summary><c>Location.Id</c> các phường/xã 2 cấp thuộc vùng phủ — được ở nhiều tỉnh.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalRevokeModel">
            <summary>Thu hồi một mã (<c>POST {id}/revoke</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalRevokeModel.Reason">
            <summary>Tối đa 500 ký tự.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAssistantConfigModel">
            <summary>Lưu cấu hình trợ lý AI cổng (<c>POST api/FranchisePortalAssistant/config</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAssistantConfigModel.ProviderId">
            <summary>null / 0 = tắt trợ lý (không lùi về nhà cung cấp mặc định); chỉ loại Anthropic / OpenAI.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAssistantConfigModel.ProviderPin">
            <summary>
            Dấu của dòng nhà cung cấp mà người quản lý ĐANG THẤY trên form (<c>Providers[].Pin</c> của lần đọc cấu hình). Bắt
            buộc khi chọn nhà cung cấp: dòng vừa bị sửa giữa lúc mở form và lúc bấm Lưu thì máy chủ từ chối (CNQ-65).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAssistantConfigModel.Model">
            <summary>Rỗng = model mặc định; tối đa 100 ký tự, chỉ chữ, số, <c>. - _ : /</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAssistantConfigModel.Knowledge">
            <summary>Văn bản nền — HTML của trình soạn hoặc chữ thường, tối đa 20.000 ký tự.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAssistantTestModel">
            <summary>"Hỏi thử" trợ lý với ngữ cảnh của một mã (<c>POST api/FranchisePortalAssistant/ask-test</c>).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceExportModel">
            <summary>Yêu cầu xuất bảng giá nhượng quyền của sale.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceExportModel.ProvinceId">
            <summary>Tỉnh/thành phố (2 cấp) — bắt buộc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceExportModel.WardIds">
            <summary>
            Phường/xã đã tích chọn. Rỗng = xuất bảng giá cả tỉnh, không có phần tổng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceExportModel.VehicleCount">
            <summary>Ô "Số xe thuê LADA", mặc định 0.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceLineModel">
            <summary>
            Thêm/sửa tay một dòng giá của phiên bản hiện hành. Ô bắt buộc để kiểu nullable để phân biệt "bỏ trống" với số 0;
            luật kiểm giống hệt sheet <c>BangGia</c> của file upload.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceLineModel.WardId">
            <summary>Phường/xã 2 cấp — chỉ đọc khi thêm; khi sửa lấy theo đường dẫn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceLineModel.Tier">
            <summary><c>bac</c> 1–5.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceLineModel.FranchisePrice">
            <summary><c>gia_nhuong_quyen</c> — đồng, gồm VAT.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceLineModel.VolumeDeposit">
            <summary><c>coc_theo_san_luong</c> — đồng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceLineModel.ExpectedVolume">
            <summary><c>san_luong_du_kien</c> — đơn/ngày.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceLineModel.Stamp">
            <summary>Dấu của dòng lúc mở form (<c>FranchisePriceLineItem.Stamp</c>) — bắt buộc khi sửa.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceWardFilter">
            <summary>Bộ lọc danh sách phường/xã có giá, đọc từ <c>SmartTableParam.Search.PredicateObject</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceWardFilter.Keyword">
            <summary>Tìm theo tên, có dấu hay không dấu đều ra.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementGenerateModel">
            <summary>Lập / làm mới nháp phiếu tháng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementGenerateModel.Period">
            <summary>Kỳ yyyyMM; null = kỳ trước tháng hiện tại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementGenerateModel.AgencyId">
            <summary>Chỉ một bưu cục; null = mọi ví có dòng trong kỳ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementInvoiceModel">
            <summary>Đánh dấu đã lập hoá đơn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementInvoiceModel.InvoiceNoLadaToAgency">
            <summary>Số hoá đơn LADA xuất cho bưu cục.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementInvoiceModel.InvoiceNoAgencyToLada">
            <summary>Số hoá đơn bưu cục xuất cho LADA.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementNoteModel">
            <summary>Ghi chú khi phát hành / khoá.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementNoteModel.Note">
            <summary>Ghi chú.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementNoteModel.ExpectedUpdatedTime">
            <summary>Dấu <c>UpdatedTime</c> lúc mở phiếu — lệch thì từ chối.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseAdjustmentCreateModel">
            <summary>Tạo một điều chỉnh tay (thưởng / bồi thường / điều chỉnh) — chờ duyệt.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseAdjustmentCreateModel.AgencyId">
            <summary>Bưu cục nhượng quyền.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseAdjustmentCreateModel.EntryType">
            <summary>Thưởng / Bồi thường / Điều chỉnh.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseAdjustmentCreateModel.Amount">
            <summary>Số tiền có dấu (+ LADA trả bưu cục, − bưu cục trả LADA). Thưởng phải dương.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseAdjustmentCreateModel.Reason">
            <summary>Lý do — bắt buộc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseAdjustmentCreateModel.OrderId">
            <summary>Đơn liên quan (tuỳ chọn).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseAdjustmentCreateModel.ReferenceEntryId">
            <summary>Dòng gốc được điều chỉnh (tuỳ chọn).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseAdjustmentCreateModel.SettlementId">
            <summary>
            Đưa điều chỉnh "vào kỳ" của phiếu đối soát đang NHÁP của đúng bưu cục này (SPEC §3.6, tuỳ chọn). Bỏ trống thì điều
            chỉnh vào kỳ chứa ngày được duyệt.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletEnableModel">
            <summary>Bật ví cho một chi nhánh (Ví v2 plan §1.1 — bưu cục nhượng quyền hoặc chi nhánh LADA).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletEnableModel.AgencyId">
            <summary>Chi nhánh được bật ví.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletConfigModel">
            <summary>
            Sửa tham số + tài khoản của một ví (Ví v2 plan §3.8.1 "Cấu hình ví", role Config). Không có cờ bật / chặn: bật ví đi
            <c>wallets/enable</c>, chặn xuất kho theo loại chi nhánh (§6 mục 15). Tham số chỉ áp cho bưu cục nhượng quyền.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletConfigModel.MinBalance">
            <summary>Số dư tối thiểu sau rút / để được xuất kho (đồng, ≥ 0).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletConfigModel.WarningThreshold">
            <summary>Ngưỡng cảnh báo số dư thấp (đồng, ≥ 0).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletConfigModel.WithdrawMin">
            <summary>Số rút tối thiểu một lệnh (đồng, ≥ 0).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletConfigModel.WithdrawPerDay">
            <summary>Số lệnh rút một ngày (1–10).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletConfigModel.HoldAmount">
            <summary>Tạm giữ (bồi thường — trừ khỏi số rút được, đồng, ≥ 0).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletConfigModel.BankAccountNo">
            <summary>Tài khoản nhận tiền rút — đủ cả ba hoặc trống cả ba.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletConfigModel.VirtualAccountNo">
            <summary>Tài khoản ảo nạp tiền (đối chiếu sao kê).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseAdjustmentRejectModel">
            <summary>Từ chối một điều chỉnh tay.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseAdjustmentRejectModel.Reason">
            <summary>Lý do từ chối.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.CustomerOwnerAgencyModel">
            <summary>Gán / bỏ bưu cục sở hữu khách.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.CustomerOwnerAgencyModel.AgencyId">
            <summary>Bưu cục nhượng quyền; null = khách của LADA.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalCreateModel">
            <summary>
            Chủ bưu cục tạo lệnh rút (Ví v2 §3.5). KHÔNG có bưu cục / tài khoản nhận trong yêu cầu: ví = bưu cục của người gọi, tài khoản nhận
            chụp từ ví do kế toán khai (chống IDOR / đổi tài khoản nhận).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalCreateModel.Amount">
            <summary>Số tiền rút (đồng, số nguyên dương).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalCreateModel.Note">
            <summary>Ghi chú (tối đa 500 ký tự).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalTransferModel">
            <summary>Kế toán quỹ xác nhận đã chuyển tiền lệnh rút.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalTransferModel.TransferRef">
            <summary>Mã giao dịch ngân hàng (bắt buộc).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalRejectModel">
            <summary>Kế toán quỹ từ chối lệnh rút.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalRejectModel.Reason">
            <summary>Lý do (bắt buộc, ít nhất 5 ký tự).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseDepositCreateModel">
            <summary>Kế toán quỹ ghi nhận tiền bưu cục nạp vào tài khoản LADA (Ví v2 §3.5 đường 1 — nhập tay).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseDepositCreateModel.AgencyId">
            <summary>Bưu cục được cộng ví.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseDepositCreateModel.Amount">
            <summary>Số tiền (đồng, số nguyên dương).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseDepositCreateModel.ValueDate">
            <summary>Ngày tiền vào tài khoản LADA (không sau hôm nay).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseDepositCreateModel.BankRef">
            <summary>Mã giao dịch ngân hàng — bắt buộc, không trùng khoản nạp đã ghi nhận của cùng ví.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseDepositCreateModel.Content">
            <summary>Nội dung chuyển khoản.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseReturnFeeDebtSettleModel">
            <summary>Bưu cục sale báo đã tự thu cước nợ đơn hoàn của khách, ngoài ví (mota L2-4).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseReturnFeeDebtSettleModel.Note">
            <summary>Ghi chú (bắt buộc, ít nhất 5 ký tự — thu khi nào, bằng gì).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel">
            <summary>Tạo nháp một phiên bản — từ khung niêm yết hiện tại, hoặc sao chép từ bản khác.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel.Kind">
            <summary>Bảng nào.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel.VersionCode">
            <summary>Mã phiên bản; để trống = hệ thống gợi ý theo mẫu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel.Name">
            <summary>Tên; để trống = "&lt;Tên bảng&gt; &lt;mã&gt;".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel.Note">
            <summary>Ghi chú.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel.EffectiveFrom">
            <summary>Ngày bắt đầu áp dụng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel.EffectiveTo">
            <summary>Ngày ngừng áp dụng (ngày đầu tiên không còn áp); null = tới khi có bản sau thay.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel.ScopeType">
            <summary>Toàn mạng hay danh sách bưu cục.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel.AgencyIds">
            <summary>Bưu cục của phạm vi (chỉ khi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel.ScopeType"/> = danh sách).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel.GenerationMode">
            <summary>Cách sinh.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel.DefaultCoefficient">
            <summary>Hệ số chung khi sinh từ khung (bắt buộc với cách sinh theo hệ số).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel.RoundingStep">
            <summary>Bước làm tròn ô trọn gói: 1 / 100 / 1.000 đồng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel.SourceVersionId">
            <summary>Sao chép giá từ bản này (cùng bảng); null = sinh từ khung.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionUpdateModel">
            <summary>Sửa nháp: thông tin chung, phạm vi, và (tuỳ chọn) các ô.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionUpdateModel.VersionCode">
            <summary>Mã phiên bản (nullable để thiếu / rỗng đi tới câu kiểm tiếng Việt của service thay vì 400 tự động).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionUpdateModel.Name">
            <summary>Tên.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionUpdateModel.Note">
            <summary>Ghi chú.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionUpdateModel.EffectiveFrom">
            <summary>Ngày bắt đầu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionUpdateModel.EffectiveTo">
            <summary>Ngày ngừng áp dụng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionUpdateModel.ScopeType">
            <summary>Phạm vi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionUpdateModel.AgencyIds">
            <summary>Bưu cục của phạm vi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionUpdateModel.RoundingStep">
            <summary>Bước làm tròn ô trọn gói.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionUpdateModel.Cells">
            <summary>Các ô cần ghi; null = không đụng ô nào.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionUpdateModel.ExpectedUpdatedTime">
            <summary>Dấu <c>UpdatedTime</c> lúc mở bản — lệch thì từ chối (người khác vừa sửa).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceCellUpdateModel">
            <summary>Một ô sửa trên màn hình.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceCellUpdateModel.Id">
            <summary>Id ô (thuộc bản đang sửa).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceCellUpdateModel.Value">
            <summary>Giá gõ tay — dùng khi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceCellUpdateModel.Coefficient"/> null.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceCellUpdateModel.Coefficient">
            <summary>Hệ số của ô; có giá trị thì server tự tính giá = niêm yết × hệ số.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceCellUpdateModel.IsOverridden">
            <summary>Ô sửa tay (Sinh theo % không đè trừ khi xác nhận).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceGenerateModel">
            <summary>"Sinh theo %".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceGenerateModel.Coefficient">
            <summary>Hệ số chung (0,70 = 70 %).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceGenerateModel.RoundingStep">
            <summary>Bước làm tròn ô trọn gói; null = giữ bước của bản.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceGenerateModel.OverwriteOverridden">
            <summary>Đè cả ô đã sửa tay.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceGenerateModel.ExpectedUpdatedTime">
            <summary>Dấu <c>UpdatedTime</c> lúc mở bản.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceApproveModel">
            <summary>Duyệt.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceApproveModel.ExpectedUpdatedTime">
            <summary>Dấu <c>UpdatedTime</c> của bản người duyệt đang xem — lệch thì từ chối, phải tải lại xem bản mới.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceCancelModel">
            <summary>Huỷ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceCancelModel.Reason">
            <summary>Lý do — bắt buộc (service kiểm; nullable để không bị 400 tự động).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceEffectiveToModel">
            <summary>Đặt / bỏ ngày ngừng áp dụng của bản đã duyệt.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceEffectiveToModel.EffectiveTo">
            <summary>Ngày đầu tiên không còn áp; null = bỏ ngày ngừng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.SendNotificationModel">
            <summary>
            Model gửi thông báo (Admin)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.SendNotificationModel.SystemName">
            <summary>
            SystemName của NotificationCategory
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.SendNotificationModel.Title">
            <summary>
            Tiêu đề (override template nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.SendNotificationModel.Content">
            <summary>
            Nội dung (override template nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.SendNotificationModel.ImageUrl">
            <summary>
            Ảnh minh họa
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.SendNotificationModel.ActionUrl">
            <summary>
            URL điều hướng khi click
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.SendNotificationModel.ActionData">
            <summary>
            JSON data bổ sung
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.SendNotificationModel.Scope">
            <summary>
            Phạm vi: 0=All, 1=Role, 2=User, 3=UserGroup
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.SendNotificationModel.ScopeValue">
            <summary>
            Giá trị phạm vi (RoleId, UserId list...)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.SendNotificationModel.ScheduledAt">
            <summary>
            Lên lịch gửi (null = gửi ngay)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.SendNotificationModel.Priority">
            <summary>
            Độ ưu tiên (null = dùng default của category)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.NotificationCategoryModel">
            <summary>
            Model tạo/cập nhật NotificationCategory
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.UpdatePreferenceModel">
            <summary>
            Model cập nhật notification preferences
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.RegisterDeviceTokenModel">
            <summary>
            Model đăng ký device token
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.RegisterDeviceTokenModel.Platform">
            <summary>
            0=Web, 1=Android, 2=iOS
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.RegisterDeviceTokenModel.WebPushSubscription">
            <summary>
            VAPID subscription JSON (chỉ cho Web Push)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.NotificationFilter">
            <summary>
            Filter cho danh sách thông báo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.NotificationFilter.IsRead">
            <summary>
            Lọc theo trạng thái đọc: null=tất cả, true=đã đọc, false=chưa đọc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.NotificationFilter.GroupName">
            <summary>
            Lọc theo group name (order, finance, system...)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.NotificationFilter.CategorySystemName">
            <summary>
            Lọc theo category SystemName
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.OrderBusiness.OrderFailReasonModel">
            <summary>
            Model Create/Update lý do thất bại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.OrderBusiness.OrderFailReasonModel.Name">
            <summary>
            Tên/tiêu đề lý do thất bại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.OrderBusiness.OrderFailReasonModel.Description">
            <summary>
            Mô tả chi tiết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.OrderBusiness.OrderFailReasonModel.Type">
            <summary>
            Loại thất bại: 1 = Pickup, 2 = Delivery, 3 = Both
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.OrderBusiness.OrderFailReasonModel.IsMediaRequired">
            <summary>
            Có bắt buộc tải ảnh minh chứng không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.OrderBusiness.OrderFailReasonModel.MediaTitle">
            <summary>
            Tiêu đề/hướng dẫn ảnh cần tải
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.OrderBusiness.OrderFailReasonModel.SortOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.OrderBusiness.OrderFailReasonModel.IsActive">
            <summary>
            Trạng thái hoạt động
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.CollectMoneyModel">
            <summary>
            Model sử dụng để truyền thông tin thu tiền
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel">
            <summary>
            Đối tượng đại diện cho thông tin địa chỉ chi tiết của đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.Id">
            <summary>
            Id của địa chỉ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.OrderId">
            <summary>
            Id của đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.Name">
            <summary>
            Tên người liên hệ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.PhoneNumber1">
            <summary>
            Số điện thoại chính.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.PhoneNumber2">
            <summary>
            Số điện thoại phụ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.Address1">
            <summary>
            Địa chỉ chính.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.Address2">
            <summary>
            Địa chỉ phụ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.AddressType">
            <summary>
            Loại địa chỉ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.AddressTypeStr">
            <summary>
            Chuỗi mô tả loại địa chỉ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.CityId">
            <summary>
            Id của tỉnh/thành phố.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.DistrictId">
            <summary>
            Id của quận/huyện.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.WardId">
            <summary>
            Id của phường/xã.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.FullAddress">
            <summary>
            Địa chỉ đầy đủ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.Note">
            <summary>
            Ghi chú.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.Lat">
            <summary>
            Vĩ độ đã ghim. Null nghĩa là chưa có định vị — trang tra cứu dựa vào đây
            để hiện trạng thái "đã / chưa định vị".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.Long">
            <summary>
            Kinh độ đã ghim. Null nghĩa là chưa có định vị.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.CoordSource">
            <summary>
            Nguồn toạ độ: 0 = chưa có, 1 = ghim chính xác, 2 = tâm phường/xã (gần đúng).
            Do service gán qua <see cref="T:Ladaer.BackEnd.Infrastructures.Helpers.OrderCoordHelper"/>, không map từ entity.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.ScheduledTime">
            <summary>
            Thời gian hẹn lấy/giao hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailAddressModel.ScheduledTimeStr">
            <summary>
            Chuỗi hiển thị thời gian hẹn lấy/giao hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailFinModel.ReconciliationAmount">
            <summary>
            Tiền đối soát dựa trên PayFeeType
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailFinModel.PickupSubFee">
            <summary>
            Phụ phí lấy hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailFinModel.DeliverySubFee">
            <summary>
            Phụ phí giao hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailFinModel.GoodsAttributeFee">
            <summary>
            Phụ phí theo thuộc tính loại hàng (0 với đơn không chọn danh mục)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel">
            <summary>
            Đối tượng đại diện cho thông tin chung của đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.Code">
            <summary>
            Mã đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.Status">
            <summary>
            Trạng thái đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.StatusStr">
            <summary>
            Chuỗi mô tả trạng thái đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.OrderDirection">
            <summary>
            Chiều đơn hàng (đi giao / trả về).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.OrderDirectionStr">
            <summary>
            Chuỗi mô tả chiều đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.PhysicalStatus">
            <summary>
            Trạng thái vật lý của đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.PhysicalStatusStr">
            <summary>
            Chuỗi mô tả trạng thái vật lý của đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.StatusContent">
            <summary>
            Nội dung trạng thái đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.RouteName">
            <summary>
            Tên tuyến đường.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.CustomerName">
            <summary>
            Tên khách hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.CustomerUserName">
            <summary>
            Tên đăng nhập của khách hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.CustomerId">
            <summary>
            Id của khách hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.PicId">
            <summary>
            Id của người phụ trách hiện tại.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.PicUserName">
            <summary>
            Tên người phụ trách hiện tại.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.AgencyName">
            <summary>
            Tên bưu cục hiện tại.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.ExpectAgencyPickupName">
            <summary>
            Tên bưu cục lấy hàng dự kiến.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.ExpectAgencyDeliveryName">
            <summary>
            Tên bưu cục giao hàng dự kiến.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.CreatedTime">
            <summary>
            Ngày tạo.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.CreatedTimeDisplay">
            <summary>
            Chuỗi hiển thị ngày tạo.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.UpdatedTime">
            <summary>
            Ngày cập nhật.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.UpdatedTimeDisplay">
            <summary>
            Chuỗi hiển thị ngày cập nhật.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.PickupTime">
            <summary>
            Thời gian lấy hàng thành công.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.PickupTimeDisplay">
            <summary>
            Chuỗi hiển thị thời gian lấy hàng thành công.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.DeliveryTime">
            <summary>
            Thời gian giao hàng thành công.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailGeneralModel.DeliveryTimeDisplay">
            <summary>
            Chuỗi hiển thị thời gian giao hàng thành công.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailModel.GoodsCategoryId">
            <summary>
            Danh mục hàng hóa khách chọn (Category có ContentType = GoodsType)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailModel.GoodsAttributes">
            <summary>
            Thuộc tính loại hàng đã lưu trên đơn (snapshot). Rỗng với đơn cũ / đơn không phân loại.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailPackageModel.GoodsCategoryId">
            <summary>
            Loại hàng của riêng kiện này, <c>null</c> = kiện không khai loại (đơn cũ dùng loại cấp đơn).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailTrackModel">
            <summary>
            Đối tượng đại diện cho thông tin theo dõi chi tiết đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailTrackModel.TrackActionType">
            <summary>
            Loại hành động theo dõi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailTrackModel.TrackActionTypeStr">
            <summary>
            Chuỗi mô tả loại hành động theo dõi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailTrackModel.Name">
            <summary>
            Tên hành động theo dõi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailTrackModel.ActionSource">
            <summary>
            Nguồn hành động.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailTrackModel.DataBefore">
            <summary>
            Dữ liệu trước khi thay đổi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailTrackModel.DataAfter">
            <summary>
            Dữ liệu sau khi thay đổi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailTrackModel.OrderTrackType">
            <summary>
            Quy định hiển thị của đơn hàng: khách hàng, nội bộ hoặc cả 2.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailTrackModel.PicId">
            <summary>
            Id của người phụ trách.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailTrackModel.PicUserName">
            <summary>
            Tên người phụ trách.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailTrackModel.AgencyId">
            <summary>
            Id của đại lý.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailTrackModel.AgencyName">
            <summary>
            Tên bưu cục/đại lý thao tác.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailTrackModel.PhoneContact">
            <summary>
            Số điện thoại của người phụ trách.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailTrackModel.OrderId">
            <summary>
            Id của đơn hàng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailWithUnitsModel">
            <summary>
            Model chi tiết đơn hàng với thông tin đơn vị đo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailWithUnitsModel.Packages">
            <summary>
            Packages với thông tin đơn vị đo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailWithUnitsModel.UnitInfo">
            <summary>
            Thông tin về đơn vị đo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailWithUnitsModel.GoodsCategoryId">
            <summary>
            Danh mục hàng hóa khách chọn (Category có ContentType = GoodsType)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Detail.OrderDetailWithUnitsModel.GoodsAttributes">
            <summary>
            Thuộc tính loại hàng đã lưu trên đơn (snapshot). Rỗng với đơn cũ / đơn không phân loại.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderAddressModel.AddressLevelType">
            <summary>
            Phân loại địa chỉ: 2 cấp (mới, sau sáp nhập) hoặc 3 cấp (cũ)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderAddressModel.Lat">
            <summary>
            Vĩ độ điểm đã ghim. Null nghĩa là đơn chưa được định vị — khi đó hệ thống
            hiển thị tạm tâm phường/xã. Client gửi lên khi địa chỉ chọn từ sổ địa chỉ
            khách hàng đã có sẵn điểm ghim.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderAddressModel.Long">
            <summary>
            Kinh độ điểm đã ghim. Null nghĩa là đơn chưa được định vị.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel">
            <summary>
            Model xuất Excel đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel.SearchParam">
            <summary>
            Thông số tìm kiếm (giống Search nhưng không có phân trang)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel.FileName">
            <summary>
            Tên file Excel (tùy chọn)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel.IncludeHeader">
            <summary>
            Có bao gồm header không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel.FormatDates">
            <summary>
            Có format ngày tháng không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel.FolderPath">
            <summary>
            Đường dẫn thư mục lưu file (tùy chọn)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel.Validate">
            <summary>
            Validate model
            </summary>
            <returns>Danh sách lỗi validation</returns>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel.IncludeAddresses">
            <summary>
            Có bao gồm thông tin địa chỉ không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel.IncludePackages">
            <summary>
            Có bao gồm thông tin gói hàng không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel.IncludeFinancial">
            <summary>
            Có bao gồm thông tin tài chính không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel.IncludeTimeTrack">
            <summary>
            Có bao gồm thông tin thời gian không
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportTemplateType">
            <summary>
            Enum định nghĩa các loại template xuất Excel
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportTemplateType.Finance">
            <summary>
            Template cho tài chính - TransferPaymentBill
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportTemplateType.Operations">
            <summary>
            Template cho vận hành - Operations
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportTemplateType.Logistics">
            <summary>
            Template cho logistics - Pickup/Delivery
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportTemplateType.Reporting">
            <summary>
            Template cho báo cáo - Reporting
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportTemplateType.Customer">
            <summary>
            Template cho khách hàng - Customer view
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportTemplateType.Basic">
            <summary>
            Template cơ bản - Basic info
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportTemplateType.Full">
            <summary>
            Template đầy đủ - All information
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportTemplateType.Custom">
            <summary>
            Template tùy chỉnh
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel">
            <summary>
            Model chung cho việc xuất Excel đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel.TemplateType">
            <summary>
            Loại template xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel.OrderIds">
            <summary>
            Danh sách ID đơn hàng cần xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel.OrderCodes">
            <summary>
            Danh sách mã đơn hàng cần xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel.FileName">
            <summary>
            Tên file Excel (không bao gồm extension)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel.FolderPath">
            <summary>
            Đường dẫn thư mục lưu file (tùy chọn)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel.WorksheetName">
            <summary>
            Tên worksheet (tùy chọn, sẽ dùng default của template nếu không có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel.IncludePackageDetails">
            <summary>
            Có bao gồm thông tin hàng hóa chi tiết không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel.IncludeAddressDetails">
            <summary>
            Có bao gồm thông tin địa chỉ chi tiết không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel.IncludeFinanceDetails">
            <summary>
            Có bao gồm thông tin tài chính chi tiết không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel.IncludeTimeDetails">
            <summary>
            Có bao gồm thông tin thời gian chi tiết không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel.IncludeTrackingDetails">
            <summary>
            Có bao gồm thông tin tracking không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel.IncludeMediaDetails">
            <summary>
            Có bao gồm thông tin media/hình ảnh không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel.AdditionalOptions">
            <summary>
            Các tùy chọn bổ sung (JSON format)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel.Validate">
            <summary>
            Validate model
            </summary>
            <returns>Danh sách lỗi validation</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel.GetTemplateTypeName">
            <summary>
            Lấy tên template dạng string
            </summary>
            <returns>Tên template</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel">
            <summary>
            Model cho việc xuất Excel với filter nâng cao
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel.CustomerIds">
            <summary>
            Lọc theo khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel.SaleIds">
            <summary>
            Lọc theo sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel.OrderStatuses">
            <summary>
            Lọc theo trạng thái đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel.PhysicalStatuses">
            <summary>
            Lọc theo trạng thái vật lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel.CreatedFromDate">
            <summary>
            Lọc theo ngày tạo từ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel.CreatedToDate">
            <summary>
            Lọc theo ngày tạo đến
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel.PickupFromDate">
            <summary>
            Lọc theo ngày lấy hàng từ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel.PickupToDate">
            <summary>
            Lọc theo ngày lấy hàng đến
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel.DeliveryFromDate">
            <summary>
            Lọc theo ngày giao hàng từ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel.DeliveryToDate">
            <summary>
            Lọc theo ngày giao hàng đến
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel.RouteIds">
            <summary>
            Lọc theo tuyến
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel.AgencyIds">
            <summary>
            Lọc theo agency
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel.SearchKeyword">
            <summary>
            Từ khóa tìm kiếm (mã đơn, tên khách hàng, sdt)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel.Validate">
            <summary>
            Validate model với filter
            </summary>
            <returns>Danh sách lỗi validation</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel.HasAnyFilter">
            <summary>
            Kiểm tra có filter nào không
            </summary>
            <returns>True nếu có filter</returns>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderFinModel.GoodsAttributeFee">
            <summary>
            Phụ phí theo thuộc tính loại hàng. Server tự tính, client gửi lên sẽ bị ghi đè.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderFinModel.VatInfoId">
            <summary>
            ID thông tin xuất hóa đơn VAT (null nếu không xuất VAT)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderFinModel.ReconciliationAmount">
            <summary>
            Tiền đối soát dựa trên PayFeeType
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderFinModel.TransferFee">
            <summary>
            Cước chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderFinModel.TransferFeeCashierId">
            <summary>
            Người giữ tiền cước thu từ chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderFinModel.DeductCodFee">
            <summary>
            Cước chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderFinModel.DeductCodFeeCashierId">
            <summary>
            Người giữ tiền cước thu từ chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel.CustomerId">
            <summary>
            Đơn hàng của khách hàng nào
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel.SourceAddress">
            <summary>
            Địa chỉ nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel.DestAddress">
            <summary>
            Địa chỉ đích
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel.ReturnAddress">
            <summary>
            Địa chỉ trả về (nếu không dùng IsReturnSameAsSource)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel.IsReturnSameAsSource">
            <summary>
            Nếu true, địa chỉ trả về giống địa chỉ lấy hàng (tự động copy)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel.Note">
            <summary>
            Ghi chú đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel.GoodsCategoryId">
            <summary>
            Danh mục hàng hóa khách chọn (Category có ContentType = GoodsType).
            Null = không phân loại, giữ nguyên cách tính cước cũ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel.GoodsAttributes">
            <summary>
            Lựa chọn thuộc tính hàng hóa. Client chỉ gửi lựa chọn, giá luôn resolve từ DB.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel.SaleId">
            <summary>
            Đơn hàng của sale nào
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel.IsVatRequired">
            <summary>
            Có xuất hóa đơn VAT không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel.VatInfoId">
            <summary>
            ID thông tin xuất hóa đơn VAT (bắt buộc nếu IsVatRequired = true)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel.PartnerCode">
            <summary>
            Mã đối tác
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel">
            <summary>
            Model hàng hóa trong đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.Id">
            <summary>
            ID của kiện hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.Picture">
            <summary>
            Ảnh kiện hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.Code">
            <summary>
            Mã kiện hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.Name">
            <summary>
            Tên hàng hóa
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.Weight">
            <summary>
            Trọng lượng cân nặng của 1 kiện hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.Length">
            <summary>
            Chiều dài 1 kiện hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.Width">
            <summary>
            Chiều rộng 1 kiện hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.Height">
            <summary>
            Chiều cao 1 kiện hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.Quantity">
            <summary>
            Số lượng kiện
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.SubTotalWeight">
            <summary>
            Tổng trọng lượng của kiện hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.Note">
            <summary>
            Ghi chú của kiện hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.GoodsCategoryId">
            <summary>
            Loại hàng của riêng kiện này. <c>null</c> / <c>0</c> = không khai ⇒ backend điền loại mặc định.
            </summary>
            <remarks>
            Một đơn được phép nhiều loại hàng (1 xe máy + 1 kiện hàng), mỗi kiện tra bảng giá theo loại của
            chính nó. Kênh chưa khai theo kiện thì bỏ trống và <c>OrderModel.GoodsCategoryId</c> cấp đơn vẫn
            dùng được như trước.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.GoodsAttributes">
            <summary>
            Lựa chọn thuộc tính hàng hóa của riêng kiện này. Giá luôn resolve từ DB, không tin giá client gửi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.WeightUnit">
            <summary>
            Đơn vị trọng lượng (hiển thị cho client)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.DimensionUnit">
            <summary>
            Đơn vị kích thước (hiển thị cho client)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel.Validate(System.ComponentModel.DataAnnotations.ValidationContext)">
            <summary>
            Xác thực kiện hàng, hàng phải có trọng lượng cân nặng hoặc trọng lượng kích thước
            </summary>
            <param name="validationContext"></param>
            <returns></returns>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderTrackModel.OrderTrackType">
            <summary>
            Quy định hiển thị của đơn hàng: khách hàng, nội bộ hoặc cả 2
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderTrackModel.PhoneContact">
            <summary>
            Số điện thoại của người phụ trách
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressCoordModel">
             <summary>
             Thông tin cập nhật định vị (toạ độ) cho một địa chỉ đơn hàng.
            
             Tách khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel"/> vì đây là thao tác riêng: chỉ
             ghi Lat/Long, KHÔNG đụng tới tỉnh/phường nên không kéo theo việc tính lại cước
             hay đổi bưu cục dự kiến.
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressCoordModel.Id">
            <summary>
            Id của địa chỉ đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressCoordModel.Lat">
            <summary>
            Vĩ độ. Để null (cả Lat và Long) nghĩa là xoá định vị đang có.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressCoordModel.Long">
            <summary>
            Kinh độ. Để null (cả Lat và Long) nghĩa là xoá định vị đang có.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressCoordModel.Method">
            <summary>
            Cách lấy toạ độ, chỉ để ghi vào hành trình cho dễ truy vết:
            "link" (link Google), "map" (ghim trên bản đồ), "manual" (nhập tay), "clear" (xoá).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressCoordModel.UpdatedBy">
            <summary>
            Id của người cập nhật (controller gán từ token, client không gửi).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressCoordModel.UpdatedByUserName">
            <summary>
            Tên người cập nhật (controller gán từ token, client không gửi).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.ResolveMapLinkModel">
            <summary>
            Yêu cầu bóc toạ độ từ một link Google Maps rút gọn (maps.app.goo.gl).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.ResolveMapLinkModel.Url">
            <summary>
            Link người dùng dán vào. Chỉ nhận các miền của Google.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel">
            <summary>
            Đối tượng đại diện cho thông tin cập nhật địa chỉ đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.Id">
            <summary>
            Id của địa chỉ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.OrderId">
            <summary>
            Id của đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.Name">
            <summary>
            Tên người liên hệ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.PhoneNumber1">
            <summary>
            Số điện thoại chính.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.PhoneNumber2">
            <summary>
            Số điện thoại phụ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.Address1">
            <summary>
            Địa chỉ chính.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.Address2">
            <summary>
            Địa chỉ phụ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.AddressType">
            <summary>
            Loại địa chỉ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.CityId">
            <summary>
            Id của tỉnh/thành phố.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.CityName">
            <summary>
            Tên của tỉnh/thành phố.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.DistrictId">
            <summary>
            Id của quận/huyện.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.DistrictName">
            <summary>
            Tên của quận/huyện.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.WardId">
            <summary>
            Id của phường/xã.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.WardName">
            <summary>
            Tên của phường/xã.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.AddressLevelType">
            <summary>
            Phân loại địa chỉ: 2 cấp (mới, sau sáp nhập) hoặc 3 cấp (cũ)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.Note">
            <summary>
            Ghi chú.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.UpdatedBy">
            <summary>
            Id của người cập nhật.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.UpdatedByUserName">
            <summary>
            Tên người cập nhật.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.ScheduledTime">
            <summary>
            Thời gian hẹn lấy/giao hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.Lat">
            <summary>
            Vĩ độ đã ghim. Null nghĩa là chưa có định vị.
            Dialog cập nhật định vị đọc trường này để nạp toạ độ hiện tại;
            OrderAddressService.Update KHÔNG ghi trường này — định vị đi qua UpdateCoord riêng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.Long">
            <summary>
            Kinh độ đã ghim. Null nghĩa là chưa có định vị.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel.Validate(System.ComponentModel.DataAnnotations.ValidationContext)">
            <summary>
            Phương thức kiểm tra tính hợp lệ của đối tượng.
            </summary>
            <param name="validationContext">Ngữ cảnh kiểm tra tính hợp lệ.</param>
            <returns>Danh sách các kết quả kiểm tra tính hợp lệ.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel">
            <summary>
            Model để cập nhật thông tin tài chính đơn hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.Id">
            <summary>
            ID của tài chính đơn hàng (cũng chính là OrderId).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.CollectAmount">
            <summary>
            Số tiền thu hộ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.PayFeeType">
            <summary>
            Loại phí thanh toán.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.Discount">
            <summary>
            Giảm giá.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.PickupSubFee">
            <summary>
            Phí phụ thu khi lấy hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.DeliverySubFee">
            <summary>
            Phí phụ thu khi giao hàng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.Fee">
            <summary>
            Phí.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.CodFee">
            <summary>
            Phí COD.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.GoodsAttributeFee">
            <summary>
            Phụ phí theo thuộc tính loại hàng. Server tự tính lại, client gửi lên sẽ bị ghi đè.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.GoodsCategoryId">
            <summary>
            Danh mục hàng hóa của đơn (Category có ContentType = GoodsType).
            Null = không phân loại, giữ nguyên cách tính cước cũ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.GoodsAttributes">
            <summary>
            Lựa chọn thuộc tính hàng hóa sau khi sửa. Client chỉ gửi lựa chọn, giá luôn resolve từ DB.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.TotalFee">
            <summary>
            Tổng phí.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.SourceFee">
            <summary>
            Phí nguồn.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.DestFee">
            <summary>
            Phí đích.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.UpdatedBy">
            <summary>
            ID của người cập nhật.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel.UpdatedByUserName">
            <summary>
            Tên người cập nhật.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderPackageModel">
            <summary>
            Model cập nhật các kiện hàng trong đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderPackageModel.OrderId">
            <summary>
            Mã đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderPackageModel.Packages">
            <summary>
            Danh sách kiện hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderPackageModel.UpdatedBy">
            <summary>
            ID của người cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderPackageModel.UpdatedByUserName">
            <summary>
            Tên đăng nhập của người cập nhật
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.UpdateOrderPackageWithUnitsModel">
            <summary>
            Model cập nhật kiện hàng với thông tin đơn vị đo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.UpdateOrderPackageWithUnitsModel.OrderId">
            <summary>
            ID của đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.UpdateOrderPackageWithUnitsModel.Packages">
            <summary>
            Danh sách kiện hàng với thông tin đơn vị đo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.UpdateOrderPackageWithUnitsModel.UnitInfo">
            <summary>
            Thông tin tổng hợp về đơn vị đo được sử dụng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.UnitInformation">
            <summary>
            Thông tin về đơn vị đo được sử dụng trong hệ thống
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.UnitInformation.WeightUnit">
            <summary>
            Đơn vị trọng lượng hiển thị cho client
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.UnitInformation.DimensionUnit">
            <summary>
            Đơn vị kích thước hiển thị cho client
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.UnitInformation.DatabaseWeightUnit">
            <summary>
            Đơn vị trọng lượng lưu trong database
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.UnitInformation.DatabaseDimensionUnit">
            <summary>
            Đơn vị kích thước lưu trong database
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.UnitInformation.WeightConversionFactor">
            <summary>
            Hệ số chuyển đổi trọng lượng (client -> database)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.UnitInformation.DimensionConversionFactor">
            <summary>
            Hệ số chuyển đổi kích thước (client -> database)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Updates.UpdateStatusModel.UpdatedByAgencyId">
            <summary>
            Cập nhật bởi chi nhánh nào
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseContactModel">
            <summary>
            Model tạo/cập nhật liên hệ mặt bằng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseFinancialModel">
            <summary>
            Model tạo/cập nhật thông tin tài chính mặt bằng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseModel">
            <summary>
            Model tạo/cập nhật mặt bằng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseModel.Contacts">
            <summary>
            Danh sách liên hệ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseModel.Scores">
            <summary>
            Danh sách điểm chấm theo tiêu chí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseModel.Financial">
            <summary>
            Thông tin tài chính (optional)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseModel.NewMediaFiles">
            <summary>
            Danh sách file ảnh upload mới
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseModel.NewMediaTypes">
            <summary>
            Loại media tương ứng với từng file (FrontageImage, InsideImage, StreetImage...)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseModel.DeleteMediaIds">
            <summary>
            Danh sách PremiseMedia.Id cần xóa (khi chỉnh sửa)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseStatusModel">
            <summary>
            Model cập nhật trạng thái mặt bằng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseScoreModel">
            <summary>
            Model tạo/cập nhật điểm chấm của mặt bằng theo tiêu chí
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseScoringCriteriaModel">
            <summary>
            Model tạo/cập nhật tiêu chí chấm điểm (Admin)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseScoringCriteriaModel.Options">
            <summary>
            Danh sách options kèm điểm
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Premises.PremiseScoringOptionModel">
            <summary>
            Model tạo/cập nhật option cho tiêu chí
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Promotions.PromotionCodeModel">
            <summary>
            Model tạo/cập nhật mã khuyến mãi
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Promotions.GenerateCodesModel">
            <summary>
            Model sinh mã hàng loạt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Promotions.GenerateCodesModel.Prefix">
            <summary>
            Tiền tố mã (VD: LADA)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Promotions.GenerateCodesModel.Quantity">
            <summary>
            Số lượng mã cần sinh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Promotions.GenerateCodesModel.CodeLength">
            <summary>
            Số ký tự phần random
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Promotions.GenerateCodesModel.UsageLimitPerCode">
            <summary>
            Số lượt sử dụng tối đa mỗi mã
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Promotions.PromotionProgramModel">
            <summary>
            Model tạo/cập nhật chương trình khuyến mãi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Promotions.PromotionProgramModel.Conditions">
            <summary>
            Danh sách điều kiện áp dụng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Promotions.PromotionConditionModel">
            <summary>
            Model điều kiện áp dụng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Reports.BankTransferSummaryBySalePrepareModel">
            <summary>
            Model chuẩn bị cho màn hình thống kê chuyển khoản theo sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Reports.BankTransferSummaryBySalePrepareModel.StatusOptions">
            <summary>
            Danh sách trạng thái đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Reports.BankTransferSummaryBySalePrepareModel.PhysicalStatusOptions">
            <summary>
            Danh sách trạng thái vật lý đơn hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitDataState">
             <summary>
             Vì sao bảng lượt bot đang hiện con số nó đang hiện.
            
             <para>
             <b>Ba cách ra số 0, và chúng đòi ba phản ứng khác nhau</b> — cùng bài học với tab hiệu suất
             (<see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceDataState"/>), nhưng ở đây ba cách ấy khác hẳn về nội dung:
             </para>
             <list type="number">
             <item>website <b>chưa deploy bản có middleware đếm</b>, hoặc công tắc đang tắt — không có gì
             đang đếm cả, và con số 0 không nói gì về bot;</item>
             <item>đã đếm, nhưng <b>chưa bot nào ghé</b> trong khoảng đang xem — 0 là một phép đo thật;</item>
             <item>đã đếm, có bot ghé, nhưng <b>đường dẫn cụ thể</b> đang xem thì không ai ghé — cũng là
             một phép đo thật, ở phạm vi hẹp hơn.</item>
             </list>
             <para>
             Phân biệt (1) với (2) không nhìn vào bảng là biết được, vì cả hai đều cho bảng rỗng. Tín hiệu
             duy nhất tách được chúng là <b>công tắc</b> cộng với <b>mốc ghi gần nhất</b>: website có đếm
             thì dù 0 lượt vẫn để lại dòng của những ngày trước đó.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitDataState.ChuaGhiLanNao">
            <summary>
            Bảng chưa có dòng nào bao giờ. Việc cần làm: kiểm tra website đã deploy bản có middleware
            đếm chưa, và khoá <c>Search.BotVisit.Enabled</c> có đang bật không.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitDataState.DaGhi">
            <summary>Đã ghi và khoảng đang xem có số. Trạng thái bình thường.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitDataState.KhoangNayChuaCoSo">
            <summary>
            Đã từng ghi nhưng riêng khoảng ngày đang xem không có dòng nào — không bot nào ghé trong
            khoảng ấy, hoặc dữ liệu đã bị job dọn 90 ngày xoá.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitDataState.DangTat">
            <summary>
            Công tắc <c>Search.BotVisit.Enabled</c> đang <b>tắt</b>. Số cũ vẫn còn đó nhưng không có
            gì mới được ghi thêm — một cảnh báo, không phải một con số.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel">
            <summary>Các con số tổng hợp của tab lượt bot.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.Days">
            <summary>Độ dài khoảng đang xem, tính bằng ngày.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.TuNgay">
            <summary>Ngày đầu khoảng đang xem.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.DenNgay">
            <summary>Ngày cuối khoảng đang xem.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.NgayCoSoSomNhat">
            <summary>Ngày sớm nhất bảng còn giữ — cho biết job dọn đã cắt tới đâu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.NgayCoSoMoiNhat">
            <summary>Ngày gần nhất bảng có số.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.SoNgayTre">
            <summary>Số ngày từ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.NgayCoSoMoiNhat"/> tới hôm nay.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.DangBat">
            <summary>Công tắc <c>Search.BotVisit.Enabled</c> đang bật hay tắt.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.SoNgayGiuDuLieu">
            <summary>Số ngày dữ liệu được giữ trước khi job dọn xoá — để màn hình nói ra con số đó.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.TrangThai">
            <summary>Xem <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitDataState"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.GiaiThich">
            <summary>Câu giải thích đọc được, hiện thẳng lên màn hình. Rỗng khi mọi thứ bình thường.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.SoNgayCoSo">
            <summary>Số ngày thật sự có dòng trong khoảng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.Hits">
            <summary>Tổng lượt của mọi bot trong khoảng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.HitsOk">
            <summary>Tổng lượt trả mã dưới 400.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.HitsError">
            <summary>Tổng lượt trả mã từ 400 trở lên.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.SoBot">
            <summary>Số bot khác nhau đã ghé trong khoảng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.SoDuongDan">
            <summary>Số đường dẫn khác nhau có bot ghé trong khoảng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.CoDongGopTran">
            <summary>
            Có dòng nào rơi vào rổ gộp "(khác)" không — nghĩa là bộ đếm đã chạm trần số khoá và phần
            chi tiết của những lượt đó đã mất. Màn hình phải nói ra thay vì để nó trông như một trang
            có thật.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.TheoBot">
            <summary>Tổng lượt theo từng bot, xếp giảm dần.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitSummaryModel.TheoNgay">
            <summary>Tổng lượt theo từng ngày, xếp theo ngày tăng dần — để vẽ đường xu hướng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitBotItem">
            <summary>Một bot trong bảng tổng hợp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitBotItem.SoDuongDan">
            <summary>Số đường dẫn khác nhau bot này đã ghé.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitBotItem.LanCuoi">
            <summary>Mốc lượt gần nhất của bot này trong khoảng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitDayItem">
            <summary>Một ngày trong đường xu hướng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitPathItem">
            <summary>Một dòng của bảng xếp hạng đường dẫn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitPathItem.Path">
            <summary>Đường dẫn đã chuẩn hoá. Giá trị "(khác)" là rổ gộp khi bộ đếm chạm trần.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitPathItem.LastStatusCode">
            <summary>Mã trạng thái của lượt gần nhất — cho biết đường dẫn này hiện đang trả về gì.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitPathItem.LanCuoi">
            <summary>Mốc lượt gần nhất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitPathItem.SoBot">
            <summary>Số bot khác nhau đã ghé đường dẫn này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitPathItem.CoTrongTonKho">
             <summary>
             Đường dẫn này có trong hàng tồn kho URL không.
            
             <para>
             <b>Phép so là so giữa hai dạng ĐÃ chuẩn hoá</b>, vì hai cột vốn khác dạng:
             <c>SearchUrl.Path</c> ghi bằng <c>Uri.AbsolutePath</c> nên giữ chữ hoa và giữ mã hoá phần
             trăm, còn <c>BotVisitDaily.Path</c> đã hạ chữ thường và bỏ <c>/</c> cuối. So thẳng hai cột
             là cách chắc chắn ra kết quả sai — bài học đã cắn ở giai đoạn E và lặp lại ở giai đoạn F.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitPathItem.InSitemap">
            <summary>Còn trong sitemap không. <c>null</c> khi hàng tồn kho không có đường dẫn này.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleLabels">
             <summary>
             Nhãn tiếng Việt cho các mã của miền đồng bộ công cụ tìm kiếm.
            
             <para>
             <b>Vì sao nhãn nằm ở tầng hiển thị chứ không nằm trong DB.</b> Mã lưu xuống (<c>PASS</c>,
             <c>SearchUrlGroup.Product</c>) là thứ ổn định để đếm và để lọc; câu chữ hiện trên màn hình thì
             đổi theo cách người vận hành quen gọi. Tách hai thứ ra nghĩa là sửa chữ không cần migration,
             còn con số thống kê không bao giờ đổi nghĩa vì ai đó sửa một từ.
             </para>
            
             <para>
             <b>Cố ý không đọc <c>[Description]</c> của enum.</b> Mô tả trên enum là nhãn dùng chung cho cả
             hệ thống; nhãn ở đây là ngôn ngữ của người làm SEO — "Chưa khớp nội dung" nói rõ việc phải làm,
             còn "Không rõ" thì không. Đổi <c>[Description]</c> để sửa một chữ trên dashboard sẽ kéo theo
             mọi màn hình khác đang dùng cùng enum.
             </para>
            
             <para>
             Đặt ở đây, cạnh DTO, vì cả ba nơi đều cần đúng một bảng chữ này: dashboard, widget trang chủ
             và kết quả một lượt "kiểm ngay".
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleLabels.GroupName(Lada.Framework.Data.Enums.SearchUrlGroup)">
            <summary>Nhãn tiếng Việt của một nhóm URL.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleLabels.VerdictLabel(System.String)">
             <summary>
             Nhãn tiếng Việt của một <c>Verdict</c> do Google trả về.
            
             <para>
             Mã lạ được trả <b>nguyên văn</b> thay vì quy về "không rõ": Google thêm giá trị mới mà
             không báo trước, và một mã lạ hiện ra trên màn hình là đủ để người vận hành tra cứu, còn
             chữ "không rõ" thì xoá sạch thông tin đó.
             </para>
             </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem">
             <summary>
             Một dòng của bảng chính: URL trong hàng tồn kho kèm trạng thái index gần nhất của một công cụ
             tìm kiếm.
            
             <para>
             <b>Một dòng là phép nối hai bảng, không phải một thực thể.</b> <c>SearchUrl</c> trung lập với
             công cụ tìm kiếm còn <c>SearchIndexStatus</c> thì theo từng công cụ, nên không có entity nào
             ánh xạ thẳng ra được dòng này — cũng là lý do nó không đi qua AutoMapper (xem
             <c>SearchConsoleDashboardService.SearchAsync</c>).
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.Id">
            <summary>Khoá của <c>SearchUrl</c> — dùng để mở chi tiết và để bấm "kiểm ngay".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.Url">
            <summary>URL tuyệt đối đúng như trong sitemap.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.Path">
            <summary>Phần đường dẫn sau tên miền — cột hẹp để đọc nhanh trên bảng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.Group">
            <summary>Nhóm nguồn sinh ra URL.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.GroupName">
             <summary>
             Nhãn tiếng Việt của <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.Group"/>.
            
             <para>
             Tự suy từ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.Group"/> khi chỗ tạo dòng chưa gán, nên một dòng dựng tay ở nơi khác
             (kết quả "kiểm ngay", widget trang chủ) không bao giờ trả về nhãn rỗng. Vẫn để gán được để
             chỗ gọi ghi đè khi cần.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.EntityName">
            <summary>Tên thực thể theo cách gọi của <c>UrlRecord</c> — đường lần về bản ghi nội dung.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.EntityId">
            <summary>Khoá thực thể đứng sau URL, nếu khớp được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.SitemapLastmod">
            <summary>Mốc <c>lastmod</c> đọc từ chính sitemap — thứ website đã báo cho Google.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.InSitemap">
            <summary>URL có nằm trong sitemap ở lượt quét gần nhất hay không.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.Verdict">
            <summary>
            Kết luận tổng của lượt kiểm gần nhất (<c>PASS</c>, <c>NEUTRAL</c>, <c>FAIL</c>...).
            Đây là <b>mã ổn định</b>, dùng được để đếm và để lọc. NULL nghĩa là chưa từng kiểm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.CoverageState">
             <summary>
             Câu Google hiện ngay trên giao diện Search Console.
            
             <para>
             <b>Chỉ để hiển thị và để lọc, tuyệt đối không dùng để nhóm hay đếm.</b> Google trả câu này
             theo ngôn ngữ của property nên nó đổi chữ khi đổi ngôn ngữ — mọi con số đếm theo nó sẽ
             vỡ vào đúng ngày đó mà không ai biết. Đếm thì đếm theo <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.Verdict"/>.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.IndexingState">
            <summary>Trạng thái cho phép index: <c>INDEXING_ALLOWED</c>, <c>BLOCKED_BY_META_TAG</c>...</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.RobotsTxtState">
            <summary>Trạng thái theo <c>robots.txt</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.PageFetchState">
            <summary>Kết quả lượt Google tải trang: <c>SUCCESSFUL</c>, <c>SERVER_ERROR</c>, <c>SOFT_404</c>...</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.LastCrawlTime">
            <summary>Lần Google thu thập trang gần nhất. NULL nghĩa là Google chưa từng thu thập.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.CheckedAt">
            <summary>Thời điểm <b>mình</b> hỏi Google — khác hẳn <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.LastCrawlTime"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.GoogleCanonical">
            <summary>URL chuẩn tắc theo Google.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.UserCanonical">
            <summary>URL chuẩn tắc do chính trang khai.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.CanonicalMatched">
            <summary>
            Hai URL chuẩn tắc có khớp nhau không. NULL khi thiếu một trong hai — "chưa biết" phải khác
            hẳn "lệch", vì chỉ cái sau mới là lỗi SEO cần sửa.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.InSitemapPerEngine">
            <summary>
            Google có thấy URL này trong sitemap không — theo lời Google. Lệch với
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.InSitemap"/> thường nghĩa là Google đang đọc một bản sitemap cũ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.ChangedNotRecrawled">
            <summary>
            Trang vừa sửa mà Google chưa đọc lại — câu hỏi có giá trị nhất của cả màn hình, nên nó
            cũng là khoá sắp xếp mặc định của bảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.Checked">
            <summary>Đã từng hỏi Google về URL này hay chưa.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.Clicks">
             <summary>
             Số lượt nhấp từ kết quả tìm kiếm.
            
             <para>
             <b>Luôn NULL cho tới khi có phần đọc Search Analytics.</b> NULL và 0 là hai điều khác nhau:
             0 nghĩa là đã đo và không ai nhấp, NULL nghĩa là chưa đo. Giao diện phải hiện "chưa có dữ
             liệu" chứ không được hiện số 0.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.Impressions">
            <summary>Số lượt hiển thị trong kết quả tìm kiếm. Luôn NULL — xem <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.Clicks"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.HasRedirectRule">
            <summary>
            Đường dẫn của URL này có một luật trong bảng <c>UrlRedirect</c> đang bật hay không.
            </summary>
            <remarks>
            <b>Dữ liệu của chính mình nên luôn biết được</b> — vì thế là <c>bool</c> chứ không phải
            <c>bool?</c>, khác hẳn <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.RedirectPerEngine"/> ngay dưới. Nó là một nửa của phép đối
            chiếu mà kế hoạch §3.4 đòi: Google bảo một URL có lệnh chuyển hướng thì phải xem có đúng
            mình cố ý làm thế hay không.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.RedirectPerEngine">
            <summary>
            Công cụ tìm kiếm có nói URL này đang chuyển hướng hay không.
            <c>null</c> = <b>chưa hỏi bao giờ</b>, không phải "không chuyển hướng".
            </summary>
            <remarks>
            <b>Đây là một phép dò theo chuỗi, không phải một mã ổn định</b> — và phải đọc nó với đúng
            mức tin cậy đó. <c>urlInspection</c> của Google không có trường riêng nào cho "trang có lệnh
            chuyển hướng"; điều đó chỉ xuất hiện trong <c>CoverageState</c>, là <b>câu tiếng Việt hiển
            thị trên giao diện Search Console</b> (đo thật 2026-09-15: "Đã được gửi và lập chỉ mục",
            "Lỗi máy chủ (5xx)"…). Nên ở đây phải dò theo cách diễn đạt, và dò cả tiếng Việt lẫn tiếng
            Anh vì chuỗi đổi theo ngôn ngữ của property.
            <para>
            <b>Chưa từng khớp một dòng thật nào.</b> Việc 0 của GĐ D đếm trên 148 URL của DB dev: <b>0
            URL</b> có <c>CoverageState</c> chứa "chuyển hướng" hay "redirect". Điều đó đúng như kỳ vọng
            — hàng tồn kho dựng từ sitemap, mà URL trong sitemap thì lẽ ra không được chuyển hướng — nên
            cờ này là một <b>hàng rào canh</b> cho ngày điều đó sai, chứ không phải một số đo đang có
            người đọc.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.RedirectWithoutRule">
            <summary>
            Google nói URL này chuyển hướng, mà <b>mình không có luật nào</b> cho nó —
            <i>chuyển hướng ở đâu ra?</i> <c>null</c> khi chưa hỏi Google về URL này.
            </summary>
            <remarks>
            Nguồn khả dĩ khi cờ này bật: một chỗ <c>RedirectPermanent</c> trong controller
            (<c>PricingController</c>, <c>AgencyController</c> — canonical theo route, cố ý giữ trong
            code), một tầng đứng trước ứng dụng (CDN, cấu hình IIS), hoặc chính Google đang giữ một bản
            ghi cũ từ trước khi luật bị xoá.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.RedirectRuleButStillInSitemap">
            <summary>
            URL <b>còn trong sitemap</b> mà đã có luật chuyển hướng đang bật — mâu thuẫn cần sửa.
            </summary>
            <remarks>
            Không cần hỏi Google mới biết: cả hai vế đều là dữ liệu của mình, nên đây là cờ đối chiếu
            <b>dùng được ngay</b>, khác <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.RedirectWithoutRule"/> phải chờ một lượt kiểm. Bật
            nghĩa là sitemap đang nói "hãy vào đọc trang này" trong khi máy chủ trả 301 "trang này
            chuyển đi rồi" — công cụ tìm kiếm ghi nhận nó thành lỗi chứ không tự chọn giúp bên nào (bài
            học GEO-12). Tầng lưu của màn 301 tự tắt cờ sitemap khi tạo luật, nên bật ở đây nghĩa là có
            người bật lại sau đó, hoặc URL quay vào sitemap từ một nguồn khác <c>UrlRecord</c>.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel">
            <summary>
            Các con số tổng của một công cụ tìm kiếm — phần thẻ đầu trang dashboard.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.TotalUrls">
            <summary>Tổng số URL trong hàng tồn kho (chưa xoá mềm).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.Indexed">
            <summary>Số URL có <c>Verdict = PASS</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.NotIndexed">
            <summary>Số URL <b>đã kiểm</b> mà <c>Verdict</c> khác <c>PASS</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.NotChecked">
            <summary>Số URL chưa từng hỏi Google — không cộng vào <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.NotIndexed"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.ChangedNotRecrawled">
            <summary>Số URL vừa sửa mà Google chưa đọc lại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.CanonicalMismatch">
            <summary>Số URL có hai URL chuẩn tắc lệch nhau.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.NotInGoogleSitemap">
            <summary>Số URL mà Google nói là không thấy trong sitemap.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.RedirectWithoutRule">
            <summary>
            Số URL Google nói đang chuyển hướng mà bảng <c>UrlRedirect</c> không có luật nào —
            <i>chuyển hướng ở đâu ra?</i>
            </summary>
            <remarks>
            <para>
            <b><c>null</c> nghĩa là chưa hỏi Google về URL nào</b>, khác hẳn <c>0</c> nghĩa là đã hỏi và
            không có URL nào như thế. Đây là trạng thái mặc định sau khi deploy, vì hai công tắc gọi
            Google mặc định TẮT — in <c>0</c> ở đó là đúng loại nói dối bằng số mà giai đoạn C đã mắc
            ("Đã index: 0" cho một hệ thống chưa kiểm lần nào).
            </para>
            <para>
            Chỉ đếm trong số URL <b>đã kiểm</b>: URL chưa hỏi Google thì không có ý kiến nào để đối
            chiếu. Đo trên DB dev 2026-09-15: <b>0</b>, trên một hàng tồn kho 148 URL mà cả 148 đều đã
            có lượt kiểm — nên số 0 đó là "đã đo và bằng không", không phải "chưa đo".
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.RedirectRuleButStillInSitemap">
            <summary>
            Số URL còn trong sitemap mà đã có luật chuyển hướng đang bật.
            </summary>
            <remarks>
            Cả hai vế đều là dữ liệu của mình nên con số này <b>không phụ thuộc lượt kiểm Google nào</b> —
            nó đúng kể cả khi hai công tắc gọi Google còn tắt. Nhưng nó <b>vẫn phụ thuộc</b> một thứ: vế
            "còn trong sitemap" đọc <c>SearchUrl.InSitemap</c>, nên trước lượt dựng hàng tồn kho đầu tiên
            (<see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.LastInventorySyncAt"/> còn <c>null</c>) thì bảng rỗng và con số này là 0 vì
            <b>chưa có gì để đếm</b>, không phải vì đã đếm. Giao diện phải đọc nó cùng
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.LastInventorySyncAt"/>.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.ApiCalls24h">
            <summary>Số lời gọi ra công cụ tìm kiếm trong 24 giờ gần nhất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.ApiErrors24h">
            <summary>Số lời gọi thất bại trong 24 giờ gần nhất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.HasMetrics">
            <summary>
            Đã có số liệu nhấp/hiển thị hay chưa. Còn <c>false</c> tới khi có phần đọc Search
            Analytics — giao diện dựa vào cờ này để ẩn hẳn khối đó thay vì vẽ một biểu đồ toàn số 0.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.LastInventorySyncAt">
            <summary>Lần gần nhất hàng tồn kho được dựng lại từ sitemap.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.LastInspectAt">
            <summary>Lần gần nhất hỏi Google trạng thái một URL bất kỳ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.ByVerdict">
            <summary>Đếm theo <c>Verdict</c> — mã ổn định, đây là bảng số liệu dùng được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.ByCoverageState">
            <summary>
            Đếm theo câu mô tả của Google. <b>Chỉ để trả lời "vì sao" và để người dùng bấm lọc</b> theo
            đúng câu chữ họ nhìn thấy trong Search Console — không phải một chỉ số để theo dõi theo thời
            gian, vì câu chữ đổi theo ngôn ngữ property.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.ByGroup">
            <summary>Đếm theo nhóm URL — <c>Key</c> là số của <c>SearchUrlGroup</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.Settings">
            <summary>Công tắc và hạn mức đang hiệu lực.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchCountItem">
            <summary>
            Một dòng đếm: mã để lọc, nhãn để đọc, số để xem.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchCountItem.Key">
            <summary>Mã ổn định — chính là giá trị giao diện gửi ngược lên khi bấm lọc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchCountItem.Label">
            <summary>Nhãn tiếng Việt hiện trên màn hình.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchCountItem.Count">
            <summary>Số URL thuộc nhóm này.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSettingsModel">
             <summary>
             Công tắc, định danh property và hạn mức — phần "vì sao màn hình đang im lặng" của dashboard.
            
             <para>
             Có mặt cả khi mọi công tắc đang tắt: trạng thái tắt là trạng thái hợp lệ, và người vận hành
             phải đọc được ngay lý do thay vì nhìn một màn hình trống rồi tưởng hệ thống hỏng.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSettingsModel.Enabled">
            <summary>Công tắc ĐỌC.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSettingsModel.SubmitEnabled">
            <summary>Công tắc GHI (nộp sitemap).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSettingsModel.CanRead">
            <summary>Được phép gọi lời gọi đọc hay không.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSettingsModel.CanWrite">
            <summary>Được phép gọi lời gọi ghi hay không.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSettingsModel.BlockReason">
            <summary>Câu tiếng Việt giải thích vì sao chưa được gọi; rỗng khi đã được phép ghi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSettingsModel.SiteUrl">
            <summary>Định danh property trong Search Console.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSettingsModel.SitemapUrl">
            <summary>Tệp sitemap đang theo dõi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSettingsModel.InspectDailyBudget">
            <summary>Trần số lượt kiểm URL mỗi ngày.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSettingsModel.InspectUsedToday">
            <summary>
            Số lượt kiểm đã dùng hôm nay — <b>đếm chung</b> cho job theo lịch và nút bấm tay, vì cả hai
            tiêu vào đúng một hạn mức của Google.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSettingsModel.InspectRemainingToday">
            <summary>Số lượt kiểm còn lại hôm nay, không bao giờ âm.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchSitemapStatusModel">
            <summary>
            Trạng thái tệp sitemap dưới mắt công cụ tìm kiếm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchSitemapStatusModel.SitemapUrl">
            <summary>
            Tệp sitemap đang theo dõi, lấy từ cấu hình — có giá trị <b>kể cả khi chưa đo lần nào</b>,
            để màn hình nói được "đang theo dõi tệp nào" trước cả khi có số.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchSitemapStatusModel.HasData">
             <summary>
             Đã có bản ghi đo hay chưa.
            
             <para>
             <c>false</c> là trạng thái hợp lệ (chưa lần nào chạy job đọc sitemap). Giao diện phải hiện
             lý do chứ <b>không</b> được hiện số 0 như thể đã đo và kết quả bằng không — hai điều đó
             dẫn tới hai quyết định khác hẳn nhau.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchSitemapStatusModel.LastSubmittedAt">
            <summary>Lần <b>hệ thống này</b> gửi sitemap đi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchSitemapStatusModel.LastSubmittedByGoogle">
            <summary>Mốc nộp gần nhất theo ghi nhận của Google, bất kể ai nộp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchSitemapStatusModel.LastDownloadedAt">
            <summary>Lần Google thật sự tải tệp về đọc — mốc đáng theo dõi nhất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchSitemapStatusModel.CheckedAt">
            <summary>Thời điểm mình hỏi Google về tệp này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchSitemapStatusModel.IsPending">
            <summary>Google đang xử lý dở tệp này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchSitemapStatusModel.Errors">
            <summary>Số lỗi Google báo trên tệp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchSitemapStatusModel.Warnings">
            <summary>Số cảnh báo Google báo trên tệp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchSitemapStatusModel.UrlCountSubmitted">
            <summary>Số URL Google đếm được trong tệp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchSitemapStatusModel.InventoryUrlCount">
            <summary>
            Số dòng URL đang sống trong hàng tồn kho — để đặt cạnh <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchSitemapStatusModel.UrlCountSubmitted"/>.
            Hai số lệch nhau nghĩa là Google đang đọc một bản sitemap cũ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchApiLogItem">
             <summary>
             Một dòng nhật ký lời gọi ra công cụ tìm kiếm.
            
             <para>
             Cố ý <b>không</b> mang <c>RequestSummary</c>/<c>ResponseSummary</c>: bảng trên màn hình chỉ cần
             trả lời "việc gì, lúc nào, mã bao nhiêu", trong khi hai cột tóm tắt dài tới 8 KB mỗi dòng và
             chỉ hữu ích khi soi lại trực tiếp trong DB.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchApiLogItem.Id">
            <summary>Khoá dòng nhật ký.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchApiLogItem.Action">
            <summary>Việc đã làm: <c>Inspect</c>, <c>GetSitemap</c>, <c>SubmitSitemap</c>, <c>DryRun</c>...</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchApiLogItem.Url">
            <summary>URL liên quan, nếu lượt gọi nhắm vào một trang cụ thể.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchApiLogItem.Endpoint">
            <summary>Endpoint đã gọi, đã bỏ tham số truy vấn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchApiLogItem.HttpStatusCode">
            <summary>Mã HTTP trả về. NULL với lượt chạy thử vì không có lời gọi nào đi ra.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchApiLogItem.IsSuccess">
            <summary>Lượt gọi có thành công không.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchApiLogItem.ErrorMessage">
            <summary>Thông báo lỗi đã rút gọn, nếu thất bại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchApiLogItem.DurationMs">
            <summary>Thời gian gọi, tính bằng mili giây.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchApiLogItem.CreatedTime">
            <summary>Thời điểm gọi.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchInspectNowRequest">
             <summary>
             Yêu cầu kiểm ngay một URL.
            
             <para>
             Chỉ nhận đúng một URL, và URL đó <b>phải đã có trong hàng tồn kho</b> (service kiểm lại). Nhận
             URL tự do vừa là đường SSRF vừa là đường đốt hạn mức của Google bằng những trang không phải
             của mình.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchInspectNowRequest.Url">
            <summary>URL tuyệt đối, khớp chính xác một dòng <c>SearchUrl</c> chưa xoá.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchInspectNowResult">
            <summary>
            Kết quả một lượt kiểm ngay: trạng thái mới của URL kèm hạn mức còn lại, để màn hình cập nhật
            đủ cả hai thứ mà không phải gọi thêm lượt nào.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchInspectNowResult.Item">
            <summary>Trạng thái URL sau khi kiểm. NULL khi lượt kiểm bị từ chối hoặc thất bại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchInspectNowResult.InspectUsedToday">
            <summary>Số lượt kiểm đã dùng hôm nay sau lượt vừa rồi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchInspectNowResult.InspectRemainingToday">
            <summary>Số lượt kiểm còn lại hôm nay, không bao giờ âm.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceDataState">
             <summary>
             Vì sao màn hình đang hiện con số nó đang hiện.
            
             <para>
             <b>Ở miền này có ít nhất ba cách ra số 0, và chúng đòi ba phản ứng khác nhau.</b> Một màn hình
             in "0 lượt bấm" cho cả ba là nói với người đọc rằng website không ai vào — trong khi sự thật có
             thể là chưa ai bấm chạy tác vụ kéo số. Con số 0 chỉ có nghĩa khi nó nghĩa là "đã đo và bằng
             không".
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceDataState.ChuaKeoVe">
            <summary>Bảng chưa có dòng nào — chưa kéo lần nào. Việc cần làm: bấm chạy tác vụ kéo bù.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceDataState.DaKeo">
            <summary>Đã kéo và khoảng đang xem có số. Đây là trạng thái bình thường.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceDataState.KhoangNayChuaCoSo">
            <summary>
            Đã kéo nhưng riêng khoảng ngày đang xem không có ngày nào có số — ví dụ hỏi 7 ngày trong
            khi mới kéo bù tới một mốc cũ hơn.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceDataState.CuHonKyVong">
            <summary>
            Số mới nhất cũ hơn hẳn mức Google thường chốt (~3 ngày). Gần như luôn nghĩa là job hằng
            ngày chưa được đăng ký, hoặc đang hỏng. Đây là một <b>cảnh báo</b>, không phải một con số.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel">
            <summary>Các con số tổng hợp của tab hiệu suất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.Days">
            <summary>Độ dài khoảng đang xem, tính bằng ngày.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.TuNgay">
            <summary>Ngày đầu khoảng đang xem. <c>null</c> khi chưa kéo lần nào.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.DenNgay">
            <summary>Ngày cuối khoảng đang xem.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.NgayCoSoSomNhat">
            <summary>Ngày sớm nhất bảng có số — cho biết lượt kéo bù đã đi ngược tới đâu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.NgayCoSoMoiNhat">
            <summary>Ngày gần nhất bảng có số.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.SoNgayTre">
            <summary>Số ngày từ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.NgayCoSoMoiNhat"/> tới hôm nay.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.DoTreChotSoNgay">
            <summary>Độ trễ chốt số bình thường của Google, để màn hình nói ra ngưỡng nó đang so.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.TrangThai">
            <summary>Xem <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceDataState"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.GiaiThich">
            <summary>Câu giải thích đọc được, hiện thẳng lên màn hình. Rỗng khi mọi thứ bình thường.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.SoNgayCoSo">
            <summary>Số ngày thật sự có dòng trong khoảng — khác <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.Days"/> khi dữ liệu thủng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.Clicks">
            <summary>
            Tổng lượt bấm. <b>Lấy từ mức toàn site</b>, không phải cộng từ mức trang — đo 2026-09-16:
            cộng từ mức trang cho lượt hiển thị lệch +47 %.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.Impressions">
            <summary>Tổng lượt hiển thị, cùng nguồn với <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.Clicks"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.PositionWeightedSum">
            <summary>Tổng (vị trí × lượt hiển thị) — để màn hình tính lại vị trí trung bình cho đúng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.Ctr">
            <summary>CTR của cả khoảng, tính từ tổng chứ không phải trung bình các CTR ngày.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.Position">
            <summary>Vị trí trung bình của cả khoảng, tính từ tổng có trọng số.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.ClicksKyTruoc">
            <summary>Lượt bấm của kỳ liền trước cùng độ dài. <c>null</c> khi chưa đủ dữ liệu để so.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.ImpressionsKyTruoc">
            <summary>Lượt hiển thị của kỳ liền trước.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.SoNgayCoSoKyTruoc">
            <summary>
            Số ngày có số ở kỳ trước. Quan trọng hơn vẻ ngoài của nó: kỳ trước chỉ có 3/28 ngày thì
            phép so "giảm 89 %" là vô nghĩa, và màn hình phải biết để không vẽ ra một mũi tên đỏ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceSummaryModel.TheoNgay">
            <summary>Số liệu từng ngày, để vẽ đường xu hướng. Đã xếp theo ngày tăng dần.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceDayItem">
            <summary>Một ngày trong đường xu hướng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceRowItem">
            <summary>Một dòng của bảng xếp hạng trang hoặc truy vấn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceRowItem.Key">
            <summary>Giá trị chiều đã gộp — URL đã chuẩn hoá, hoặc truy vấn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceRowItem.Url">
            <summary>URL, khi dòng này là một trang.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceRowItem.Query">
            <summary>Truy vấn, khi dòng này là một truy vấn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceRowItem.Ctr">
            <summary>Tính từ tổng của dòng, không phải trung bình các CTR ngày.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceRowItem.Position">
            <summary>Tính từ tổng có trọng số của dòng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceRowItem.InSitemap">
            <summary>
            Trang này còn trong sitemap không. <c>null</c> nghĩa là <b>hàng tồn kho không có URL
            này</b> — không phải "không có trong sitemap". Hai điều đó khác nhau, và cái sau là một
            phát hiện đáng xem: Google có lưu lượng cho một trang mà hệ thống chưa biết tới.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceRowItem.CoTrongTonKho">
            <summary>
            URL này có mặt trong hàng tồn kho không. Tách khỏi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchPerformanceRowItem.InSitemap"/> để màn hình nói
            được ba câu khác nhau thay vì hai.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CallPathVersionModel">
            <summary>
            Model cho CallPathVersion - dùng cho Create/Update/GetById
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CallPathVersionModel.Version">
            <summary>
            Số phiên bản (ví dụ: 1.0.0)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CallPathVersionModel.Build">
            <summary>
            Số build (ví dụ: 101)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CallPathVersionModel.Domain">
            <summary>
            Domain cơ sở (ví dụ: https://api.ladaexpress.vn)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CallPathVersionModel.Description">
            <summary>
            Mô tả phiên bản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CallPathVersionModel.IsDefault">
            <summary>
            Đánh dấu phiên bản mặc định
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CopyCallPathRequest">
            <summary>
            Request model để copy CallPath từ một version sang version khác.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CopyCallPathRequest.SourceVersionId">
            <summary>
            Id của CallPathVersion nguồn (copy từ).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CopyCallPathRequest.TargetVersionId">
            <summary>
            Id của CallPathVersion đích (copy sang).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatChannelStaffModel">
            <summary>
            Thêm hoặc sửa một dòng "nhân viên phụ trách kênh".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatChannelStaffModel.Id">
            <summary>Bỏ trống (0) là thêm mới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatChannelStaffModel.WeightOverride">
            <summary>
            Ép trọng số phân phối. Bỏ trống là tính theo điểm chất lượng.
            Khoảng cho phép cùng khoảng của trọng số suy từ điểm (§3.6).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatChannelAssignmentModel">
            <summary>
            Đổi cấu hình phân phối của một kênh: bưu cục sở hữu và chế độ phân phối.
            <para>
            Đổi <c>AssignmentMode</c> khỏi <c>Shared</c> là <b>bật hàng rào quyền xem</b> cho kênh —
            một hành động đổi phạm vi dữ liệu người ta đọc được, không phải một tuỳ chọn hiển thị.
            Giao diện phải hỏi lại trước khi gửi.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatChannelAssignmentModel.AgencyId">
            <summary>Bưu cục sở hữu kênh; bỏ trống là gỡ liên kết bưu cục</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatDistributionReplayModel">
            <summary>Tham số một lượt phát lại lịch sử để dựng bảng đối chiếu dry-run.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatDistributionReplayModel.From">
            <summary>Đầu cửa sổ (bao gồm)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatDistributionReplayModel.To">
            <summary>Cuối cửa sổ (không bao gồm)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatDistributionReplayModel.ChatChannelId">
            <summary>Chỉ một kênh; bỏ trống hoặc 0 = mọi kênh đang tự phân phối</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceModel">
            <summary>
            Đặt trạng thái sẵn sàng — cho chính mình hoặc cho người khác.
            </summary>
            <remarks>
            Một model dùng cho cả hai đường, nhưng <b>hai endpoint riêng</b> với hai
            <c>[Authorize]</c> khác nhau: đặt cho người khác đòi <c>ChatAgentPresence.ManageOthers</c>.
            Gộp thành một endpoint rồi phân nhánh theo <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceModel.StaffId"/> là dựng một đường mà quyền
            phụ thuộc vào nội dung thân yêu cầu — đúng loại hàng rào dễ quên nhất.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceModel.StaffId">
            <summary>
            Người được đặt trạng thái. Bỏ trống (0) ở đường "của tôi" nghĩa là chính người đăng
            nhập; ở đường "đặt hộ" thì bắt buộc.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceModel.SelfStatus">
            <summary>
            Trạng thái muốn đặt. Chỉ nhận <c>Available</c> / <c>Busy</c> / <c>Away</c> /
            <c>OnLeave</c> — <c>Suspended</c> đi qua đường riêng, còn <c>OffShift</c> và
            <c>Resigned</c> là trạng thái suy ra, không ai khai được.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceModel.UntilTime">
            <summary>
            Đến khi nào. <b>Bắt buộc</b> với <c>Busy</c> / <c>Away</c> / <c>OnLeave</c>, và phải
            nằm trong tương lai; bỏ qua với <c>Available</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceModel.Note">
            <summary>Ghi chú hiện cho quản lý và đồng nghiệp</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel">
            <summary>
            Đặt, sửa hoặc xoá giờ làm việc <b>riêng</b> của một sale (KC-18) — cho chính mình hoặc cho
            người khác.
            </summary>
            <remarks>
            <para>
            Cùng khuôn với <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceModel"/>: một model, <b>hai endpoint</b> với hai
            <c>[Authorize]</c> khác nhau (<c>me/working-hours</c> và <c>staff/working-hours</c>). Đường
            "của tôi" không đọc <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel.StaffId"/>.
            </para>
            <para>
            Mọi trường giờ là <c>string?</c> và ngày làm là <c>int[]?</c> có chủ ý: assembly bật
            <c>&lt;Nullable&gt;enable</c>, nên một kiểu tham chiếu không-null bị ASP.NET Core suy ra
            <c>[Required]</c> ngầm — gửi <c>null</c> để <b>xoá</b> giờ riêng sẽ ăn 400 trước khi dòng
            code đầu tiên chạy (đúng lỗi L13 ghi ở <c>ChatPresenceController.SearchDurations</c>).
            Luật hợp lệ nằm ở <c>ChatWorkingHours.ValidateStaffInput</c>, không ở attribute, để API và
            đường dựng từ cột dùng chung một định nghĩa.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel.StaffId">
            <summary>
            Người được đặt giờ. Bỏ qua ở đường "của tôi"; bắt buộc ở đường "đặt hộ".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel.WorkStart">
            <summary>
            Giờ bắt đầu làm việc, dạng <c>HH:mm</c>. Để trống <b>cùng</b> <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel.WorkEnd"/> là
            xoá giờ riêng, về "chưa đặt" (luôn trong ca).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel.WorkEnd">
            <summary>Giờ kết thúc làm việc, dạng <c>HH:mm</c>; <c>23:59</c> (hoặc <c>24:00</c>) = làm tới hết ngày</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel.BreakStart">
            <summary>Giờ bắt đầu nghỉ trưa, dạng <c>HH:mm</c>; trống cùng <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel.BreakEnd"/> = không nghỉ trưa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel.BreakEnd">
            <summary>Giờ kết thúc nghỉ trưa, dạng <c>HH:mm</c></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel.WorkingDays">
            <summary>Ngày làm, mã 2 (Thứ Hai) … 7 (Thứ Bảy), 8 (Chủ Nhật); phải có ít nhất một ngày khi đặt giờ</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceSuspendModel">
            <summary>
            Quản lý tạm ngưng chia khách cho một người, hoặc gỡ lệnh tạm ngưng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceSuspendModel.SuspendedUntil">
            <summary>
            Tạm ngưng đến khi nào. Bỏ trống là <b>gỡ</b> lệnh tạm ngưng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceSuspendModel.Note">
            <summary>
            Lý do tạm ngưng. <b>Bắt buộc</b> khi đặt, bỏ qua khi gỡ.
            <para>
            Bắt buộc có chủ ý: §3.6 chọn "quản lý bấm tạm ngưng" làm đường cắt hẳn một người khỏi
            việc nhận khách, chính vì nó có tên người chịu trách nhiệm — một lệnh cắt không lý do
            thì bằng đúng cái công thức trọng số mà §3.6 vừa từ chối.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceDelegateModel">
            <summary>
            Uỷ quyền tạm bằng tay: giao hội thoại của một người đang không sẵn sàng cho người khác cùng
            kênh, người cũ vẫn giữ quyền đọc.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceDelegateModel.FromStaffId">
            <summary>Người đang giữ hội thoại (đang nghỉ / bị tạm ngưng / ngoài giờ)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceDelegateModel.ToStaffId">
            <summary>
            Người nhận tạm. Bỏ trống (0) là để hệ thống tự chọn người ít việc nhất đang sẵn sàng
            trong cùng kênh.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceDelegateModel.Note">
            <summary>Ghi chú, ghi thẳng vào dòng lịch sử phân công</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SaveChatQuickReplyModel">
            <summary>
            Tạo hoặc sửa một mẫu tin nhắn nhanh — dùng chung cho <c>save-personal</c> và <c>save-shared</c>
            (docs/plan-tin-nhan-nhanh-chat.md §3.3).
            <para>
            Model này KHÔNG có, và không bao giờ được có, bốn trường: <c>Scope</c>, <c>OwnerUserId</c>,
            <c>ImageUrl</c>, <c>ImageSystemPath</c>. Phạm vi do <b>endpoint</b> quyết định — mỗi phạm vi một
            endpoint, gác bằng một role khác nhau. Chủ của mẫu cá nhân là người đang đăng nhập. Ảnh chỉ vào qua
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SaveChatQuickReplyModel.File"/>, máy chủ tự lưu và tự sinh đường dẫn. Thêm một trong bốn trường ấy là mở lại đúng
            lỗ mà §3.8 đóng; ca test <c>Model_KhongNhanPhamViChuVaDuongDanTuClient</c> canh điều này.
            </para>
            <para>
            Không khai thuộc tính kiểm tra dữ liệu: mọi luật (độ dài, định dạng phím tắt, trùng phím tắt) nằm ở
            <c>ChatQuickReplyService</c> để một luật chỉ có một chỗ, trả cùng một kiểu <c>BaseResult</c> với
            thông điệp tiếng Việt, và ca test gọi thẳng vào được.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SaveChatQuickReplyModel.Id">
            <summary>Bỏ trống (hoặc 0) là tạo mới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SaveChatQuickReplyModel.Title">
            <summary>Tên hiện trong danh sách chọn — bắt buộc, tối đa 200 ký tự</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SaveChatQuickReplyModel.Shortcut">
            <summary>
            Từ khoá gõ sau dấu <c>/</c>; bỏ trống là không có phím tắt. Máy chủ bỏ dấu <c>/</c> gõ kèm và
            hạ chữ thường, rồi chỉ nhận <c>[a-z0-9_-]</c>, tối đa 50 ký tự.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SaveChatQuickReplyModel.Content">
            <summary>Nội dung mẫu — bắt buộc, tối đa 2.000 ký tự (giới hạn một tin của Zalo)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SaveChatQuickReplyModel.SortOrder">
            <summary>Thứ tự trong danh sách chọn, xét sau số lượt dùng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SaveChatQuickReplyModel.File">
            <summary>Ảnh mới cho mẫu — JPG/PNG, tối đa 1 MB. Bỏ trống là giữ nguyên ảnh đang có.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SaveChatQuickReplyModel.RemoveImage">
            <summary>
            Bỏ ảnh khỏi mẫu: xoá hai cột ảnh, <b>không</b> xoá tệp trên đĩa — tin đã gửi từ mẫu vẫn đang trỏ
            vào tệp ấy (nguyên tắc 1.4). Có <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SaveChatQuickReplyModel.File"/> mới thì cờ này bị bỏ qua.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendQuickReplyModel">
            <summary>
            Gửi một tin vào hội thoại, xuất phát từ một mẫu tin nhắn nhanh (<c>send-quick-reply</c>).
            <para>
            Không có, và không bao giờ được có, trường đường dẫn tệp. Client chỉ nói <b>mẫu nào</b> và
            <b>có gửi kèm ảnh của mẫu hay không</b>; máy chủ tra ảnh theo mã mẫu — cùng lý do
            <c>SendChatImageModel</c> nhận chính tệp chứ không nhận đường dẫn.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendQuickReplyModel.QuickReplyId">
            <summary>Mẫu xuất phát — phải thấy được với người gửi và đang bật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendQuickReplyModel.Content">
            <summary>
            Nội dung <b>gửi đi</b>: chữ trong ô soạn sau khi nhân viên đã sửa và đã thay placeholder, không
            phải nội dung gốc của mẫu (§3.2). Với tin kèm ảnh thì đây là chú thích, có thể bỏ trống.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendQuickReplyModel.WithImage">
            <summary><c>true</c> = gửi kèm ảnh <b>của mẫu</b>; mẫu không có ảnh thì bị từ chối</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendQuickReplyModel.ReplyToMessageId">
            <summary>
            Mã tin <b>trong LADA</b> được trả lời trích dẫn, như <c>SendChatMessageModel.ReplyToMessageId</c>.
            Tin kèm ảnh không trích dẫn được — luật đó nằm sẵn trong <c>SendMessageAsync</c>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.LinkChatCustomerModel">
            <summary>
            Gắn một hội thoại với hồ sơ khách hàng có sẵn trong hệ thống.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.LinkChatCustomerModel.CustomerKeyword">
            <summary>
            Từ khoá mà nhân viên đã dùng để tìm ra khách hàng này (thường là số điện thoại).
            <para>
            Bắt buộc, và không phải để tìm lại: máy chủ chạy lại ĐÚNG đường gợi ý có phạm vi với
            từ khoá này rồi đối chiếu <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.LinkChatCustomerModel.CustomerId"/> nằm trong kết quả. Không có bước
            đó thì endpoint gắn khách thành một máy tra tên khách hàng theo mã — gọi lần lượt
            1, 2, 3… là đọc được tên của cả tệp khách hàng mà không cần từ khoá nào.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.LinkChatCustomerModel.WriteContact">
            <summary>
            Có ghi thêm dấu vết liên hệ (tên + định danh nền tảng) vào hồ sơ khách hàng không.
            Ghi THÊM chứ không đè — cột đó là văn bản tự do đã có người nhập tay từ trước.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.AssignChatConversationModel">
            <summary>
            Phân công một hội thoại cho nhân viên.
            <para>
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.AssignChatConversationModel.AssignedStaffId"/> để trống nghĩa là GỠ phân công — đó là một hành động có
            thật ("tôi không cầm việc này nữa"), không phải dữ liệu thiếu.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChangeChatStatusModel">
            <summary>
            Đổi trạng thái vòng đời của một hội thoại.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ReleaseChatConversationModel">
            <summary>
            Nhả một hội thoại về hàng chờ.
            </summary>
            <remarks>
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ReleaseChatConversationModel.Reason"/> <b>không phải một nhãn hiển thị</b>: nó quyết định người vừa nhả còn
            đọc được hội thoại nữa không (§6.2). Vì thế nó bắt buộc, và giao diện không có ô nào cho
            người dùng tự đặt cờ quyền đọc — cờ ấy suy ra từ lý do, ở
            <c>ChatReleaseReasonRules.KeepsReadAccess</c>.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ReleaseChatConversationModel.Note">
            <summary>Ghi chú bắt buộc — nhật ký chỉ có mã lý do thì tháng sau không ai đọc lại được</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.RevokeChatReadAccessModel">
            <summary>
            Thu hồi quyền xem một hội thoại của một nhân viên đã thôi giữ nó.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.RevokeChatReadAccessModel.StaffId">
            <summary>Nhân viên bị thu hồi quyền xem</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.RevokeChatReadAccessModel.Reason">
            <summary>Bắt buộc là lý do CẮT quyền xem (§6.2); lý do khác bị máy chủ từ chối</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.TransferChatConversationModel">
            <summary>
            Chuyển một hội thoại sang nhân viên khác.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.TransferChatConversationModel.ToStaffId">
            <summary>Người nhận hội thoại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.TransferChatConversationModel.Reason">
            <summary>Vì sao người cũ thôi giữ — quyết định phạm vi dữ liệu của họ (§6.2)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.FacebookPagesLookupModel">
            <summary>
            Dữ liệu hỏi danh sách Page mà một tài khoản Facebook đang quản lý.
            <para>
            Điền đúng MỘT trong hai trường. <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.FacebookPagesLookupModel.State"/> là đường chuẩn: quản trị viên đã bấm
            "Đăng nhập bằng Facebook" và token đang nằm trong bộ nhớ máy chủ, trình duyệt không giữ gì.
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.FacebookPagesLookupModel.UserAccessToken"/> là đường dự phòng cho lúc ứng dụng Facebook chưa khai xong
            đường chuyển hướng.
            </para>
            <para>
            Cả hai đi trong THÂN request chứ không trên query string: query string bị ghi vào nhật ký
            truy cập của mọi proxy và của chính máy chủ, mà đây là bí mật mở được cả tệp Page.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.FacebookPagesLookupModel.UserAccessToken">
            <summary>
            User access token dán từ Graph API Explorer. Máy chủ tự đổi sang bản dài hạn rồi
            dùng để hỏi <c>/me/accounts</c>; giá trị này KHÔNG bao giờ được lưu xuống database.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.FacebookPagesLookupModel.State">
            <summary>
            Chuỗi <c>state</c> của phiên Facebook Login vừa hoàn tất, lấy từ
            <c>GET facebook/authorization-url</c>. Không phải bí mật tự thân — nó chỉ mở được phiên
            của đúng người đã bấm cấp quyền, và chỉ trong 10 phút.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ConnectFacebookPageModel">
            <summary>
            Dữ liệu kết nối một Page cụ thể thành kênh chat.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ConnectFacebookPageModel.PageId">
            <summary>Định danh Page được chọn ở bước trước</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendChatImageModel">
            <summary>
            Dữ liệu tải một ảnh lên rồi gửi vào hội thoại.
            <para>
            Model này KHÔNG có, và không bao giờ được có, trường đường dẫn tệp. Chỉ có chính tệp
            (<see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendChatImageModel.File"/>) — máy chủ lưu rồi tự sinh đường dẫn. Nhận đường dẫn từ client là mở
            đường đọc tệp bất kỳ trên máy chủ rồi gửi thẳng ra ngoài cho khách.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendChatImageModel.Caption">
            <summary>Chú thích đi kèm ảnh, có thể bỏ trống</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendChatImageModel.File">
            <summary>Tệp ảnh — JPG hoặc PNG, tối đa 1 MB (giới hạn của Zalo)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendChatMessageModel">
            <summary>
            Dữ liệu nhân viên gửi lên khi trả lời một hội thoại.
            <para>
            Cố ý rất hẹp. Mọi thứ khác — kênh nào, gửi cho ai, gửi bằng token nào — đều tra từ hội thoại
            phía máy chủ, vì đó là những giá trị quyết định tin đi tới đâu. Trường thứ ba thêm ở giai
            đoạn G cũng theo đúng luật ấy: nó mang mã tin <b>nội bộ</b>, không mang mã tin của nền tảng.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendChatMessageModel.Content">
            <summary>Nội dung văn bản. Zalo giới hạn 2.000 ký tự, tầng ZaloApiService kiểm lại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendChatMessageModel.ReplyToMessageId">
            <summary>
            Mã tin <b>trong LADA</b> mà tin này trả lời trích dẫn; bỏ trống là tin thường.
            <para>
            Cố ý KHÔNG nhận mã tin của nền tảng. Máy chủ tra mã ấy ra từ mã nội bộ này, và tra theo
            CẶP (tin, hội thoại) — nhận thẳng mã nền tảng thì không kiểm được nó thuộc hội thoại nào,
            và một mã đoán được sẽ kéo nội dung của khách khác vào câu trả lời gửi ra ngoài.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendChatReactionModel">
            <summary>
            Dữ liệu nhân viên gửi lên khi thả hoặc gỡ một biểu tượng cảm xúc trên một tin nhắn.
            <para>
            Cùng luật với <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendChatMessageModel"/>: chỉ mang mã tin <b>nội bộ</b>, còn kênh
            nào, gửi cho ai, gửi bằng token nào đều tra từ hội thoại phía máy chủ. Nhận mã tin của nền
            tảng từ client thì không kiểm được nó thuộc hội thoại nào.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendChatReactionModel.MessageId">
            <summary>Mã tin trong LADA cần thả biểu tượng cảm xúc</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendChatReactionModel.Emoji">
            <summary>
            Ký tự emoji cần thả. <b>Bỏ trống nghĩa là GỠ</b> biểu tượng đang có; gửi lại đúng biểu
            tượng đang hiển thị cũng được hiểu là gỡ, đúng thói quen bấm ở chính hai nền tảng.
            <para>
            Là emoji thật chứ không phải mã riêng của nền tảng — việc đổi sang <c>react_icon</c> của
            Zalo làm ở tầng nền tảng. Zalo chỉ nhận sáu biểu tượng và sẽ từ chối phần còn lại; danh
            sách hợp lệ của từng hội thoại nằm ở <c>ChatConversationItem.ReactionEmojis</c>.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Training.CourseModel">
            <summary>
            Model tạo/cập nhật khóa học
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Training.SectionModel">
            <summary>
            Model tạo/cập nhật section
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Training.LessonModel">
            <summary>
            Model tạo/cập nhật bài giảng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel">
            <summary>
            Model đổ dầu cho lái xe trên app mobile.
            Lái xe là người đăng nhập, xe là xe đang phụ trách (tự động xác định).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel.FuelCardId">
            <summary>
            ID thẻ xăng dầu (nullable - có thể của mình hoặc người khác, hoặc trả tiền mặt)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel.QrCode">
            <summary>
            QR Code được quét từ thẻ (thay thế FuelCardId khi đổ bằng thẻ)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel.CurrentOdo">
            <summary>
            ODO hiện tại khi đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel.Amount">
            <summary>
            Số tiền đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel.UnitPrice">
            <summary>
            Đơn giá dầu (VND/lít)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel.PaymentMethod">
            <summary>
            Phương thức thanh toán: Card(1) hoặc Cash(2)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel.StationName">
            <summary>
            Tên cây xăng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel.StationAddress">
            <summary>
            Địa chỉ cây xăng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel.RefillTime">
            <summary>
            Thời gian đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel.Notes">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel.Files">
            <summary>
            Danh sách hình ảnh (ODO trước, ODO sau, cây dầu, hóa đơn)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel.MediaTypes">
            <summary>
            Loại hình ảnh tương ứng (OdoBeforePhoto, OdoAfterPhoto, FuelPumpPhoto, FuelReceiptPhoto)
            Phải tương ứng 1-1 với Files
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.GarageModel">
            <summary>
            Dữ liệu tạo/sửa garage
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.GarageModel.Name">
            <summary>
            Tên garage
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.GarageModel.Address">
            <summary>
            Địa chỉ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.GarageModel.Phone">
            <summary>
            Số điện thoại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.GarageModel.ContactPerson">
            <summary>
            Người liên hệ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.GarageModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.GarageModel.IsActive">
            <summary>
            Còn sử dụng hay không
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.MaintenanceSlipUploadModel">
            <summary>
            Payload multipart đọc phiếu bằng AI lúc TẠO MỚI bản ghi bảo dưỡng (QĐ3-3) — tệp chỉ được đọc, không lưu làm media.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.MaintenanceSlipUploadModel.File">
            <summary>Phiếu / hoá đơn: ảnh (JPG, PNG, WebP, HEIC) hoặc PDF.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.MaintenanceSlipUploadModel.TruckId">
            <summary>Xe đang chọn trên form — phải thuộc phạm vi chi nhánh của người gọi.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.MaintenanceSlipAttachModel">
            <summary>Gắn một lượt đọc lúc tạo mới vào bản ghi vừa lưu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.MaintenanceSlipAttachModel.MediaLinkId">
            <summary>Dòng media vừa tải lên từ cùng tệp (nếu có).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeAliasModel">
            <summary>Ghi nhớ một tên gọi khác cho loại bộ phận K200.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeAliasModel.Alias">
            <summary>Tên như trên phiếu, ví dụ "nhớt", "bố thắng".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckActivityModel.CurrentOdo">
            <summary>
            Số ODO hiện tại của xe (chỉ áp dụng cho hoạt động đổ dầu)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckAssetModel.UnitPrice">
            <summary>
            Đơn giá
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckCheckInOutModel">
            <summary>
            Model cho việc nhận/trả xe tải
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckCheckInOutModel.TruckId">
            <summary>
            ID xe tải
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckCheckInOutModel.AgencyId">
            <summary>
            ID đại lý (tự động lấy từ thông tin người dùng)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckCheckInOutModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckCheckInOutModel.CurrentOdo">
            <summary>
            Số ODO hiện tại của xe (bắt buộc, >= 0)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckCheckInOutModel.Files">
            <summary>
            Danh sách file hình ảnh upload
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentModel">
            <summary>
            Dữ liệu gắn/sửa bộ phận trên xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentModel.TruckId">
            <summary>
            Xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentModel.ComponentTypeId">
            <summary>
            Loại bộ phận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentModel.Position">
            <summary>
            Vị trí trên xe (giá trị enum <c>ComponentPosition</c>; 0 = không theo vị trí)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentModel.InstalledDate">
            <summary>
            Ngày lắp
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentModel.InstalledOdo">
            <summary>
            ODO lúc lắp. Bỏ trống thì hệ thống lấy ODO hiện tại của xe.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentModel.Source">
            <summary>
            Nguồn gốc (giá trị enum <c>ComponentSource</c>: 1 = nguyên bản nhà máy, 2 = đã thay mới)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentModel.LifespanKmOverride">
            <summary>
            Tuổi thọ theo km riêng cho bộ phận này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentModel.LifespanMonthsOverride">
            <summary>
            Tuổi thọ theo tháng riêng cho bộ phận này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentModel.IsActive">
            <summary>
            Còn đang lắp trên xe hay không
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentInitModel">
            <summary>
            Yêu cầu khởi tạo bộ bộ phận hàng loạt cho một xe từ danh mục đang bật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentInitModel.TruckId">
            <summary>
            Xe cần khởi tạo bộ phận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentInitModel.ComponentTypeIds">
            <summary>
            Chỉ khởi tạo các loại bộ phận này. Bỏ trống = mọi loại đang bật và
            KHÔNG yêu cầu vị trí (loại theo vị trí như lốp phải gắn tay vì số lượng
            phụ thuộc cấu hình trục của từng xe).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentInitModel.InstalledDate">
            <summary>
            Ngày lắp áp dụng chung. Bỏ trống = hôm nay.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentInitModel.InstalledOdo">
            <summary>
            ODO lúc lắp áp dụng chung. Bỏ trống = ODO hiện tại của xe.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentInitModel.Source">
            <summary>
            Nguồn gốc áp dụng chung (mặc định 1 = nguyên bản nhà máy)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel">
            <summary>
            Dữ liệu tạo/sửa loại bộ phận xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel.Code">
            <summary>
            Mã loại bộ phận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel.Name">
            <summary>
            Tên hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel.DefaultLifespanKm">
            <summary>
            Tuổi thọ mặc định theo km
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel.DefaultLifespanMonths">
            <summary>
            Tuổi thọ mặc định theo tháng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel.RequiresPosition">
            <summary>
            Có gắn với vị trí trên xe hay không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel.WarnBeforeKm">
            <summary>
            Ngưỡng cảnh báo trước theo km (null = dùng mặc định toàn cục)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel.WarnBeforeDays">
            <summary>
            Ngưỡng cảnh báo trước theo ngày (null = dùng mặc định toàn cục)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel.GroupType">
            <summary>
            Nhóm phân loại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel.QuantityPerTruck">
            <summary>
            Số lượng trên mỗi xe, dạng chữ tham khảo (tối đa 128 ký tự)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel.ReferenceCost">
            <summary>
            Chi phí tham khảo dạng chữ (tối đa 256 ký tự)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel.Note">
            <summary>
            Ghi chú
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel.IsActive">
            <summary>
            Còn dùng hay không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel.SortOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckFuelRefillModel">
            <summary>
            Model cho hoạt động đổ dầu xe tải
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckFuelRefillModel.TruckId">
            <summary>
            ID của xe tải
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckFuelRefillModel.AgencyId">
            <summary>
            ID của đại lý (tự động lấy từ thông tin người dùng)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckFuelRefillModel.CurrentOdo">
            <summary>
            Số ODO hiện tại của xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckFuelRefillModel.Note">
            <summary>
            Ghi chú về việc đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckFuelRefillModel.Files">
            <summary>
            Danh sách file ảnh đổ dầu (tối thiểu 2, tối đa 5)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceMediaUploadModel">
            <summary>
            Payload multipart tải tệp đính kèm cho một lần bảo dưỡng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceMediaUploadModel.MaintenanceId">
            <summary>Lần bảo dưỡng nhận tệp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceMediaUploadModel.MediaType">
            <summary>Loại tệp — giá trị enum <c>TruckMaintenanceMediaType</c>: 1 hoá đơn, 2 ảnh hiện trạng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceMediaUploadModel.Files">
            <summary>Các tệp ảnh</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel">
            <summary>
            Đối tượng đại diện cho thông tin bảo dưỡng xe tải.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.AgencyId">
            <summary>
            Id của đại lý.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.TruckId">
            <summary>
            Id của xe tải.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.Title">
            <summary>
            Tiêu đề của hoạt động bảo dưỡng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.Description">
            <summary>
            Mô tả của hoạt động bảo dưỡng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.UserId">
            <summary>
            Id của người dùng thực hiện bảo dưỡng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.GarageName">
            <summary>
            Tên của gara thực hiện bảo dưỡng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.GarageAddress">
            <summary>
            Địa chỉ của gara thực hiện bảo dưỡng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.GaragePhone">
            <summary>
            Số điện thoại của gara thực hiện bảo dưỡng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.Cost">
            <summary>
            Chi phí bảo dưỡng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.HasInvoice">
            <summary>
            Có hóa đơn hay không.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.InvoiceUrl">
            <summary>
            URL của hóa đơn.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.StartTime">
            <summary>
            Thời gian bắt đầu bảo dưỡng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.EndTime">
            <summary>
            Thời gian kết thúc bảo dưỡng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.NextTime">
            <summary>
            Thời gian bảo dưỡng tiếp theo.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.GarageId">
            <summary>
            Garage chọn từ danh mục. Null = không nhắc tới (màn cũ nhập garage bằng ba trường chuỗi).
            </summary>
            <remarks>
            Luồng cập nhật chỉ ghi đè khi trường này có giá trị — payload kiểu cũ thiếu trường mới
            không được phép xoá trắng dữ liệu màn mới đã nhập (§3.11 dòng bẫy DTO).
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.Odo">
            <summary>
            Chỉ số ODO của xe tại thời điểm bảo dưỡng — mốc reset tuổi thọ khi thay bộ phận mới.
            Null = không nhắc tới.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.TruckMaintLinkModels">
            <summary>
            Danh sách các liên kết bảo dưỡng xe tải.
            </summary>
            <remarks>
            <c>null</c> nghĩa là payload không nhắc tới dòng công việc nào ⇒ giữ nguyên toàn bộ dòng
            đang có. Danh sách rỗng mới là lệnh xoá hết dòng không gắn bộ phận.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.DeletedTruckMaintLinkIds">
            <summary>
            Id các dòng công việc cần xoá — cách <b>duy nhất</b> để xoá một dòng đã gắn bộ phận.
            </summary>
            <remarks>
            Dòng gắn bộ phận không được suy ra ý định xoá từ việc payload thiếu nó: màn cũ không hề
            biết trường <c>TruckComponentId</c> tồn tại nên payload của nó luôn "thiếu" (nợ BD-8).
            Muốn xoá thì phải nói ra.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.ClearGarageId">
            <summary>
            Gỡ hẳn garage khỏi bản ghi (đặt <c>GarageId</c> về null).
            </summary>
            <remarks>
            Cần một cách nói tường minh vì <c>GarageId = null</c> đã mang nghĩa "không nhắc tới"
            — nếu không thì màn mới không bao giờ gỡ được garage đã chọn nhầm. Cờ này thắng
            <c>GarageId</c>: gửi cả hai thì garage bị gỡ.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.ClearOdo">
            <summary>
            Gỡ hẳn chỉ số ODO khỏi bản ghi (đặt <c>Odo</c> về null). Cùng lý do với
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel.ClearGarageId"/>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintDeleteModel">
            <summary>
            Tham số xoá một lần bảo dưỡng — chỉ cần Id.
            </summary>
            <remarks>
            Không dùng lại <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel"/>: các trường bắt buộc của nó
            (Title, Description, GarageName, InvoiceUrl) làm mọi payload chỉ có Id bị chặn ở
            bước kiểm tra model và trả 400 trước khi vào action — nút "Xóa lần bảo dưỡng"
            vì thế chưa từng xoá được. Hình dạng này khớp với tài liệu API và với màn đang gọi.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintDeleteModel.Id">
            <summary>
            Id của lần bảo dưỡng cần xoá.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintLinkModel.TruckMaintAttributeId">
            <summary>Hạng mục theo danh mục cũ; null hoặc 0 = không có (dòng phải gắn bộ phận thay vào đó)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintLinkModel.TruckComponentId">
            <summary>
            Bộ phận trên xe mà dòng công việc này chạm tới. Null = dòng không gắn bộ phận
            (dữ liệu lịch sử, hoặc màn cũ chưa gửi trường này).
            </summary>
            <remarks>
            <b>Null nghĩa là "không nhắc tới", không phải "hãy xoá".</b> Màn cũ
            <c>/bao-tri-xe-tai</c> không gửi ba trường mới của dòng công việc — nợ BD-8 chính là
            việc luồng lưu cũ hiểu nhầm sự vắng mặt này thành lệnh xoá.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintLinkModel.ActionType">
            <summary>
            Hành động lên bộ phận: thay mới / đảo vị trí / sửa / kiểm tra. Null = không nhắc tới.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintLinkModel.LineCost">
            <summary>
            Chi phí riêng của dòng công việc. Null = không nhắc tới.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintLinkModel.ClearTruckComponentId">
            <summary>
            Gỡ bộ phận khỏi dòng đã lưu (kéo theo gỡ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintLinkModel.ActionType"/>) và tính lại mốc lắp của bộ phận
            vừa gỡ. Cần cờ riêng vì <c>TruckComponentId = null</c> nghĩa là "không nhắc tới" (BD-8) — không có
            cờ này thì dòng "Thay mới" gắn nhầm bộ phận không gỡ được, mốc lắp đã reset nằm sai mãi
            (finding review GĐ E). Cùng họ với <c>ClearGarageId</c>/<c>ClearOdo</c> của bản ghi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintLinkModel.ClearActionType">
            <summary>Gỡ hành động khỏi dòng đã lưu (giữ bộ phận); mốc lắp của bộ phận được tính lại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.LicensePlate">
            <summary>
            Biển số xe (bắt buộc, tối đa 20 ký tự)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.Brand">
            <summary>
            Thương hiệu xe tải (ví dụ: "Kia", "Hyundai", "Isuzu")
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.Model">
            <summary>
            Model xe tải (ví dụ: "K200", "Porter", "D-Max")
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.AgencyId">
            <summary>
            ID chi nhánh mà xe tải thuộc về
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.MaxPayload">
            <summary>
            Tải trọng tối đa cho phép (tấn)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.CargoLength">
            <summary>
            Chiều dài khu vực chứa hàng (cm)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.CargoWidth">
            <summary>
            Chiều rộng khu vực chứa hàng (cm)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.CargoHeight">
            <summary>
            Chiều cao khu vực chứa hàng (cm)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.OperatingStatus">
            <summary>
            Trạng thái vận hành hiện tại (Running/Stop)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.Status">
            <summary>
            Trạng thái xe tải (Normal/Broken/Maintenance/etc)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.CurrentDriverId">
            <summary>
            ID tài xế hiện đang phụ trách xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.ManufacturingYear">
            <summary>
            Năm sản xuất của xe tải
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.RegistrationInfo">
            <summary>
            Thông tin đăng kiểm (tối đa 200 ký tự)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.FuelQuotaPer100Km">
            <summary>
            Định mức khoán xăng dầu (lít/100km)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.Files">
            <summary>
            Danh sách file ảnh upload mới
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.MediaTypes">
            <summary>
            Loại media tương ứng với từng file (RegistrationPhoto, InspectionPhoto)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel.ExistingMediaIds">
            <summary>
            Danh sách ID TruckMedia hiện có cần giữ lại (khi cập nhật).
            ID = 0 nghĩa là vị trí đó cần upload file mới.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.ChangePasswordModel">
            <summary>
            Model để đổi mật khẩu của người dùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.ChangePasswordModel.UserId">
            <summary>
            ID của người dùng cần đổi mật khẩu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.ChangePasswordModel.CurrentPassword">
            <summary>
            Mật khẩu hiện tại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.ChangePasswordModel.NewPassword">
            <summary>
            Mật khẩu mới
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.ChangePasswordModel.ConfirmNewPassword">
            <summary>
            Xác nhận mật khẩu mới
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.ChangePasswordModel.UpdatedBy">
            <summary>
            ID người cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.ChangePasswordModel.UpdatedByUserName">
            <summary>
            Tên người cập nhật
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.CreateCustomerAccountModel">
            <summary>
            Thông tin tạo tài khoản đăng nhập kiểu khách hàng.
            </summary>
            <remarks>
            Thông tin nhân thân (họ tên, email, số điện thoại, địa chỉ) do tầng gọi lấy từ hồ sơ
            khách hàng, KHÔNG lấy từ request — người quản trị chỉ được đặt tên đăng nhập và mật khẩu.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.RegisterModel.AgencyId">
            <summary>
            Mã đại lý của người dùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.RegisterModel.AttendanceCode">
            <summary>
            Mã chấm công (khớp với máy chấm công vân tay)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.SetPasswordModel.UpdatedBy">
            <summary>
            ID người cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.SetPasswordModel.UpdatedByUserName">
            <summary>
            Tên người cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.StaffModel.ManagerId">
            <summary>
            ID người quản lý trực tiếp (từ UserPreference.ManagerId)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.StaffModel.ManagerName">
            <summary>
            Tên người quản lý trực tiếp (readonly, để hiển thị)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.StaffModel.ManagerUserName">
            <summary>
            Tên đăng nhập người quản lý trực tiếp (readonly, để hiển thị)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.StaffModel.DataAccessScope">
            <summary>
            Phạm vi truy cập dữ liệu (0=SelfOnly, 10=ManagedTeam, 20=All)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.StaffModel.SalaryAdvance">
            <summary>
            Số tiền tạm ứng lương hiện tại trong tháng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.StaffModel.ResponsibilityDepositLimit">
            <summary>
            Tổng hạn mức cọc trách nhiệm yêu cầu của lái xe (tối đa 5,000,000 đ)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.StaffModel.ResponsibilityDepositPaid">
            <summary>
            Số tiền cọc trách nhiệm đã đóng lũy kế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.StaffModel.ResponsibilityDepositMonthly">
            <summary>
            Số tiền cọc trách nhiệm cấn trừ hàng tháng qua lương
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Users.StaffModel.AttendanceCode">
            <summary>
            Mã chấm công (khớp với mã máy chấm công vân tay khi import)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Profiles.AdsMappingProfile">
            <summary>
            Ánh xạ cho module quảng cáo đa nền tảng.
            Nguyên tắc bảo mật: mọi credential đều đi qua <see cref="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.AdsMappingProfile.MaskSecret(System.String)"/> — DTO không bao giờ mang giá trị gốc.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.AdsMappingProfile.MaskSecret(System.String)">
            <summary>
            Che thông tin mật để trả ra API: giữ 4 ký tự đầu và 4 ký tự cuối.
            Chuỗi quá ngắn thì che hoàn toàn — thà mất tiện lợi hơn để lộ credential.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.AdsMappingProfile.ParseTexts(System.String)">
            <summary>
            Đọc mảng text lưu dạng JSON trong entity. JSON hỏng thì trả danh sách rỗng
            thay vì ném lỗi — một bản ghi lỗi không nên làm sập cả trang danh sách.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.AdsMappingProfile.FormatDayOfWeek(System.DayOfWeek)">
            <summary>
            Thứ trong tuần sang tiếng Việt. Không dùng CultureInfo("vi-VN") vì .NET trả
            "Thứ Hai" ở dạng khác nhau tuỳ phiên bản ICU của máy chủ — bảng cứng cho kết quả ổn định.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.AdsMappingProfile.FormatTimeRange(System.Int32,System.Int32,System.Int32,System.Int32)">
            <summary>
            Khoảng giờ dạng "08:00 – 17:00". Giờ kết thúc 24 giữ nguyên là "24:00"
            (Google dùng 24 nghĩa là hết ngày) — đổi thành 00:00 sẽ đọc thành nửa đêm hôm trước.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.AdsMappingProfile.FormatBidModifierPercent(System.Nullable{System.Decimal})">
            <summary>
            Hệ số giá thầu của Google sang phần trăm để hiển thị:
            1,2 → "+20%"; 0,5 → "-50%"; 1,0 → "0%"; 0,0 → "-100%"; null → "—".
            <para>
            null và 0 là hai chuyện khác nhau: null = nền tảng không đặt điều chỉnh,
            0 = đặt -100%. Gộp lại sẽ hiển thị sai hoàn toàn ý định của người đặt lịch.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.AdsMappingProfile.FormatApprovalStatus(System.String)">
            <summary>
            Trạng thái duyệt của nền tảng sang tiếng Việt. Giá trị lạ thì <b>giữ nguyên chuỗi gốc</b>
            chứ không đoán thành "Đã duyệt" — nói sai chỗ này là để quảng cáo bị từ chối trông như
            đang chạy bình thường.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.AdsMappingProfile.FormatKeywordDisplayText(System.String,Lada.Framework.Data.Enums.AdsKeywordMatchType)">
            <summary>
            Nội dung từ khoá kèm ký hiệu kiểu khớp theo đúng cách Google Ads hiển thị:
            khớp chính xác là <c>[từ khoá]</c>, khớp cụm từ là <c>"từ khoá"</c>, khớp rộng để trần.
            Ký hiệu này là quy ước người chạy quảng cáo đọc quen — hiển thị trần hết sẽ làm ba
            kiểu khớp trông giống nhau.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.AdsMappingProfile.FormatCpcBid(System.Nullable{System.Decimal})">
            <summary>
            Giá thầu riêng của từ khoá. <c>null</c> hiển thị "theo nhóm" chứ không để trống:
            ô trống đọc thành "không có giá thầu", còn thực tế là dùng giá thầu của nhóm.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Profiles.AdsMappingExtensions">
            <summary>
            Các hàm mở rộng ánh xạ cho module quảng cáo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.AiMappingProfile.MaskApiKey(System.String)">
            <summary>
            Chỉ nói có key hay chưa và đã mã hoá chưa — không in ký tự nào của key (bản cũ in 4 ký tự đầu + 4 ký tự cuối của
            bản rõ). Form sửa không gửi lại chuỗi này (mở form là ô key trống — <c>ProviderModal.vue</c>).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Profiles.BankMappingExtensions">
            <summary>
            Extension methods cho mapping Bank entities
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.BankMappingExtensions.ToItem(Lada.Framework.Data.Domains.Finance.BankAccount)">
            <summary>
            Convert BankAccount entity sang BankAccountItem
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.BankMappingExtensions.ToItem(Lada.Framework.Data.Domains.Finance.BankTransaction)">
            <summary>
            Convert BankTransaction entity sang BankTransactionItem
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.BankMappingExtensions.ToItem(Lada.Framework.Data.Domains.Finance.BankStatementImport)">
            <summary>
            Convert BankStatementImport entity sang BankStatementImportItem
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.BankMappingExtensions.ToItem(Lada.Framework.Data.Domains.Finance.Bank)">
            <summary>
            Convert Bank entity sang BankItem
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.BankMappingExtensions.ToModel(Lada.Framework.Data.Domains.Finance.Bank)">
            <summary>
            Convert Bank entity sang BankModel
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.BankMappingExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.BankModel)">
            <summary>
            Convert BankModel sang Bank entity
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.BankMappingExtensions.ToOptionItem(Lada.Framework.Data.Domains.Finance.Bank)">
            <summary>
            Convert Bank entity sang BankOptionItem
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.BankMappingExtensions.FormatFileSize(System.Int64)">
            <summary>
            Format file size
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Profiles.ContentStoreMappingProfile">
            <summary>
            Ánh xạ entity kho nội dung AI → DTO. Các cột *Json của bài (AltTitles, Brief, Faq, Footer, SelfScore…)
            và hai collection ô/ảnh được <b>Ignore</b> ở đây — service tự parse và sắp thứ tự, để profile không
            giấu lỗi JSON và không phụ thuộc Include. Mapping chạy in-memory nên gọi được
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreJson"/> trong MapFrom (TextOnImage của ảnh).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Profiles.ContentStoreMappingExtensions">
            <summary>Extension ánh xạ cho miền kho nội dung — theo quy ước <c>.ToItem()</c> của repo.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.ContentStoreMappingExtensions.ToDetailModel(Lada.Framework.Data.Domains.ContentStore.ContentArticle)">
            <summary>Bản đầy đủ chưa có phần JSON/ô/ảnh — service gọi rồi điền tiếp.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Profiles.EmailMappingProfile">
            <summary>
            AutoMapper profile cho domain Email (tài khoản gửi + nhật ký).
            Lưu ý: secret (Password/SecretKey) KHÔNG map ra Item — chỉ suy ra cờ Has*.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Profiles.EmailMappingExtensions">
            <summary>
            Extension mapping tiện dụng (giống CrmMappingExtensions).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.FinanceMappingProfile.GetExpenseStatusDisplay(System.Nullable{Lada.Framework.Data.Enums.ExpenseStatus})">
            <summary>
            Lấy tên hiển thị của trạng thái chi phí
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Profiles.TransactionMappingHelpers">
            <summary>
            Helper methods cho Transaction mapping
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.TransactionMappingHelpers.GetTransactionIcon(Lada.Framework.Data.Enums.TransactionType)">
            <summary>
            Lấy icon cho loại giao dịch
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.TransactionMappingHelpers.GetShortDescription(Lada.Framework.Data.Domains.Finance.Wallets.Transaction)">
            <summary>
            Tạo mô tả ngắn gọn cho giao dịch
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Profiles.FuelCardMappingProfile">
            <summary>
            Extension methods để map giữa FuelCard entities và items
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.FuelCardMappingProfile.ToItem(Lada.Framework.Data.Domains.Finance.FuelCardTransaction)">
            <summary>
            Chuyển đổi FuelCardTransaction entity sang FuelCardTransactionItem
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Profiles.GoodsCategoryMappingExtensions">
            <summary>
            Extension ánh xạ cho cấu hình danh mục hàng hóa động
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Profiles.GoodsCategoryMappingProfile">
            <summary>
            Mapping cho cấu hình danh mục hàng hóa động
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Profiles.InternalNewsMappingProfile">
            <summary>
            Ánh xạ Bảng tin nội bộ. Trường tính theo người xem (đã đọc, tên tác giả, đang ghim theo giờ hiện tại) do service
            điền sau khi ánh xạ — profile chỉ chép cột.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Profiles.InternalNewsMappingExtensions.ApplyTo(Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsPostModel,Lada.Framework.Data.Domains.InternalNews.InternalNewsPost)">
            <summary>Chép các trường người soạn được sửa vào bài đang có (hoặc bài mới).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Profiles.TruckMappingProfile">
            <summary>
            AutoMapper profile cho các ánh xạ liên quan đến Truck.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateItem">
            <summary>
            Item báo cáo đổ dầu thực tế theo ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateItem.RefillDate">
            <summary>
            Ngày đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateItem.TotalRefillCount">
            <summary>
            Số lần đổ dầu trong ngày (số phiếu)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateItem.TotalDistanceKm">
            <summary>
            Tổng số km chạy trong ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateItem.TotalActualLiters">
            <summary>
            Số lít đổ dầu thực tế trong ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateItem.TotalActualAmount">
            <summary>
            Số tiền đổ dầu thực tế trong ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateItem.AvgUnitPrice">
            <summary>
            Đơn giá bình quân gia quyền trong ngày (tổng tiền / tổng lít)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateItem.TotalCardAmount">
            <summary>
            Tiền đổ bằng thẻ trong ngày (PaymentMethod = Card)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateItem.TotalCashAmount">
            <summary>
            Tiền đổ bằng tiền mặt trong ngày (PaymentMethod = Cash)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateItem.Details">
            <summary>
            Chi tiết theo lái xe và xe trong ngày
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateDetailItem">
            <summary>
            Chi tiết đổ dầu thực tế theo lái xe và xe trong 1 ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateDetailItem.DriverId">
            <summary>
            ID lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateDetailItem.DriverUserName">
            <summary>
            Tên đăng nhập lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateDetailItem.DriverFullName">
            <summary>
            Họ và tên lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateDetailItem.TruckId">
            <summary>
            ID xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateDetailItem.TruckPlate">
            <summary>
            Biển số xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateDetailItem.TruckName">
            <summary>
            Tên xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateDetailItem.Status">
            <summary>
            Trạng thái phiếu đổ dầu (0: Pending, 1: Approved, 2: Rejected)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateDetailItem.TotalRefillCount">
            <summary>
            Số lần đổ dầu (số phiếu)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateDetailItem.TotalDistanceKm">
            <summary>
            Số km chạy
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateDetailItem.TotalActualLiters">
            <summary>
            Số lít đổ dầu thực tế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateDetailItem.TotalActualAmount">
            <summary>
            Số tiền đổ dầu thực tế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateDetailItem.AvgUnitPrice">
            <summary>
            Đơn giá bình quân gia quyền (tổng tiền / tổng lít)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateDetailItem.TotalCardAmount">
            <summary>
            Tiền đổ bằng thẻ (PaymentMethod = Card)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDateDetailItem.TotalCashAmount">
            <summary>
            Tiền đổ bằng tiền mặt (PaymentMethod = Cash)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDriverItem">
            <summary>
            Item báo cáo đổ dầu thực tế theo lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDriverItem.DriverId">
            <summary>
            ID lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDriverItem.DriverUserName">
            <summary>
            Tên đăng nhập lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDriverItem.DriverFullName">
            <summary>
            Họ và tên lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDriverItem.TotalRefillCount">
            <summary>
            Số lần đổ dầu (số phiếu)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDriverItem.TotalDistanceKm">
            <summary>
            Số km chạy trong tháng (tổng DistanceKm)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDriverItem.TotalActualLiters">
            <summary>
            Số lít đổ dầu thực tế (tổng ActualLiters)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDriverItem.TotalActualAmount">
            <summary>
            Số tiền đổ dầu thực tế (tổng Amount)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDriverItem.AvgUnitPrice">
            <summary>
            Đơn giá bình quân gia quyền (tổng tiền / tổng lít)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDriverItem.TotalCardAmount">
            <summary>
            Tiền đổ bằng thẻ (PaymentMethod = Card)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDriverItem.TotalCashAmount">
            <summary>
            Tiền đổ bằng tiền mặt (PaymentMethod = Cash)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByDriverItem.TruckDetails">
            <summary>
            Chi tiết số liệu theo từng xe mà lái xe đã chạy
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckItem">
            <summary>
            Item chi tiết đổ dầu thực tế theo xe (dùng trong báo cáo theo lái xe)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckItem.TruckId">
            <summary>
            ID xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckItem.TruckPlate">
            <summary>
            Biển số xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckItem.TruckName">
            <summary>
            Tên xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckItem.TotalRefillCount">
            <summary>
            Số lần đổ dầu (số phiếu)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckItem.TotalDistanceKm">
            <summary>
            Số km chạy trong khoảng thời gian (tổng DistanceKm)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckItem.TotalActualLiters">
            <summary>
            Số lít đổ dầu thực tế (tổng ActualLiters)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckItem.TotalActualAmount">
            <summary>
            Số tiền đổ dầu thực tế (tổng Amount)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckItem.AvgUnitPrice">
            <summary>
            Đơn giá bình quân gia quyền (tổng tiền / tổng lít)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckItem.TotalCardAmount">
            <summary>
            Tiền đổ bằng thẻ (PaymentMethod = Card)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckItem.TotalCashAmount">
            <summary>
            Tiền đổ bằng tiền mặt (PaymentMethod = Cash)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckSummaryItem">
            <summary>
            Item báo cáo tổng hợp đổ dầu thực tế theo xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckSummaryItem.TruckId">
            <summary>
            ID xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckSummaryItem.TruckPlate">
            <summary>
            Biển số xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckSummaryItem.TruckName">
            <summary>
            Tên xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckSummaryItem.TotalRefillCount">
            <summary>
            Số lần đổ dầu (số phiếu)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckSummaryItem.TotalDistanceKm">
            <summary>
            Số km chạy (tổng DistanceKm)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckSummaryItem.TotalActualLiters">
            <summary>
            Số lít đổ dầu thực tế (tổng ActualLiters)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckSummaryItem.TotalActualAmount">
            <summary>
            Số tiền đổ dầu thực tế (tổng Amount)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckSummaryItem.AvgUnitPrice">
            <summary>
            Đơn giá bình quân gia quyền (tổng tiền / tổng lít)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckSummaryItem.TotalCardAmount">
            <summary>
            Tiền đổ bằng thẻ (PaymentMethod = Card)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckSummaryItem.TotalCashAmount">
            <summary>
            Tiền đổ bằng tiền mặt (PaymentMethod = Cash)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckSummaryItem.DriverDetails">
            <summary>
            Chi tiết số liệu theo từng lái xe đã đổ dầu cho xe này
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckDriverDetailItem">
            <summary>
            Item chi tiết đổ dầu thực tế theo lái xe (dùng trong báo cáo theo xe)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckDriverDetailItem.DriverId">
            <summary>
            ID lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckDriverDetailItem.DriverUserName">
            <summary>
            Tên đăng nhập lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckDriverDetailItem.DriverFullName">
            <summary>
            Họ và tên lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckDriverDetailItem.TotalRefillCount">
            <summary>
            Số lần đổ dầu (số phiếu)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckDriverDetailItem.TotalDistanceKm">
            <summary>
            Số km chạy (tổng DistanceKm)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckDriverDetailItem.TotalActualLiters">
            <summary>
            Số lít đổ dầu thực tế (tổng ActualLiters)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckDriverDetailItem.TotalActualAmount">
            <summary>
            Số tiền đổ dầu thực tế (tổng Amount)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckDriverDetailItem.AvgUnitPrice">
            <summary>
            Đơn giá bình quân gia quyền (tổng tiền / tổng lít)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckDriverDetailItem.TotalCardAmount">
            <summary>
            Tiền đổ bằng thẻ (PaymentMethod = Card)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.FuelCards.FuelRefillReportByTruckDriverDetailItem.TotalCashAmount">
            <summary>
            Tiền đổ bằng tiền mặt (PaymentMethod = Cash)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.AgencyRevenueStatisticsItem">
            <summary>
            Một dòng doanh số của một bưu cục bán hàng — kết quả <c>sp_GetAgencyRevenueStatistics</c>.
            </summary>
            <remarks>
            "Bưu cục bán hàng" là <c>Order.SaleAgencyId</c> (bưu cục của sale, đóng dấu lúc tạo đơn),
            không phải bưu cục vận hành đơn. Xem chú thích ngữ nghĩa đầy đủ trong chính file SP.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.AgencyRevenueStatisticsItem.AgencyId">
            <summary>
            ID bưu cục bán hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.AgencyRevenueStatisticsItem.OrderCount">
            <summary>
            Số đơn tính vào doanh số của bưu cục trong khoảng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.AgencyRevenueStatisticsItem.TotalRevenue">
            <summary>
            Tổng cước sau VAT (<c>OrderFin.TotalFeeAfterVat</c>, SP cộng tay 7 thành phần)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityGroupItem">
            <summary>
            Item nhóm báo cáo năng suất lái xe (chứa tổng và chi tiết từng ngày)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityGroupItem.DriverId">
            <summary>
            ID lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityGroupItem.DriverUserName">
            <summary>
            Tên đăng nhập lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityGroupItem.DriverFullName">
            <summary>
            Tên đầy đủ lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityGroupItem.PickupCount">
            <summary>
            Tổng số lượng đơn hàng lấy hàng trong khoảng thời gian
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityGroupItem.DeliveryCount">
            <summary>
            Tổng số lượng đơn hàng giao hàng trong khoảng thời gian
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityGroupItem.TotalCount">
            <summary>
            Tổng số lượng đơn hàng trong khoảng thời gian
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityGroupItem.DailyDetails">
            <summary>
            Chi tiết theo từng ngày
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityReportByDateItem">
            <summary>
            Item báo cáo năng suất lái xe theo ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityReportByDateItem.DriverId">
            <summary>
            ID lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityReportByDateItem.DriverUserName">
            <summary>
            Tên đăng nhập lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityReportByDateItem.DriverFullName">
            <summary>
            Tên đầy đủ lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityReportByDateItem.ActivityDate">
            <summary>
            Ngày hoạt động
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityReportByDateItem.PickupCount">
            <summary>
            Số lượng đơn hàng lấy hàng trong ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityReportByDateItem.DeliveryCount">
            <summary>
            Số lượng đơn hàng giao hàng trong ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityReportByDateItem.TotalCount">
            <summary>
            Tổng số lượng đơn hàng trong ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityReportByDateItem.DayOfWeek">
            <summary>
            Tên ngày trong tuần
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityReportByDateItem.FromDate">
            <summary>
            Thời gian bắt đầu (từ tham số)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityReportByDateItem.ToDate">
            <summary>
            Thời gian kết thúc (từ tham số)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem">
            <summary>
            Bản ghi báo cáo doanh số theo khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.CustomerId">
            <summary>
            ID của khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.CustomerCode">
            <summary>
            Mã khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.CustomerPhone">
            <summary>
            Số điện thoại khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.ManagerId">
            <summary>
            ID Sale quản lý khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.ManagerName">
            <summary>
            Tên Sale quản lý khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.TotalOrders">
            <summary>
            Tổng số đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.TotalRevenue">
            <summary>
            Tổng doanh số
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.TotalCollectAmount">
            <summary>
            Tổng tiền thu hộ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.TotalRecords">
            <summary>
            Tổng số bản ghi (dùng cho phân trang)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.IsTotalRow">
            <summary>
            Kiểm tra có phải dòng tổng cộng không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.TotalInProgress">
            <summary>
            Tổng số đơn đang xử lý (chưa hoàn thành)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.TotalFailed">
            <summary>
            Tổng số đơn thất bại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.TotalCompleted">
            <summary>
            Tổng số đơn hoàn thành
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.SuccessRate">
            <summary>
            Tỷ lệ thành công (%)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.TotalInProgressRevenue">
            <summary>
            Tổng doanh số đơn đang xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.TotalFailedRevenue">
            <summary>
            Tổng doanh số đơn thất bại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.TotalCompletedRevenue">
            <summary>
            Tổng doanh số đơn hoàn thành
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.TotalInProgressCollectAmount">
            <summary>
            Tổng tiền thu hộ đơn đang xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.TotalFailedCollectAmount">
            <summary>
            Tổng tiền thu hộ đơn thất bại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.CustomerRevenueItem.TotalCompletedCollectAmount">
            <summary>
            Tổng tiền thu hộ đơn hoàn thành
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogDetailItem">
            <summary>
            Chi tiết đơn hàng tồn đọng (drill-down từ bảng tổng hợp)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogDetailItem.OrderId">
            <summary>
            ID đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogDetailItem.OrderCode">
            <summary>
            Mã đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogDetailItem.Status">
            <summary>
            Trạng thái đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogDetailItem.PhysicalStatus">
            <summary>
            Trạng thái vật lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogDetailItem.StatusContent">
            <summary>
            Nội dung trạng thái (mô tả)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogDetailItem.UpdatedTime">
            <summary>
            Thời gian cập nhật lần cuối
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogDetailItem.DaysAgo">
            <summary>
            Số ngày tồn đọng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogDetailItem.TotalRecord">
            <summary>
            Tổng số bản ghi (dùng cho phân trang)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem">
            <summary>
            DTO chứa thống kê tồn đọng đơn hàng theo trạng thái và thời gian
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.AgencyId">
            <summary>
            Mã bưu cục (dùng cho phân nhóm theo Agency)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.AgencyName">
            <summary>
            Tên bưu cục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.StatusGroup">
            <summary>
            Tên nhóm trạng thái (VD: "Tạo mới", "Đang lấy hàng", ...)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.StatusOrder">
            <summary>
            Thứ tự sắp xếp trạng thái
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.D0">
            <summary>
            Số đơn cập nhật hôm nay (0 ngày trước)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.D1">
            <summary>
            Số đơn cập nhật 1 ngày trước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.D2">
            <summary>
            Số đơn cập nhật 2 ngày trước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.D3">
            <summary>
            Số đơn cập nhật 3 ngày trước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.D4">
            <summary>
            Số đơn cập nhật 4 ngày trước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.D5">
            <summary>
            Số đơn cập nhật 5 ngày trước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.D6">
            <summary>
            Số đơn cập nhật 6 ngày trước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.D7">
            <summary>
            Số đơn cập nhật 7 ngày trước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.D7Plus">
            <summary>
            Số đơn cập nhật trên 7 ngày trước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.Total">
            <summary>
            Tổng số đơn theo trạng thái
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.FeeD0">
            <summary>Tổng cước D0</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.FeeD1">
            <summary>Tổng cước D1</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.FeeD2">
            <summary>Tổng cước D2</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.FeeD3">
            <summary>Tổng cước D3</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.FeeD4">
            <summary>Tổng cước D4</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.FeeD5">
            <summary>Tổng cước D5</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.FeeD6">
            <summary>Tổng cước D6</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.FeeD7">
            <summary>Tổng cước D7</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.FeeD7Plus">
            <summary>Tổng cước D7+</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderBacklogItem.FeeTotal">
            <summary>Tổng cước tất cả</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderProductionItem">
            <summary>
            Bản ghi báo cáo sản lượng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderProductionItem.OrderDateStr">
            <summary>
            Chuỗi hiển thị ngày, nếu là ngày tổng hợp thì hiển thị "TỔNG CỘNG"
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderProductionItem.IsTotalRow">
            <summary>
            Kiểm tra xem có phải là dòng tổng cộng không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderProductionItem.TotalInProgress">
            <summary>
            Tổng số đơn đang xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderProductionItem.TotalFailed">
            <summary>
            Tổng số đơn thất bại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderProductionItem.TotalCompleted">
            <summary>
            Tổng số đơn hoàn thành
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderProductionItem.SuccessRate">
            <summary>
            Tỷ lệ thành công
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderReportByRouteItem">
            <summary>
            DTO cho báo cáo số lượng đơn và doanh số theo tuyến
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderReportByRouteItem.RouteName">
            <summary>
            Tên tuyến (Tỉnh/Thành gửi - Tỉnh/Thành nhận)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderReportByRouteItem.SourceCityName">
            <summary>
            Tên tỉnh/thành phố gửi hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderReportByRouteItem.DestCityName">
            <summary>
            Tên tỉnh/thành phố nhận hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderReportByRouteItem.OrderStatusName">
            <summary>
            Tên trạng thái đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderReportByRouteItem.StatusOrder">
            <summary>
            Thứ tự sắp xếp trạng thái (1-6)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderReportByRouteItem.OrderCount">
            <summary>
            Số lượng đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderReportByRouteItem.TotalRevenue">
            <summary>
            Tổng doanh số
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderReportByRouteItem.AvgRevenue">
            <summary>
            Doanh số trung bình
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderReportByRouteItem.MinRevenue">
            <summary>
            Doanh số thấp nhất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderReportByRouteItem.MaxRevenue">
            <summary>
            Doanh số cao nhất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderReportByRouteItem.FromDate">
            <summary>
            Ngày bắt đầu lọc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderReportByRouteItem.ToDate">
            <summary>
            Ngày kết thúc lọc
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByAgencyItem">
            <summary>
            Một dòng báo cáo doanh số theo bưu cục (<c>sp_GetOrderRevenueByAgency</c>). Bưu cục của đơn =
            <c>Order.SaleAgencyId</c> — bưu cục của sale lúc tạo đơn, cùng trục với KPI <c>agency.revenue</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByAgencyItem.AgencyId">
            <summary>Id bưu cục.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByAgencyItem.AgencyCode">
            <summary>Mã bưu cục.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByAgencyItem.AgencyName">
            <summary>Tên bưu cục.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByAgencyItem.AgencyIsDeleted">
            <summary>
            Bưu cục đã xoá mềm — service điền, không phải cột SP. Founder/kế toán vẫn thấy dòng này để tổng báo cáo
            bằng tổng KPI (plan §6.3, DS-7); giao diện gắn nhãn "(đã ngừng)".
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem">
            <summary>
            Bản ghi báo cáo doanh thu đơn hàng theo ngày nhận tiền (Collection Date)
            Chỉ bao gồm thống kê tài chính (không có thống kê trạng thái triển khai)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem.CollectionDate">
            <summary>
            Ngày công ty nhận tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem.CollectionDateStr">
            <summary>
            Chuỗi hiển thị ngày, nếu là ngày tổng hợp thì hiển thị "TỔNG CỘNG"
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem.TotalOrders">
            <summary>
            Tổng số đơn (trừ hủy)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem.TotalRevenue">
            <summary>
            Tổng doanh thu (trừ hủy)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem.UnpaidOrders">
            <summary>
            Số đơn chưa thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem.UnpaidRevenue">
            <summary>
            Doanh thu chưa thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem.WaitingConfirmationOrders">
            <summary>
            Số đơn chờ xác nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem.WaitingConfirmationRevenue">
            <summary>
            Doanh thu chờ xác nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem.PaidOrders">
            <summary>
            Số đơn đã thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem.PaidRevenue">
            <summary>
            Doanh thu đã thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem.RecognizedRevenue">
            <summary>
            Doanh thu ghi nhận (đã trừ VAT 8%)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem.IsTotalRow">
            <summary>
            Kiểm tra xem có phải là dòng tổng cộng không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem.PaymentRate">
            <summary>
            Tỷ lệ thanh toán (%)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem.UnpaidRate">
            <summary>
            Tỷ lệ chưa thanh toán (%)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem.WaitingConfirmationRate">
            <summary>
            Tỷ lệ chờ xác nhận (%)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueBySaleItem">
            <summary>
            Bản ghi báo cáo doanh thu theo Sale (chỉ thống kê tài chính)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueBySaleItem.SaleId">
            <summary>
            ID nhân viên sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueBySaleItem.SaleName">
            <summary>
            Tên nhân viên sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueBySaleItem.SaleUserName">
            <summary>
            Tên đăng nhập nhân viên sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueBySaleItem.TotalOrders">
            <summary>
            Tổng số đơn (trừ hủy)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueBySaleItem.TotalRevenue">
            <summary>
            Tổng doanh thu (trừ hủy)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueBySaleItem.UnpaidOrders">
            <summary>
            Số đơn chưa thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueBySaleItem.UnpaidRevenue">
            <summary>
            Doanh thu chưa thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueBySaleItem.WaitingConfirmationOrders">
            <summary>
            Số đơn chờ xác nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueBySaleItem.WaitingConfirmationRevenue">
            <summary>
            Doanh thu chờ xác nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueBySaleItem.PaidOrders">
            <summary>
            Số đơn đã thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueBySaleItem.PaidRevenue">
            <summary>
            Doanh thu đã thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueBySaleItem.RecognizedRevenue">
            <summary>
            Doanh thu ghi nhận (đã trừ VAT 8%)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByTeamItem">
            <summary>
            Một dòng báo cáo doanh số theo nhóm (<c>sp_GetOrderRevenueByTeam</c>). Nhóm của đơn =
            <c>UserPreference.ManagerId</c> của sale tạo đơn — quản lý trực tiếp, không đệ quy.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByTeamItem.ManagerId">
            <summary>Id quản lý trực tiếp; <c>0</c> = dòng "Chưa có quản lý trực tiếp".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByTeamItem.ManagerName">
            <summary>Tên nhóm = họ tên quản lý (SP đã đặt sẵn tên cho dòng 0).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByTeamItem.MemberCount">
            <summary>Số sale <b>có đơn trong kỳ</b> thuộc nhóm — không phải số người dưới quyền.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByWardItem">
            <summary>
            Một dòng báo cáo doanh số theo phường/xã (<c>sp_GetOrderRevenueByWard</c>) của điểm lấy hoặc điểm giao.
            Chỉ nhóm theo xã bộ 2 cấp; địa chỉ hệ cũ gom vào một dòng <c>WardId = 0</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByWardItem.WardId">
            <summary>Id xã 2 cấp; <c>0</c> = "Địa chỉ hệ 3 cấp cũ (chưa quy đổi)".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByWardItem.WardName">
            <summary>Tên xã ("Phường Ba Đình"); SP đã đặt sẵn tên cho dòng 0.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByWardItem.CityName">
            <summary>Tỉnh/thành phố của xã; <c>null</c> ở dòng 0.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByWardItem.CoverageAgencyId">
            <summary>Bưu cục phụ trách vùng phủ (<c>Location.AgencyId</c>); <c>null</c> khi xã chưa có.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByWardItem.CoverageAgencyName">
            <summary>Tên bưu cục phụ trách vùng phủ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueDetailItem">
            <summary>
            Một đơn trong danh sách drill-down của một ô báo cáo doanh số theo chiều (<c>sp_GetOrderRevenueDetail</c>).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueDetailItem.OrderId">
            <summary>Id đơn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueDetailItem.OrderCode">
            <summary>Mã đơn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueDetailItem.CreatedTime">
            <summary>Thời điểm tạo đơn — mốc của kỳ báo cáo.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueDetailItem.Status">
            <summary>Mã <c>OrderStatus</c>; <c>null</c> khi đơn không có dòng <c>OrderOps</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueDetailItem.StatusName">
            <summary>
            Tên trạng thái đơn — mô tả của <see cref="T:Lada.Framework.Data.Enums.OrderStatus"/>, để giao diện không giữ bảng tên riêng. Đơn không
            có dòng <c>OrderOps</c> hoặc mang mã ngoài enum hiện "Không xác định", đúng nhóm mà view xếp chúng vào.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueDetailItem.StatusGroup">
            <summary>Nhóm trạng thái <c>OrderStatusGroup</c> (1–4).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueDetailItem.Revenue">
            <summary>Doanh số của đơn (7 khoản, gồm VAT).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueDetailItem.CustomerName">
            <summary>Tên khách hàng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueDetailItem.SaleName">
            <summary>Tên sale tạo đơn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueDetailItem.AgencyName">
            <summary>Tên bưu cục bán (<c>Order.SaleAgencyId</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueDetailItem.TotalItem">
            <summary>Tổng số đơn của ô (lặp ở mọi dòng, <c>COUNT(*) OVER()</c>) — service chuyển thành <c>TotalRecord</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueItem">
            <summary>
            Bản ghi báo cáo doanh thu đơn hàng theo ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueItem.OrderDateStr">
            <summary>
            Chuỗi hiển thị ngày, nếu là ngày tổng hợp thì hiển thị "TỔNG CỘNG"
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueItem.IsTotalRow">
            <summary>
            Kiểm tra xem có phải là dòng tổng cộng không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueItem.TotalInProgress">
            <summary>
            Tổng số đơn đang xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueItem.TotalFailed">
            <summary>
            Tổng số đơn thất bại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueItem.TotalCompleted">
            <summary>
            Tổng số đơn hoàn thành
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueItem.SuccessRate">
            <summary>
            Tỷ lệ thành công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueItem.TotalInProgressRevenue">
            <summary>
            Tổng doanh số đơn đang xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueItem.TotalFailedRevenue">
            <summary>
            Tổng doanh số đơn thất bại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueItem.TotalCompletedRevenue">
            <summary>
            Tổng doanh số đơn hoàn thành
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueItem.TotalInProgressCollectAmount">
            <summary>
            Tổng tiền thu hộ đơn đang xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueItem.TotalFailedCollectAmount">
            <summary>
            Tổng tiền thu hộ đơn thất bại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueItem.TotalCompletedCollectAmount">
            <summary>
            Tổng tiền thu hộ đơn hoàn thành
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueStatusAmounts">
            <summary>
            Bốn cặp (số đơn, doanh số) theo nhóm trạng thái <c>OrderStatusGroup</c> + tổng — phần chung của mọi dòng
            báo cáo doanh số theo chiều (bưu cục / nhóm / phường xã) và của dòng tổng cộng.
            </summary>
            <remarks>
            Tên property trùng tên cột của <c>sp_GetOrderRevenueBy*</c> để Dapper ánh xạ thẳng. Doanh số = 7 khoản
            <c>OrderFin</c> (đúng <c>TotalFeeAfterVat</c>, gồm VAT), tính theo ngày tạo đơn — công thức nằm duy nhất ở
            view <c>vw_OrderRevenueFact</c> (plan-bao-cao-doanh-so-theo-chieu §3.1).
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueStatusAmounts.NewCount">
            <summary>Số đơn nhóm Tạo mới.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueStatusAmounts.NewRevenue">
            <summary>Doanh số nhóm Tạo mới.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueStatusAmounts.InProgressCount">
            <summary>Số đơn nhóm Đang triển khai.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueStatusAmounts.InProgressRevenue">
            <summary>Doanh số nhóm Đang triển khai.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueStatusAmounts.DoneCount">
            <summary>Số đơn nhóm Đã triển khai.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueStatusAmounts.DoneRevenue">
            <summary>Doanh số nhóm Đã triển khai.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueStatusAmounts.CancelledCount">
            <summary>Số đơn nhóm Huỷ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueStatusAmounts.CancelledRevenue">
            <summary>Doanh số nhóm Huỷ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueStatusAmounts.TotalCount">
            <summary>Tổng số đơn của dòng (cả 4 nhóm).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueStatusAmounts.TotalRevenue">
            <summary>Tổng doanh số của dòng (cả 4 nhóm, kể cả Huỷ).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueStatusAmounts.Sum(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueStatusAmounts})">
            <summary>Cộng dồn các dòng thành dòng "Tổng cộng" — SP không trả dòng tổng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleDebtItem">
            <summary>
            Bản ghi báo cáo công nợ theo sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleDebtItem.SaleId">
            <summary>
            ID của sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleDebtItem.SaleName">
            <summary>
            Tên sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleDebtItem.SalePhoneNumber">
            <summary>
            Số điện thoại sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleDebtItem.TotalOrders">
            <summary>
            Tổng số đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleDebtItem.TotalRevenue">
            <summary>
            Tổng doanh số
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleDebtItem.TotalCollected">
            <summary>
            Tổng tiền đã thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleDebtItem.TotalDebt">
            <summary>
            Tổng công nợ (doanh số - đã thu)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleDebtItem.UncollectedOrders">
            <summary>
            Số đơn hàng chưa thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleDebtItem.CollectedOrders">
            <summary>
            Số đơn hàng đã thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleDebtItem.CollectionRate">
            <summary>
            Tỷ lệ thu hộ (%)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleDebtItem.LastUpdated">
            <summary>
            Ngày cập nhật cuối
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem">
            <summary>
            Bản ghi báo cáo doanh thu theo sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.SaleId">
            <summary>
            ID của sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.SaleName">
            <summary>
            Tên sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.SalePhoneNumber">
            <summary>
            Số điện thoại sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.TotalOrders">
            <summary>
            Tổng số đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.TotalRevenue">
            <summary>
            Tổng doanh số
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.TotalCollectAmount">
            <summary>
            Tổng tiền thu hộ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.IsTotalRow">
            <summary>
            Kiểm tra có phải dòng tổng cộng không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.TotalInProgress">
            <summary>
            Tổng số đơn đang xử lý (chưa hoàn thành)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.TotalFailed">
            <summary>
            Tổng số đơn thất bại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.TotalCompleted">
            <summary>
            Tổng số đơn hoàn thành
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.SuccessRate">
            <summary>
            Tỷ lệ thành công (%)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.TotalInProgressRevenue">
            <summary>
            Tổng doanh số đơn đang xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.TotalFailedRevenue">
            <summary>
            Tổng doanh số đơn thất bại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.TotalCompletedRevenue">
            <summary>
            Tổng doanh số đơn hoàn thành
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.TotalInProgressCollectAmount">
            <summary>
            Tổng tiền thu hộ đơn đang xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.TotalFailedCollectAmount">
            <summary>
            Tổng tiền thu hộ đơn thất bại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleRevenueItem.TotalCompletedCollectAmount">
            <summary>
            Tổng tiền thu hộ đơn hoàn thành
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.CustomerArResult">
            <summary>
            Kết quả báo cáo Công nợ phải thu khách hàng
            Tracking cước phí khách hàng nợ chưa trả (PayFeeType = BankTransfer)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.CustomerRevenuePermissionsResult">
            <summary>
            Kết quả quyền truy cập báo cáo doanh thu theo khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.CustomerRevenuePermissionsResult.CanSelectSale">
            <summary>
            User có thể chọn sale để lọc hay không
            true = Founder/Accountant (có thể chọn sale)
            false = Sale (chỉ xem được khách hàng của mình)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.CustomerRevenuePermissionsResult.CanSelectMultipleCustomers">
            <summary>
            User có thể chọn nhiều khách hàng hay không
            true = Founder/Accountant
            false = Sale
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.CustomerRevenueResult">
            <summary>
            Kết quả báo cáo doanh số theo khách hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.DriverProductivityReportByDateResult">
            <summary>
            Kết quả báo cáo năng suất lái xe theo ngày
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.DriverProductivityReportByDateResult.UpdateTotalItem">
            <summary>
            Cập nhật item tổng hợp từ danh sách items
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult">
            <summary>
            Tổng quan tình hình tài chính — Financial Health Overview
            Tổng hợp 12 KPIs: Profitability (5) + Liquidity (5) + Franchise (2)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.TotalRevenue">
            <summary>Tổng doanh thu cước (30 ngày gần nhất)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.TotalVariableCost">
            <summary>Tổng biến phí vận hành (Expense nhóm 6421, Paid)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.TotalFixedCost">
            <summary>Tổng định phí (Expense nhóm 6422 + Lãi vay, Paid)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.InterestExpense">
            <summary>Lãi vay xe (LoanRepaymentSchedule.InterestAmount, Paid)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.GrossProfit">
            <summary>Lợi nhuận gộp = Revenue - Variable Cost</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.GrossMarginPercent">
            <summary>Gross Margin % = GrossProfit / Revenue × 100</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.Ebitda">
            <summary>EBITDA = GrossProfit - FixedCost</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.EbitdaMarginPercent">
            <summary>EBITDA Margin % = EBITDA / Revenue × 100</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.NetProfit">
            <summary>Lợi nhuận ròng ước tính = EBITDA - InterestExpense - Tax(20%)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.NetMarginPercent">
            <summary>Net Margin % = NetProfit / Revenue × 100</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.TotalOrders">
            <summary>Tổng số đơn hàng trong kỳ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.RevenuePerOrder">
            <summary>Doanh thu bình quân mỗi đơn = Revenue / TotalOrders</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.CostPerOrder">
            <summary>Chi phí bình quân mỗi đơn = TotalCost / TotalOrders</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.Dso">
            <summary>DSO — Days Sales Outstanding (đã tính sẵn)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.DsoSlipCount">
            <summary>Số phiếu đối soát dùng tính DSO</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.Dpo">
            <summary>DPO — Days Payable Outstanding = Avg(PaymentsDate - CreatedTime) của Expense</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.FloatPeriod">
            <summary>Float Period — Trung bình ngày chiếm dụng vốn thẻ tín dụng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.CashConversionCycle">
            <summary>Cash Conversion Cycle = DSO - DPO (âm = tốt)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.Dscr">
            <summary>DSCR — Debt Service Coverage Ratio = Operating Cash Flow / Debt Service</summary>
        </member>
        <!-- Badly formed XML comment ignored for member "P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.DscrStatus" -->
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.TotalShortTermDebt">
            <summary>Tổng nợ ngắn hạn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.FuelCardDebt">
            <summary>Nợ thẻ dầu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.LoanPaymentsDue30Days">
            <summary>Nợ vay xe 30 ngày tới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.CodDebt">
            <summary>Nợ COD chưa đối soát</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.OverduePayments">
            <summary>Số khoản trả góp quá hạn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.TotalArOutstanding">
            <summary>Tổng công nợ phải thu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.ArCustomerCount">
            <summary>Số khách hàng đang nợ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.ArOverdue30Days">
            <summary>Nợ quá 30 ngày</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.ArAging">
            <summary>AR Aging breakdown</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.CashInflow30Days">
            <summary>Tổng thu vào 30 ngày</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.CashOutflow30Days">
            <summary>Tổng chi ra 30 ngày</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.NetCashFlow30Days">
            <summary>Dòng tiền ròng 30 ngày</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.WorkingCapital">
            <summary>Vốn lưu động = AR - Short-term Liabilities</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.OverallHealthStatus">
            <summary>Đánh giá tổng thể: Healthy / Warning / Critical</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.HealthScore">
            <summary>Điểm sức khỏe tài chính (0-100)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.Alerts">
            <summary>Danh sách cảnh báo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.PeriodStart">
            <summary>Ngày bắt đầu kỳ phân tích</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FinancialHealthOverviewResult.PeriodEnd">
            <summary>Ngày kết thúc kỳ phân tích</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.HealthAlertItem.Code">
            <summary>Mã cảnh báo (VD: AR-01, LOAN-01)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.HealthAlertItem.Severity">
            <summary>Mức độ: Critical / Warning / Info</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.HealthAlertItem.Message">
            <summary>Nội dung cảnh báo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.HealthAlertItem.Category">
            <summary>Nhóm: AR / Loan / FuelCard / CashFlow / Expense</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelRefillReportByDateResult">
            <summary>
            Kết quả báo cáo đổ dầu theo ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelRefillReportByDateResult.Items">
            <summary>
            Danh sách báo cáo theo từng ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelRefillReportByDateResult.TotalItem">
            <summary>
            Dòng tổng hợp
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelRefillReportByDateResult.TotalRecord">
            <summary>
            Tổng số bản ghi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelRefillReportByDateResult.UpdateTotalItem">
            <summary>
            Cập nhật item tổng hợp từ danh sách items
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelRefillReportByDriverResult">
            <summary>
            Kết quả báo cáo đổ dầu theo lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelRefillReportByDriverResult.Items">
            <summary>
            Danh sách báo cáo theo từng lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelRefillReportByDriverResult.TotalItem">
            <summary>
            Dòng tổng hợp
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelRefillReportByDriverResult.TotalRecord">
            <summary>
            Tổng số bản ghi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelRefillReportByDriverResult.UpdateTotalItem">
            <summary>
            Cập nhật item tổng hợp từ danh sách items
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelRefillReportByTruckResult">
            <summary>
            Kết quả báo cáo đổ dầu thực tế theo xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelRefillReportByTruckResult.Items">
            <summary>
            Danh sách báo cáo theo từng xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelRefillReportByTruckResult.TotalItem">
            <summary>
            Dòng tổng hợp
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelRefillReportByTruckResult.TotalRecord">
            <summary>
            Tổng số bản ghi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelRefillReportByTruckResult.UpdateTotalItem">
            <summary>
            Cập nhật item tổng hợp từ danh sách items
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogAgencyGroup">
            <summary>
            Nhóm thống kê tồn đọng theo bưu cục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogAgencyGroup.AgencyId">
            <summary>
            Mã bưu cục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogAgencyGroup.AgencyName">
            <summary>
            Tên bưu cục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogAgencyGroup.Items">
            <summary>
            Danh sách thống kê theo trạng thái của bưu cục này
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogAgencyGroup.TotalItem">
            <summary>
            Hàng tổng cộng của bưu cục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogAgencyGroup.GrandTotal">
            <summary>
            Tổng đơn hàng tồn đọng của bưu cục
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogByAgencyResult">
            <summary>
            Kết quả thống kê tồn đọng đơn hàng phân nhóm theo Agency
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogByAgencyResult.Agencies">
            <summary>
            Danh sách nhóm theo bưu cục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogByAgencyResult.GrandTotalItem">
            <summary>
            Hàng tổng cộng tất cả bưu cục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogByAgencyResult.GrandTotalItems">
            <summary>
            Danh sách thống kê theo trạng thái của tất cả bưu cục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogByAgencyResult.ShowFee">
            <summary>
            Cho phép hiển thị tổng cước (chỉ Founder mới thấy)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogDetailResult">
            <summary>
            Kết quả chi tiết đơn hàng tồn đọng (drill-down)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogDetailResult.Items">
            <summary>
            Danh sách đơn hàng chi tiết
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogDetailResult.TotalRecord">
            <summary>
            Tổng số bản ghi (dùng cho phân trang)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogResult">
            <summary>
            Kết quả thống kê tồn đọng đơn hàng (Backlog)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogResult.Items">
            <summary>
            Danh sách thống kê theo từng trạng thái
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogResult.TotalItem">
            <summary>
            Hàng tổng cộng (tổng theo cột)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderBacklogResult.ShowFee">
            <summary>
            Cho phép hiển thị tổng cước (chỉ Founder mới thấy)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderProductionResult">
            <summary>
            Kết quả báo cáo sản lượng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderProductionResult.UpdateTotalItem">
            <summary>
            Cập nhật OrderProductionTotalItem dựa trên Items
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderProductionResult.AddItem(Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderProductionItem)">
            <summary>
            Thêm item vào danh sách và tự động cập nhật tổng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderProductionResult.ClearItems">
            <summary>
            Xóa tất cả items và reset tổng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderReportByRouteResult">
            <summary>
            Kết quả báo cáo số lượng đơn và doanh số theo tuyến
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderReportByRouteResult.Items">
            <summary>
            Danh sách báo cáo theo tuyến và trạng thái
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderReportByRouteResult.TotalRecord">
            <summary>
            Tổng số bản ghi
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueByCollectionDateResult">
            <summary>
            Kết quả báo cáo doanh thu đơn hàng theo ngày nhận tiền
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueByCollectionDateResult.UpdateTotalItem">
            <summary>
            Cập nhật TotalItem dựa trên Items
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueByCollectionDateResult.AddItem(Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByCollectionDateItem)">
            <summary>
            Thêm item vào danh sách và tự động cập nhật tổng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueByCollectionDateResult.ClearItems">
            <summary>
            Xóa tất cả items và reset tổng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueBySaleResult">
            <summary>
            Kết quả báo cáo doanh thu theo Sale (chỉ thống kê tài chính)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueBySaleResult.UpdateTotalItem">
            <summary>
            Cập nhật TotalItem dựa trên Items
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueBySaleResult.AddItem(Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueBySaleItem)">
            <summary>
            Thêm item vào danh sách và tự động cập nhật tổng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueBySaleResult.ClearItems">
            <summary>
            Xóa tất cả items và reset tổng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueDetailResult">
            <summary>
            Danh sách đơn của một ô báo cáo doanh số theo chiều (drill-down), một trang.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueDetailResult.Items">
            <summary>Đơn của trang hiện tại, mới nhất trước.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueDetailResult.TotalRecord">
            <summary>Tổng số đơn của ô — bằng số đơn hiện ở ô trên bảng (dùng cho phân trang).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueDimensionResult`1">
            <summary>
            Kết quả một báo cáo doanh số theo chiều (bưu cục / nhóm / phường xã) — dòng đã ép phạm vi người xem
            + dòng tổng cộng tính ở service.
            </summary>
            <typeparam name="TItem">Kiểu dòng của chiều.</typeparam>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueDimensionResult`1.Items">
            <summary>Các dòng, sắp theo tổng doanh số giảm dần (thứ tự của SP).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueDimensionResult`1.Summary">
            <summary>Dòng "Tổng cộng" — 4 cặp + tổng cộng dồn từ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueDimensionResult`1.Items"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueDimensionResult`1.TotalRecord">
            <summary>Số dòng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueDimensionResult`1.FromDate">
            <summary>Đầu kỳ thực dùng — 00:00 giờ Việt Nam của ngày đầu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueDimensionResult`1.ToDate">
            <summary>Cuối kỳ thực dùng — 23:59:59 giờ Việt Nam của ngày cuối.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueExcelFileResult">
            <summary>
            File Excel của báo cáo doanh số theo chiều. Controller trả thẳng byte qua <c>File()</c> với <c>no-store</c> —
            không lưu ra <c>wwwroot</c>, vì doanh số theo bưu cục/nhóm không được nằm ở một URL tải công khai.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueFilterOptionsResult">
            <summary>
            Danh sách cho ô lọc của ba báo cáo doanh số theo chiều — đã ép phạm vi người xem, để giao diện không phải gọi
            danh mục bưu cục / nhân sự toàn cục (plan §3.4).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueFilterOptionsResult.Agencies">
            <summary>Bưu cục trong phạm vi; rỗng khi người xem không có role báo cáo bưu cục/phường xã.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueFilterOptionsResult.Managers">
            <summary>Nhóm (quản lý trực tiếp) trong phạm vi; rỗng khi người xem không có role báo cáo nhóm.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueFilterOptionsResult.Cities">
            <summary>
            Tỉnh/thành phố bộ 2 cấp cho ô lọc của trang phường/xã; rỗng khi người xem không có role báo cáo phường/xã.
            Trả ở đây để trang không phải mượn <c>Location/LoSug</c> — endpoint ấy đòi role của miền địa danh.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueAgencyOption">
            <summary>Một bưu cục trong ô lọc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueAgencyOption.IsDeleted">
            <summary>Bưu cục đã xoá mềm — chỉ Founder/kế toán thấy (plan §6.3).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueAgencyOption.IsRegion">
            <summary>Node khu vực — không bao giờ là một dòng báo cáo; chọn nó = lọc theo mọi bưu cục con cháu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueManagerOption">
            <summary>Một nhóm trong ô lọc; <c>Id = 0</c> là "Chưa có quản lý trực tiếp".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueCityOption">
            <summary>Một tỉnh/thành phố bộ 2 cấp trong ô lọc; <c>Id</c> là giá trị <c>CityId</c> của báo cáo phường/xã.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueResult">
            <summary>
            Kết quả báo cáo doanh thu đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueResult.UpdateTotalItem">
            <summary>
            Cập nhật OrderRevenueTotalItem dựa trên Items
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueResult.AddItem(Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueItem)">
            <summary>
            Thêm item vào danh sách và tự động cập nhật tổng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueResult.ClearItems">
            <summary>
            Xóa tất cả items và reset tổng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.SaleDebtResult">
            <summary>
            Kết quả báo cáo công nợ theo sale
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.SaleDebtResult.UpdateTotalItem">
            <summary>
            Cập nhật item tổng hợp từ danh sách items
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.SaleDebtResult.AddItem(Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.SaleDebtItem)">
            <summary>
            Thêm item vào danh sách và tự động cập nhật tổng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.SaleDebtResult.ClearItems">
            <summary>
            Xóa tất cả items và reset tổng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.SaleRevenueResult">
            <summary>
            Kết quả báo cáo doanh thu theo sale
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.SaleRevenueResult.UpdateTotalItem">
            <summary>
            Cập nhật item tổng hợp từ danh sách items
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.ShortTermLiabilityResult">
            <summary>
            Kết quả báo cáo nợ ngắn hạn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.ShortTermLiabilityResult.GrandTotalLiability">
            <summary>
            Tổng nợ ngắn hạn (tất cả loại)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.ShortTermLiabilityResult.TotalFuelCardDebt">
            <summary>
            Tổng nợ thẻ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.ShortTermLiabilityResult.TotalLoanDue30Days">
            <summary>
            Tổng nợ vay xe sắp đến hạn (30 ngày)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.ShortTermLiabilityResult.TotalLoanDue60Days">
            <summary>
            Tổng nợ vay xe sắp đến hạn (60 ngày)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.ShortTermLiabilityResult.TotalLoanDue90Days">
            <summary>
            Tổng nợ vay xe sắp đến hạn (90 ngày)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.ShortTermLiabilityResult.TotalLoanRemainingPrincipal">
            <summary>
            Tổng dư nợ gốc vay xe còn lại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.ShortTermLiabilityResult.FuelCardDebts">
            <summary>
            Chi tiết nợ theo thẻ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.ShortTermLiabilityResult.UpcomingLoanPayments">
            <summary>
            Chi tiết kỳ trả nợ vay xe sắp tới
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.ShortTermLiabilityResult.TotalCodDebt">
            <summary>
            Tổng nợ COD (đã thu nhưng chưa đối soát cho khách)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.ShortTermLiabilityResult.TotalCodCollected">
            <summary>
            Tổng COD đã thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.ShortTermLiabilityResult.TotalCodFeeDeducted">
            <summary>
            Tổng cước phí trừ đi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.ShortTermLiabilityResult.CodDebtByCustomer">
            <summary>
            Chi tiết nợ COD theo khách hàng (paginated)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelCardDebtItem">
            <summary>
            Chi tiết nợ 1 thẻ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.FuelCardDebtItem.NextPaymentDate">
            <summary>
            Ngày thanh toán tiếp theo (ước tính)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.CodDebtByCustomerItem">
            <summary>
            Chi tiết nợ COD theo khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.CodDebtByCustomerItem.NetDebt">
            <summary>
            Nợ ròng = TotalCollectAmount - TotalFeeAmount
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.LoanPaymentDueItem">
            <summary>
            Chi tiết 1 kỳ trả nợ vay xe sắp tới
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.LoanPaymentDueItem.DaysUntilDue">
            <summary>
            Số ngày còn lại đến hạn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Accounts.LoginResult.IsFounder">
            <summary>
            Flag xác định user có phải Founder hay không (dùng cho UI).
            Không trả về danh sách roles.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Accounts.LoginResult.AgencyId">
            <summary>
            Thông tin chi nhánh của user
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.AppConfig.AppConfigResult">
            <summary>
            Kết quả cho AppConfig operations
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.AppConfig.AppConfigResult.Key">
            <summary>
            Key của AppConfig
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.AppConfig.AppConfigResult.Value">
            <summary>
            Value của AppConfig
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.AppConfig.AppConfigResult.Description">
            <summary>
            Description của AppConfig
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Business.AssignResult.Orders">
            <summary>
            Kết quả TỪNG đơn (Ví bưu cục v2, plan §3.4 "Xuất kho") — chỉ có khi người được gán thuộc chi nhánh bật ví: đơn bị từ chối vì ví
            bưu cục phát không đủ kèm số thiếu, đơn khác vẫn đi. Lô không dính ví giữ hợp đồng cũ (danh sách rỗng).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Business.AssignOrderResult">
            <summary>Một đơn trong lô gán cho bưu cục phát.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Business.AssignOrderResult.WouldBlock">
            <summary>Ví không đủ nhưng công tắc chặn đang tắt — đã đi, đã ghi "sẽ chặn" vào sổ vấn đề.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Business.AssignOrderResult.Required">
            <summary>Số ví phải giữ cho đơn này (cước chính thức / tiền thu hộ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Business.AssignOrderResult.Available">
            <summary>Số dư khả dụng của ví lúc kiểm.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Business.AssignOrderResult.Missing">
            <summary>Thiếu bao nhiêu để xuất được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Business.InboundResult.Orders">
            <summary>Kết quả từng đơn (Ví v2): đơn bị từ chối nhập (thiếu cân thật bắt buộc) kèm lý do; đơn khác vẫn nhập.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Business.InboundOrderResult">
            <summary>Một đơn trong lô nhập kho.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Business.InboundOrderResult.OfficialFee">
            <summary>Cước chính thức vừa chốt (null = không thuộc phạm vi v2 / đã chốt trước / nhập tại bưu cục).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Business.InboundOrderResult.CodBelowFeeHold">
            <summary>Đơn COD có tiền thu hộ nhỏ hơn cước chính thức — đã giữ hàng, bên bán phải sửa trước khi xuất kho.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Cms.TopicPublishResult">
            <summary>Kết quả xuất bản khối (<c>POST api/Topic/PublishBlocks</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Cms.TopicPublishResult.DraftChanged">
            <summary>
            True = bản đang sửa đã đổi kể từ lúc người bấm mở màn (dấu <c>DraftVersion</c> lệch) — chưa xuất bản gì; FE
            tải lại bản mới nhất để người duyệt xem lại.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Cms.TopicPreviewResult">
            <summary>
            Link xem trước bản đang sửa (<c>POST api/Topic/PreviewToken</c>). <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Cms.TopicPreviewResult.Path"/> là đường dẫn trên website kèm
            token (<c>/nhuong-quyen?xem-truoc=…</c>) — FE ghép với địa chỉ website của môi trường.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Cms.UrlRedirectResult">
            <summary>Kết quả một lần lưu hoặc xoá luật chuyển hướng URL.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Cms.UrlRedirectResult.Id">
            <summary>Khoá của luật sau khi lưu; <c>0</c> khi thất bại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Cms.UrlRedirectResult.Message">
            <summary>
            Câu giải thích khi không lưu được — viết cho người nhập đọc, nói cả cách sửa.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Cms.UrlRedirectResult.Notice">
            <summary>
            Lời nhắc khi lưu <b>thành công</b> nhưng hệ thống đã tự làm thêm một việc mà người nhập
            không yêu cầu — hiện nay chỉ có một việc: tắt cờ <c>IncludeInSiteMap</c> của bản ghi
            <c>UrlRecord</c> cùng đường dẫn.
            </summary>
            <remarks>
            Tách khỏi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Cms.UrlRedirectResult.Message"/> vì giao diện xử lý hai thứ này khác nhau: một cái làm form
            đứng lại, một cái hiện kèm thông báo lưu xong. Nhập nó vào <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Cms.UrlRedirectResult.Message"/> là để giao
            diện phải đoán, và nó sẽ đoán sai đúng một lần rồi không ai nhớ.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Crm.CallLogResult">
            <summary>
            CallLog Result - Kết quả thao tác với CallLog
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Crm.CallLogResult.Id">
            <summary>
            Id của CallLog đã tạo / cập nhật
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Crm.CustomerBankAccountResult">
            <summary>
            Kết quả thao tác với tài khoản ngân hàng khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Crm.CustomerBankAccountResult.Data">
            <summary>
            Dữ liệu tài khoản ngân hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Crm.LeadResult.Id">
            <summary>
            Id của Lead đã tạo / cập nhật
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Crm.VatInfoResult">
            <summary>
            Kết quả tạo mới hoặc cập nhật thông tin xuất hóa đơn VAT
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Crm.VatInfoResult.Id">
            <summary>
            ID thông tin xuất hóa đơn VAT
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Email.EmailAccountResult">
            <summary>
            Kết quả tạo mới hoặc cập nhật tài khoản gửi email.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Email.EmailAccountResult.Id">
            <summary>
            ID tài khoản gửi email.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.ErrorReports.ErrorReportResult">
            <summary>
            Kết quả tạo mới báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.ErrorReports.ErrorReportResult.ErrorReport">
            <summary>
            Thông tin báo lỗi vừa tạo
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.ErrorReports.ErrorReportListResult">
            <summary>
            Kết quả danh sách báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.ErrorReports.ErrorReportListResult.ErrorReports">
            <summary>
            Danh sách báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.ErrorReports.ErrorReportListResult.TotalCount">
            <summary>
            Tổng số bản ghi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.ErrorReports.ErrorReportListResult.CurrentPage">
            <summary>
            Số trang hiện tại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.ErrorReports.ErrorReportListResult.PageSize">
            <summary>
            Kích thước trang
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.ErrorReports.ErrorReportListResult.TotalPages">
            <summary>
            Tổng số trang
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.ErrorReports.ErrorReportDetailResult">
            <summary>
            Kết quả chi tiết báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.ErrorReports.ErrorReportDetailResult.ErrorReport">
            <summary>
            Thông tin chi tiết báo lỗi
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.ErrorReports.ErrorReportUpdateResult">
            <summary>
            Kết quả cập nhật báo lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.ErrorReports.ErrorReportUpdateResult.ErrorReportId">
            <summary>
            ID báo lỗi đã cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.ErrorReports.ErrorReportUpdateResult.ErrorReport">
            <summary>
            Thông tin báo lỗi sau khi cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Export.ExportResult.Url">
            <summary>
            Đường dẫn tải file
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.BalanceAdjustmentResult">
            <summary>
            Kết quả điều chỉnh số dư ví
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.BalanceAdjustmentResult.OldBalance">
            <summary>
            Số dư cũ trước khi điều chỉnh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.BalanceAdjustmentResult.NewBalance">
            <summary>
            Số dư mới sau khi điều chỉnh
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.BalanceAdjustmentResult.AdjustmentAmount">
            <summary>
            Số tiền điều chỉnh (dương = cộng tiền, âm = trừ tiền)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.BalanceAdjustmentResult.TransactionId">
            <summary>
            ID giao dịch được tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.BalanceAdjustmentResult.TransactionDirection">
            <summary>
            Hướng giao dịch (Cộng tiền / Trừ tiền)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.CopyPriceListResult">
            <summary>
            Kết quả sao chép bảng giá — luôn trả về cả ba số để UI hiện đủ cho người dùng.
            </summary>
            <remarks>
            ⚠️ <b>Đừng chỉ hiện "Thành công".</b> Người dùng cần biết cái gì <b>không</b> được copy —
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.CopyPriceListResult.SkippedCount"/> và <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.CopyPriceListResult.Warnings"/> nói rõ điều đó.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.CopyPriceListResult.CreatedCount">
            <summary>Số ô giá đã tạo mới ở đích.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.CopyPriceListResult.SkippedCount">
            <summary>Số ô đã tồn tại ở đích và bị bỏ qua (khi <c>OverwriteExisting = false</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.CopyPriceListResult.OverwrittenCount">
            <summary>Số ô đã tồn tại ở đích và bị đè (khi <c>OverwriteExisting = true</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.CopyPriceListResult.Warnings">
            <summary>
            Cảnh báo không chặn — ví dụ: nguồn có tuyến mà đích không nhận diện được.
            Rỗng khi không có cảnh báo nào.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.ReconciliationResult">
            <summary>
            Kết quả thao tác với đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.ReconciliationResult.Data">
            <summary>
            Dữ liệu đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionResult.Transaction">
            <summary>
            Thông tin giao dịch đã tạo/cập nhật
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionDetailResult.Transaction">
            <summary>
            Chi tiết giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionDetailResult.Orders">
            <summary>
            Danh sách đơn hàng liên quan
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionDetailResult.SourceWallet">
            <summary>
            Thông tin ví nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionDetailResult.DestinationWallet">
            <summary>
            Thông tin ví đích (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionStatisticsResult.TotalTransactions">
            <summary>
            Tổng số giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionStatisticsResult.TotalIncome">
            <summary>
            Tổng tiền thu vào
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionStatisticsResult.TotalOutcome">
            <summary>
            Tổng tiền chi ra
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionStatisticsResult.TotalCash">
            <summary>
            Tổng tiền mặt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionStatisticsResult.TotalTransfer">
            <summary>
            Tổng tiền chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionStatisticsResult.TotalCod">
            <summary>
            Tổng tiền COD
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionStatisticsResult.TotalSourceFee">
            <summary>
            Tổng cước nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionStatisticsResult.TotalDestFee">
            <summary>
            Tổng cước đích
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionStatisticsResult.TypeStatistics">
            <summary>
            Thống kê theo loại giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionStatisticsResult.DailyStatistics">
            <summary>
            Thống kê theo ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.WalletInfo.Id">
            <summary>
            ID ví
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.WalletInfo.OwnerName">
            <summary>
            Tên chủ ví
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.WalletInfo.WalletType">
            <summary>
            Loại ví
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.WalletInfo.Balance">
            <summary>
            Số dư hiện tại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.WalletInfo.Status">
            <summary>
            Trạng thái ví
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionTypeStatistic.TransactionType">
            <summary>
            Loại giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionTypeStatistic.Count">
            <summary>
            Số lượng giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionTypeStatistic.TotalAmount">
            <summary>
            Tổng tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.DailyTransactionStatistic.Date">
            <summary>
            Ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.DailyTransactionStatistic.TransactionCount">
            <summary>
            Số giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.DailyTransactionStatistic.TotalIncome">
            <summary>
            Tổng tiền thu vào
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.DailyTransactionStatistic.TotalOutcome">
            <summary>
            Tổng tiền chi ra
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.DailyTransactionStatistic.EndOfDayBalance">
            <summary>
            Số dư cuối ngày
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionSearchResult">
            <summary>
            Kết quả tìm kiếm giao dịch với thông tin tổng thu và tổng chi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionSearchResult.TotalIncome">
            <summary>
            Tổng số tiền thu (Income)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionSearchResult.TotalOutcome">
            <summary>
            Tổng số tiền chi (Outcome)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionSearchResult.NetBalance">
            <summary>
            Số dư thực tế (TotalIncome - TotalOutcome)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionSearchResult.TotalCash">
            <summary>
            Tổng tiền mặt
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionSearchResult.TotalTransfer">
            <summary>
            Tổng tiền chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionSearchResult.DailyBalanceHistory">
            <summary>
            Lịch sử số dư theo ngày trong khoảng thời gian search
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.WalletBalanceHistoryResult.WalletId">
            <summary>
            ID ví
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.WalletBalanceHistoryResult.WalletOwnerName">
            <summary>
            Tên chủ ví
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.WalletBalanceHistoryResult.InitialBalance">
            <summary>
            Số dư ban đầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.WalletBalanceHistoryResult.CurrentBalance">
            <summary>
            Số dư hiện tại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.WalletBalanceHistoryResult.FormattedInitialBalance">
            <summary>
            Số dư ban đầu hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.WalletBalanceHistoryResult.FormattedCurrentBalance">
            <summary>
            Số dư hiện tại hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.WalletBalanceHistoryResult.DailyBalanceHistory">
            <summary>
            Lịch sử số dư theo ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.WalletBalanceHistoryResult.TransactionBalanceHistory">
            <summary>
            Lịch sử số dư theo giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.DailyBalanceHistory.Date">
            <summary>
            Ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.DailyBalanceHistory.FormattedDate">
            <summary>
            Ngày hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.DailyBalanceHistory.StartOfDayBalance">
            <summary>
            Số dư đầu ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.DailyBalanceHistory.EndOfDayBalance">
            <summary>
            Số dư cuối ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.DailyBalanceHistory.DailyChange">
            <summary>
            Thay đổi số dư trong ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.DailyBalanceHistory.FormattedStartBalance">
            <summary>
            Số dư đầu ngày hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.DailyBalanceHistory.FormattedEndBalance">
            <summary>
            Số dư cuối ngày hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.DailyBalanceHistory.FormattedDailyChange">
            <summary>
            Thay đổi số dư hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.DailyBalanceHistory.ChangeColor">
            <summary>
            Màu sắc thay đổi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionBalanceHistory.TransactionId">
            <summary>
            ID giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionBalanceHistory.Description">
            <summary>
            Mô tả giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionBalanceHistory.TransactionTypeName">
            <summary>
            Loại giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionBalanceHistory.TransactionDirectionName">
            <summary>
            Hướng giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionBalanceHistory.Amount">
            <summary>
            Số tiền giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionBalanceHistory.FormattedAmount">
            <summary>
            Số tiền hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionBalanceHistory.BalanceAfterTransaction">
            <summary>
            Số dư sau giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionBalanceHistory.FormattedBalance">
            <summary>
            Số dư hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionBalanceHistory.TransactionDate">
            <summary>
            Thời gian giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionBalanceHistory.FormattedTransactionDate">
            <summary>
            Thời gian hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionBalanceHistory.AmountColor">
            <summary>
            Màu sắc số tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.TransactionBalanceHistory.TransactionIcon">
            <summary>
            Icon giao dịch
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.BankResult">
            <summary>
            Result cho các operations của Bank
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.BankResult.Key">
            <summary>
            ID của ngân hàng (sau khi tạo/cập nhật)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelExportResult">
            <summary>
            Kết quả xuất Excel phiếu đối soát khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelExportResult.FilePath">
            <summary>
            Đường dẫn file Excel đã tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelExportResult.FileName">
            <summary>
            Tên file Excel
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelExportResult.FileSize">
            <summary>
            Kích thước file (bytes)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelExportResult.TotalRecords">
            <summary>
            Tổng số bản ghi đã xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelExportResult.DownloadUrl">
            <summary>
            URL download file
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelExportResult.ProcessStartTime">
            <summary>
            Thời gian bắt đầu xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelExportResult.ProcessEndTime">
            <summary>
            Thời gian kết thúc xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelExportResult.ProcessingTimeMs">
            <summary>
            Thời gian xử lý (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelExportResult.ProcessInfo">
            <summary>
            Thông tin chi tiết quá trình xử lý
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelProcessInfo">
            <summary>
            Thông tin chi tiết quá trình xử lý xuất Excel phiếu đối soát khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelProcessInfo.DatabaseQueryTimeMs">
            <summary>
            Thời gian query database (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelProcessInfo.DataConversionTimeMs">
            <summary>
            Thời gian chuyển đổi dữ liệu (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelProcessInfo.ExcelGenerationTimeMs">
            <summary>
            Thời gian tạo file Excel (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelProcessInfo.FileSaveTimeMs">
            <summary>
            Thời gian lưu file (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipExcelProcessInfo.TotalProcessingTimeMs">
            <summary>
            Tổng thời gian xử lý (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipResult.ReturnFeeDebts">
            <summary>Đơn hoàn khách nợ cước được cấn vào phiếu này (Ví v2 E13 — V-37): đang giữ chỗ hoặc đã cấn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipResult.CustomerBankAccounts">
            <summary>
            Danh sách tài khoản ngân hàng của khách hàng (chỉ hiển thị với phiếu Receivable - công ty cần chuyển tiền cho khách)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipResult.CanApprove">
            <summary>
            Người dùng hiện tại có thể duyệt phiếu (chỉ áp dụng cho phiếu chi tiền)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipResult.CanReject">
            <summary>
            Người dùng hiện tại có thể từ chối phiếu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.CustomerReconciliationSlipResult.CanComplete">
            <summary>
            Người dùng hiện tại có thể hoàn thành phiếu
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ExpenseCategoryResult">
            <summary>
            Kết quả trả về cho các thao tác với danh mục chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ExpenseCategoryResult.Items">
            <summary>
            Danh sách danh mục chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ExpenseCategoryResult.TotalRecord">
            <summary>
            Tổng số bản ghi
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ExportOrderResult">
            <summary>
            Kết quả xuất Excel thông tin đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ExportOrderResult.FilePath">
            <summary>
            Đường dẫn file Excel đã tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ExportOrderResult.FileName">
            <summary>
            Tên file Excel
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ExportOrderResult.DownloadUrl">
            <summary>
            URL để download file (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ExportOrderResult.FileSize">
            <summary>
            Kích thước file (bytes)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ExportOrderResult.TotalOrders">
            <summary>
            Số lượng đơn hàng đã xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ExportOrderResult.NotFoundOrders">
            <summary>
            Số lượng đơn hàng không tìm thấy
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ExportOrderResult.NotFoundOrderCodes">
            <summary>
            Danh sách mã đơn hàng không tìm thấy
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ExportOrderResult.CreatedTime">
            <summary>
            Thời gian tạo file
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ExportOrderResult.Summary">
            <summary>
            Thông tin tóm tắt kết quả
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportRowItem">
            <summary>
            Model cho từng dòng trong báo cáo thu chi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportRowItem.CategoryName">
            <summary>
            Tên danh mục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportRowItem.CategoryId">
            <summary>
            ID danh mục (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportRowItem.ParentId">
            <summary>
            ID danh mục cha (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportRowItem.Level">
            <summary>
            Cấp độ trong cây (0: gốc, 1: con, 2: cháu...)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportRowItem.RowType">
            <summary>
            Loại dòng: "Income", "Expense", "Total"
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportRowItem.DailyAmounts">
            <summary>
            Số tiền theo từng ngày (Key: "yyyy-MM-dd", Value: số tiền)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportRowItem.Total">
            <summary>
            Tổng cộng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportResult">
            <summary>
            Kết quả báo cáo thu chi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportResult.FromDate">
            <summary>
            Ngày bắt đầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportResult.ToDate">
            <summary>
            Ngày kết thúc
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportResult.DateColumns">
            <summary>
            Danh sách các cột ngày ["2025-10-01", "2025-10-02", ...]
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportResult.Rows">
            <summary>
            Danh sách các dòng dữ liệu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportResult.TotalIncome">
            <summary>
            Tổng thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportResult.TotalExpense">
            <summary>
            Tổng chi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportResult.NetAmount">
            <summary>
            Chênh lệch (Thu - Chi)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow">
            <summary>
            Model nhận dữ liệu từ stored procedure
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow.ReportDate">
            <summary>
            Ngày giao dịch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow.TransactionType">
            <summary>
            Loại giao dịch (3=OrderFee, 4=CollectFromDriver, ...)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow.TransactionDirection">
            <summary>
            Hướng giao dịch: "Income" hoặc "Outcome"
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow.CostCategoryId">
            <summary>
            ID danh mục chi phí (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow.CategoryName">
            <summary>
            Tên danh mục
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow.ParentId">
            <summary>
            ID danh mục cha
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow.Level">
            <summary>
            Cấp độ trong cây
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow.DisplayOrder">
            <summary>
            Thứ tự hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow.Amount">
            <summary>
            Số tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow.TransactionCount">
            <summary>
            Số lượng giao dịch
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelExportResult">
            <summary>
            Kết quả xuất Excel phiếu đối soát
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelExportResult.FilePath">
            <summary>
            Đường dẫn file Excel đã tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelExportResult.FileName">
            <summary>
            Tên file Excel
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelExportResult.FileSize">
            <summary>
            Kích thước file (bytes)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelExportResult.TotalRecords">
            <summary>
            Tổng số bản ghi đã xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelExportResult.DownloadUrl">
            <summary>
            URL download file
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelExportResult.ProcessStartTime">
            <summary>
            Thời gian bắt đầu xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelExportResult.ProcessEndTime">
            <summary>
            Thời gian kết thúc xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelExportResult.ProcessingTimeMs">
            <summary>
            Thời gian xử lý (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelExportResult.ProcessInfo">
            <summary>
            Thông tin chi tiết quá trình xử lý
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelProcessInfo">
            <summary>
            Thông tin chi tiết quá trình xử lý xuất Excel
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelProcessInfo.DatabaseQueryTimeMs">
            <summary>
            Thời gian query database (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelProcessInfo.DataConversionTimeMs">
            <summary>
            Thời gian chuyển đổi dữ liệu (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelProcessInfo.ExcelGenerationTimeMs">
            <summary>
            Thời gian tạo file Excel (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelProcessInfo.FileSaveTimeMs">
            <summary>
            Thời gian lưu file (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.ReconciliationExcelProcessInfo.TotalProcessingTimeMs">
            <summary>
            Tổng thời gian xử lý (ms)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TaxInvoiceResult">
            <summary>
            Kết quả thao tác hóa đơn thuế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TaxInvoiceResult.TaxInvoiceId">
            <summary>
            ID hóa đơn thuế
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TaxInvoiceResult.InvoiceNumber">
            <summary>
            Số hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TaxInvoiceResult.Status">
            <summary>
            Trạng thái
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TaxInvoiceResult.StatusName">
            <summary>
            Tên trạng thái
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult">
            <summary>
            Kết quả trả về từ stored procedure SP_GetTransferableOrdersByCustomer
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.OrderId">
            <summary>
            ID đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.OrderCode">
            <summary>
            Mã đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.OrderCreatedTime">
            <summary>
            Ngày tạo đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.OrderNote">
            <summary>
            Ghi chú đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.TransferFeeAmount">
            <summary>
            Số tiền TransferFee của đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.PayFeeType">
            <summary>
            Loại thanh toán phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.TransferFeeStage">
            <summary>
            Giai đoạn hiện tại của TransferFee
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.SenderName">
            <summary>
            Tên người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.SenderAddress">
            <summary>
            Địa chỉ người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.SenderPhone">
            <summary>
            Số điện thoại người gửi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.ReceiverName">
            <summary>
            Tên người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.ReceiverAddress">
            <summary>
            Địa chỉ người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.ReceiverPhone">
            <summary>
            Số điện thoại người nhận
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.Status">
            <summary>
            Trạng thái đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.PhysicalStatus">
            <summary>
            Trạng thái vật lý đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.CustomerFullName">
            <summary>
            Tên đầy đủ khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.CustomerPhone">
            <summary>
            Số điện thoại khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.CustomerEmail">
            <summary>
            Email khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.CustomerAddress">
            <summary>
            Địa chỉ khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.CustomerUserName">
            <summary>
            Username khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferableOrderResult.ProductInfo">
            <summary>
            Thông tin sản phẩm (gộp các package thành chuỗi)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelExportResult">
            <summary>
            Kết quả xuất Excel phiếu chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelExportResult.FilePath">
            <summary>
            Đường dẫn file Excel đã tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelExportResult.FileName">
            <summary>
            Tên file Excel
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelExportResult.FileSize">
            <summary>
            Kích thước file (bytes)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelExportResult.TotalRecords">
            <summary>
            Tổng số bản ghi đã xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelExportResult.DownloadUrl">
            <summary>
            URL download file
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelExportResult.ProcessStartTime">
            <summary>
            Thời gian bắt đầu xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelExportResult.ProcessEndTime">
            <summary>
            Thời gian kết thúc xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelExportResult.ProcessingTimeMs">
            <summary>
            Thời gian xử lý (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelExportResult.ProcessInfo">
            <summary>
            Thông tin chi tiết quá trình xử lý
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelProcessInfo">
            <summary>
            Thông tin chi tiết quá trình xử lý xuất Excel
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelProcessInfo.DatabaseQueryTimeMs">
            <summary>
            Thời gian query database (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelProcessInfo.DataConversionTimeMs">
            <summary>
            Thời gian chuyển đổi dữ liệu (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelProcessInfo.ExcelGenerationTimeMs">
            <summary>
            Thời gian tạo file Excel (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelProcessInfo.FileSaveTimeMs">
            <summary>
            Thời gian lưu file (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillExcelProcessInfo.TotalProcessingTimeMs">
            <summary>
            Tổng thời gian xử lý (ms)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillResult">
            <summary>
            Result class cho các thao tác với hóa đơn thanh toán chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillResult.Code">
            <summary>
            Mã hóa đơn được tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillResult.ProcessedOrderCount">
            <summary>
            Số lượng đơn hàng được xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillResult.TotalAmount">
            <summary>
            Tổng tiền của hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransferPaymentBillResult.TransactionId">
            <summary>
            ID giao dịch được tạo (khi duyệt)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.UserBankAccountResult">
            <summary>
            Result cho tài khoản ngân hàng người dùng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.UserBankAccountResult.Id">
            <summary>
            ID tài khoản ngân hàng được tạo/cập nhật
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.VatInvoiceSyncInfo">
            <summary>
            Thông tin đồng bộ hóa đơn VAT gần nhất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.VatInvoiceSyncInfo.HasSyncHistory">
            <summary>
            Có lịch sử đồng bộ hay chưa
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.VatInvoiceSyncInfo.LastSyncTime">
            <summary>
            Thời gian đồng bộ gần nhất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.VatInvoiceSyncInfo.SyncDateRange">
            <summary>
            Khoảng thời gian đã đồng bộ (FromDate - ToDate)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.VatInvoiceSyncInfo.Status">
            <summary>
            Trạng thái: Success, Failed, InProgress
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.VatInvoiceSyncInfo.InsertedCount">
            <summary>
            Số hóa đơn đã insert
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.VatInvoiceSyncInfo.UpdatedCount">
            <summary>
            Số hóa đơn đã update
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.VatInvoiceSyncInfo.TotalCount">
            <summary>
            Tổng số hóa đơn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.VatInvoiceSyncInfo.DurationSeconds">
            <summary>
            Thời gian thực hiện (giây)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.VatInvoiceSyncInfo.SyncType">
            <summary>
            Loại đồng bộ: Auto hoặc Manual
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.VatInvoiceSyncInfo.ErrorMessage">
            <summary>
            Thông báo lỗi nếu có
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.VatInvoiceSyncInfo.Message">
            <summary>
            Thông báo cho người dùng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelCardTransactionImportResult">
            <summary>
            Kết quả trả về sau khi import lịch sử giao dịch thẻ xăng dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelCardTransactionImportResult.TotalRows">
            <summary>
            Tổng số dòng trong file Excel
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelCardTransactionImportResult.ProcessedRows">
            <summary>
            Số dòng xử lý thành công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelCardTransactionImportResult.ErrorRows">
            <summary>
            Số dòng lỗi
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelCardTransactionImportResult.SkippedRows">
            <summary>
            Số dòng bỏ qua (không có số thẻ, dữ liệu thiếu...)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelCardTransactionImportResult.DuplicateRows">
            <summary>
            Số dòng trùng lặp (đã có trong hệ thống)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelCardTransactionImportResult.UnknownCardsCount">
            <summary>
            Số thẻ trong file không tìm thấy trong hệ thống
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelCardTransactionImportResult.UnknownCards">
            <summary>
            Danh sách số thẻ không tìm thấy trong hệ thống
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelCardTransactionImportResult.ErrorMessages">
            <summary>
            Danh sách thông báo lỗi chi tiết theo từng dòng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelCardTransactionImportResult.Warnings">
            <summary>
            Danh sách cảnh báo (không nghiêm trọng)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelCardTransactionImportResult.TotalAmountImported">
            <summary>
            Tổng số tiền chi tiêu đã import
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelCardTransactionImportResult.TotalPaymentImported">
            <summary>
            Tổng số tiền thanh toán ngân hàng đã import
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillExcelExportResult">
            <summary>
            Kết quả xuất Excel lịch sử đổ dầu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillExcelExportResult.FilePath">
            <summary>
            Đường dẫn file Excel đã tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillExcelExportResult.FileName">
            <summary>
            Tên file Excel
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillExcelExportResult.FileSize">
            <summary>
            Kích thước file (bytes)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillExcelExportResult.TotalRecords">
            <summary>
            Tổng số bản ghi đã xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillExcelExportResult.DownloadUrl">
            <summary>
            URL download file
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillExcelExportResult.ProcessStartTime">
            <summary>
            Thời gian bắt đầu xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillExcelExportResult.ProcessEndTime">
            <summary>
            Thời gian kết thúc xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillExcelExportResult.ProcessingTimeMs">
            <summary>
            Thời gian xử lý (ms)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillReportExcelResult">
            <summary>
            Kết quả xuất Excel báo cáo đổ dầu theo lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillReportExcelResult.FilePath">
            <summary>
            Đường dẫn file Excel đã tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillReportExcelResult.FileName">
            <summary>
            Tên file Excel
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillReportExcelResult.FileSize">
            <summary>
            Kích thước file (bytes)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillReportExcelResult.TotalRecords">
            <summary>
            Tổng số bản ghi đã xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillReportExcelResult.DownloadUrl">
            <summary>
            URL download file
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillReportExcelResult.ProcessStartTime">
            <summary>
            Thời gian bắt đầu xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillReportExcelResult.ProcessEndTime">
            <summary>
            Thời gian kết thúc xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.FuelCards.FuelRefillReportExcelResult.ProcessingTimeMs">
            <summary>
            Thời gian xử lý (ms)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.AttendanceImportResult">
            <summary>
            Kết quả import bảng chấm công từ file Excel (máy chấm công vân tay).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.AttendanceImportResult.TotalRows">
            <summary>
            Tổng số dòng dữ liệu đọc được (không tính header).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.AttendanceImportResult.ProcessedRows">
            <summary>
            Số dòng import thành công.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.AttendanceImportResult.ErrorRows">
            <summary>
            Số dòng lỗi (đã tồn tại chấm công cùng ngày + nhân viên).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.AttendanceImportResult.SkippedRows">
            <summary>
            Số dòng bỏ qua (mã chấm công không map được, hoặc ngày nghỉ không có giờ).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.AttendanceImportResult.ErrorMessages">
            <summary>
            Chi tiết các dòng lỗi / bỏ qua.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.AttendanceOverlapResult">
            <summary>
            Kết quả kiểm tra chồng lấp ca chấm công của cùng một nhân viên.
            Dùng cho FE cảnh báo sớm trong dialog chấm công thủ công / chấm ra bù,
            trước khi người dùng bấm lưu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.AttendanceOverlapResult.HasOverlap">
            <summary>
            Có bị trùng (chồng lấp thời gian) với ca đã tồn tại hay không.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.AttendanceOverlapResult.Message">
            <summary>
            Thông báo mô tả ca bị trùng. Rỗng nếu không trùng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.AttendanceOverlapResult.OverlapCheckInTime">
            <summary>
            Giờ vào của ca bị trùng (null nếu không trùng).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.AttendanceOverlapResult.OverlapCheckOutTime">
            <summary>
            Giờ ra của ca bị trùng (null nếu không trùng hoặc ca đó chưa chấm ra).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.CheckInOutResult">
            <summary>
            Kết quả trả về khi check-in/check-out chấm công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.CheckInOutResult.Item">
            <summary>
            Thông tin bản ghi chấm công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.CheckInOutResult.ActionType">
            <summary>
            Loại hành động vừa thực hiện (CheckIn hoặc CheckOut)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.CheckInOutResult.ActionTime">
            <summary>
            Thời gian thực hiện hành động
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.CheckInOutResult.IsCheckIn">
            <summary>
            Có phải là check-in không (true = check-in, false = check-out)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.SuggestCheckOutTimeResult">
            <summary>
            Kết quả gợi ý giờ chấm ra suy ra từ thời điểm giao/lấy hàng muộn nhất của lái xe trong ca.
            Dùng cho dialog chấm bù công khi lái xe quên chấm ra.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.SuggestCheckOutTimeResult.HasData">
            <summary>
            Có suy ra được giờ ra từ hoạt động đơn hàng hay không.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Hr.SuggestCheckOutTimeResult.SuggestedTime">
            <summary>
            Giờ chấm ra được gợi ý (thời điểm giao/lấy hàng muộn nhất trong ca). Null nếu không có dữ liệu.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Kpi.KpiAssignmentSaveResult">
            <summary>
            Kết quả lưu chỉ tiêu KPI — Draft lưu lẻ dòng được nhưng response kèm cảnh báo
            tổng trọng số hiện tại của chủ thể trong kỳ (§7.8); chặn cứng chỉ xảy ra lúc Assign.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Kpi.KpiAssignmentSaveResult.TotalWeight">
            <summary>
            Tổng trọng số (%) hiện tại của chủ thể trong kỳ sau thao tác
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Kpi.KpiAssignmentSaveResult.WeightWarning">
            <summary>
            Cảnh báo khi tổng trọng số ≠ 100% — chỉ cảnh báo, không chặn ở trạng thái Draft
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Media.SaveMediaResult.MediaId">
            <summary>
            ID của media record trong database (nếu có lưu)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Notifications.UserNotificationDto">
            <summary>
            DTO trả về cho 1 thông báo của user
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Notifications.NotificationListResult">
            <summary>
            DTO trả về cho danh sách thông báo (phân trang)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Notifications.NotificationCategoryDto">
            <summary>
            DTO cho NotificationCategory
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Notifications.NotificationPreferenceDto">
            <summary>
            DTO cho notification preference
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Notifications.NotificationPushDto">
            <summary>
            DTO cho real-time push qua SignalR (gọn nhất)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExcelExportResult">
            <summary>
            Kết quả xuất Excel đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExcelExportResult.FilePath">
            <summary>
            Đường dẫn file đã xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExcelExportResult.DownloadUrl">
            <summary>
            URL download file
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExcelExportResult.FileName">
            <summary>
            Tên file
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExcelExportResult.FileSize">
            <summary>
            Kích thước file (bytes)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExcelExportResult.TotalRecords">
            <summary>
            Số lượng đơn hàng đã xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExcelExportResult.ProcessStartTime">
            <summary>
            Thời gian bắt đầu xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExcelExportResult.ProcessEndTime">
            <summary>
            Thời gian kết thúc xử lý
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult">
            <summary>
            Kết quả xuất Excel đơn hàng (Generic)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.TemplateType">
            <summary>
            Loại template đã sử dụng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.TemplateName">
            <summary>
            Tên template đã sử dụng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.FilePath">
            <summary>
            Đường dẫn file Excel đã tạo
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.FileName">
            <summary>
            Tên file Excel
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.DownloadUrl">
            <summary>
            URL để download file (nếu có)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.FileSize">
            <summary>
            Kích thước file (bytes)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.TotalOrders">
            <summary>
            Số lượng đơn hàng đã xuất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.NotFoundOrders">
            <summary>
            Số lượng đơn hàng không tìm thấy
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.NotFoundOrderCodes">
            <summary>
            Danh sách mã đơn hàng không tìm thấy
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.NotFoundOrderIds">
            <summary>
            Danh sách ID đơn hàng không tìm thấy
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.ProcessStartTime">
            <summary>
            Thời gian bắt đầu xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.ProcessEndTime">
            <summary>
            Thời gian hoàn thành xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.ProcessingTimeMs">
            <summary>
            Thời gian xử lý (milliseconds)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.CreatedTime">
            <summary>
            Thời gian tạo file
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.ProcessInfo">
            <summary>
            Thông tin chi tiết về quá trình xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.Summary">
            <summary>
            Thông tin tóm tắt kết quả
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult.MarkProcessCompleted">
            <summary>
            Đánh dấu hoàn thành xử lý
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportProcessInfo">
            <summary>
            Thông tin chi tiết về quá trình xuất Excel
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportProcessInfo.DatabaseQueryTimeMs">
            <summary>
            Thời gian query database (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportProcessInfo.DataConversionTimeMs">
            <summary>
            Thời gian chuyển đổi dữ liệu (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportProcessInfo.ExcelGenerationTimeMs">
            <summary>
            Thời gian tạo file Excel (ms)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportProcessInfo.ProcessedRecords">
            <summary>
            Số lượng bản ghi đã xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportProcessInfo.ExcelColumns">
            <summary>
            Số lượng cột trong Excel
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportProcessInfo.ExcelRows">
            <summary>
            Số lượng dòng trong Excel (bao gồm header)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportProcessInfo.PeakMemoryUsage">
            <summary>
            Memory usage peak (bytes)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportProcessInfo.Warnings">
            <summary>
            Các cảnh báo trong quá trình xử lý
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportProcessInfo.DebugInfo">
            <summary>
            Thông tin debug (chỉ trong development)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportProcessInfo.TotalProcessingTimeMs">
            <summary>
            Tổng thời gian xử lý (ms)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult`1">
            <summary>
            Kết quả xuất Excel với thông tin template cụ thể
            </summary>
            <typeparam name="TExportItem">Loại DTO export</typeparam>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult`1.ExportedItems">
            <summary>
            Danh sách items đã xuất (để debug hoặc preview)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult`1.ColumnInfo">
            <summary>
            Metadata về các cột đã xuất
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.ExportColumnInfo">
            <summary>
            Thông tin về cột trong file Excel
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.ExportColumnInfo.ColumnName">
            <summary>
            Tên cột
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.ExportColumnInfo.ColumnIndex">
            <summary>
            Index cột (1-based)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.ExportColumnInfo.DataType">
            <summary>
            Loại dữ liệu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.ExportColumnInfo.Format">
            <summary>
            Định dạng hiển thị
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.ExportColumnInfo.Width">
            <summary>
            Chiều rộng cột
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.ExportColumnInfo.IsRequired">
            <summary>
            Có phải cột bắt buộc không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.ExportColumnInfo.Description">
            <summary>
            Mô tả cột
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.ResolveMapLinkResult">
            <summary>
            Kết quả bóc toạ độ từ link Google Maps. Chỉ dùng để điền vào form, không ghi CSDL.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.ResolveMapLinkResult.Lat">
            <summary>
            Vĩ độ bóc được. Null khi không tìm thấy toạ độ trong link.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.ResolveMapLinkResult.Long">
            <summary>
            Kinh độ bóc được. Null khi không tìm thấy toạ độ trong link.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.ResolveMapLinkResult.ResolvedUrl">
            <summary>
            URL cuối cùng sau khi đi theo redirect — trả về để người dùng đối chiếu
            khi link rút gọn trỏ tới địa điểm khác với họ nghĩ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Premises.PremiseResult">
            <summary>
            Kết quả chi tiết mặt bằng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Premises.PremiseResult.Financial">
            <summary>
            Thông tin tài chính
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Premises.PremiseResult.Contacts">
            <summary>
            Danh sách liên hệ
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Premises.PremiseResult.Scores">
            <summary>
            Danh sách điểm chấm
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Premises.PremiseResult.Medias">
            <summary>
            Danh sách ảnh/media
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult">
            <summary>
            Gợi ý đọc từ một hoá đơn bảo dưỡng đã đính kèm: số tiền / ngày / biển số, kèm kết quả đối chiếu biển số
            với xe của bản ghi. <b>Mọi trường đều là gợi ý "máy đọc — kiểm lại"</b>: người dùng bấm mới điền vào form,
            không có đường nào ghi thẳng vào DB (quyết định chủ dự án 2026-08-21, plan trích-xuất-văn-bản §6).
            </summary>
            <remarks>
            <see cref="P:Lada.Framework.DTO.BaseResult.Result"/> = Failed khi không đọc được tệp (không tìm thấy, định dạng lạ, PDF hỏng);
            Success kể cả khi không bóc được trường nào — khi đó mọi trường null và <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.Warnings"/> nói rõ.
            Không trả <c>Confidence</c> của OCR: đo GĐ B cho thấy nó không đo độ đúng (ảnh tin cậy 81 đúng 1/8 trường,
            ảnh tin cậy 84 đúng 8/8).
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.MediaLinkId">
            <summary>Id dòng đính kèm (<c>TruckMaintenanceMedia.Id</c>) đã đọc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.FileName">
            <summary>Tên tệp hiển thị (PDF) hoặc rỗng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.Format">
            <summary>Định dạng nhận diện từ nội dung tệp ("Pdf", "Jpeg", "Webp"...).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.UsedOcr">
            <summary>
            Có trang nào phải OCR không. True với ảnh và PDF scan — UI phải hiện lời nhắc "ảnh chụp giấy thường
            không đọc được, hãy nhập tay" (đo GĐ B: ảnh chụp giấy 6,2%).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.Pages">
            <summary>Số trang đã đọc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.ElapsedMs">
            <summary>Thời gian đọc (ms) — để theo dõi, không hiển thị.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.Amount">
            <summary>Tổng giá trị thanh toán gợi ý (đồng). Null = không thấy dòng tổng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.AmountText">
            <summary>Số nguyên văn trên chứng từ ("3.082.849").</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.AmountLabel">
            <summary>Nhãn dòng đã chọn ("Tổng giá trị thanh toán").</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.AmountKind">
            <summary>Loại dòng đã chọn — <c>GrandTotal</c> chắc nhất; <c>Subtotal</c>/<c>Computed</c> đi kèm cảnh báo.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.AmountLines">
            <summary>Mọi dòng tổng nhận ra trên chứng từ (trước/sau giảm giá, thuế...) để người dùng đối chiếu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.InvoiceDate">
            <summary>Ngày chứng từ / ngày vào xưởng gợi ý (giờ địa phương máy chủ, không kèm offset).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.InvoiceDateText">
            <summary>Chuỗi ngày nguyên văn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.InvoiceDateLabel">
            <summary>Nhãn đứng trước ngày ("Ngày vào xưởng"), rỗng nếu không có.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.InvoiceDateHasTime">
            <summary>Chứng từ có in giờ kèm ngày không — false thì 00:00 chỉ là giá trị mặc định.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.CompletionDate">
            <summary>Ngày hoàn thành / giao xe / ra xưởng nếu chứng từ có — gợi ý cho ô "Kết thúc".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.CompletionDateText">
            <summary>Chuỗi nguyên văn của <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.CompletionDate"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.CompletionDateLabel">
            <summary>Nhãn của <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.CompletionDate"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.CompletionDateHasTime">
            <summary>Chứng từ có in giờ kèm <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.CompletionDate"/> không.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.LicensePlate">
            <summary>Biển số đọc được, chuẩn hoá (chỉ chữ/số, IN HOA). Null = không thấy.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.LicensePlateText">
            <summary>Biển số nguyên văn trên chứng từ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.LicensePlates">
            <summary>Mọi biển số chuẩn hoá đọc được (xe kéo + rơ-moóc, bảng nhiều xe) — client so với xe đang chọn bằng danh sách này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.TruckLicensePlate">
            <summary>Biển số của xe đang gắn với bản ghi bảo dưỡng (nguyên văn trong DB).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.PlateMatchesTruck">
            <summary>
            Biển số trên chứng từ có khớp xe của bản ghi không (so sau khi chuẩn hoá cả hai).
            Null = không đọc được biển số nên không đối chiếu được. False = "hoá đơn này có vẻ của xe khác".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult.Warnings">
            <summary>Điều cần người dùng kiểm lại — hiển thị thẳng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceAmountLine">
            <summary>Một dòng tổng tiền trên chứng từ — bản phẳng của <see cref="T:Lada.Framework.DTO.TextExtraction.InvoiceAmountLine"/> cho API.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceAmountLine.Kind">
            <summary>Loại dòng (tên enum <see cref="T:Lada.Framework.DTO.TextExtraction.InvoiceAmountKind"/>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceAmountLine.Label">
            <summary>Nhãn nguyên văn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceAmountLine.Value">
            <summary>Giá trị (đồng).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceAmountLine.ValueText">
            <summary>Số nguyên văn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipReadResult">
            <summary>
            Kết quả "Đọc phiếu bằng AI" (plan bảo dưỡng đợt 3 §3.1): tiêu đề phiếu + từng dòng kèm gợi ý khớp danh mục. Mọi
            thứ ở đây là GỢI Ý — người dùng bấm "Dùng" mới thành dòng của form, không có đường nào tự ghi DB.
            </summary>
            <remarks>
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipReadResult.Mode"/> = <c>Offline</c> khi AI lỗi và máy chủ đã chuyển sang OCR cũ (QĐ3-6): khi đó chỉ
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipReadResult.Offline"/> có số (tiền / ngày / biển số), <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipReadResult.Lines"/> rỗng.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipReadResult.ReadingId">
            <summary>Id dòng nhật ký — dùng cho Khớp lại / mở lại / gắn vào bản ghi khi lưu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipReadResult.FromCache">
            <summary>Lấy lại kết quả của cùng tệp + cùng model trong 30 ngày, không gọi AI.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipReadResult.TruckLicensePlate">
            <summary>Biển số xe của bản ghi / xe đang chọn, nguyên văn trong DB.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipReadResult.PlateMatchesTruck">
            <summary>null khi phiếu không ghi biển số; false là dấu hiệu đính nhầm phiếu xe khác.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipReadResult.RematchRemaining">
            <summary>Lượt khớp lại (bước 2b) còn được chạy cho reading này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipReadResult.Offline">
            <summary>Kết quả OCR cũ khi AI lỗi (chỉ có ở <see cref="F:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipReadResult.ModeOffline"/>).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipHeaderItem">
            <summary>Phần đầu phiếu — mỗi ô có nút "Dùng" riêng trên giao diện như khối gợi ý OCR cũ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipHeaderItem.DocumentDate">
            <summary>Ngày chứng từ đã kiểm (null nếu phiếu không ghi hoặc ngày không hợp lệ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipHeaderItem.Confidence">
            <summary>Độ tự tin AI tự báo: <c>high</c> / <c>medium</c> / <c>low</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipLineItem">
            <summary>Một dòng trên phiếu, đã kiểm số, kèm gợi ý khớp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipLineItem.Kind">
            <summary><c>part</c> / <c>labor</c> / <c>service</c> / <c>fee</c> / <c>other</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipLineItem.ActionType">
            <summary><c>MaintenanceActionType</c> suy từ hành động trên phiếu; null khi không rõ hoặc "việc khác".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipLineMatchItem">
            <summary>Gợi ý khớp một dòng — kết quả tầng 2a (thuần) hoặc 2b (LLM, đã kiểm mã tồn tại).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipLineMatchItem.Decision">
            <summary><c>match</c> / <c>new</c> / <c>skip</c> / <c>unmatched</c> (chưa khớp được, chưa có gợi ý).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipLineMatchItem.TargetType">
            <summary><c>componentType</c> / <c>attribute</c> / null.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipLineMatchItem.Confidence">
            <summary><c>high</c> / <c>medium</c> / <c>low</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipLineMatchItem.Source">
            <summary>Khớp nhờ đâu: <c>alias</c> / <c>code</c> / <c>name</c> / <c>attribute</c> / <c>fuzzy</c> / <c>llm</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipProposalItem">
            <summary>Đề xuất cho người quản lý danh mục — chỉ mở form có sẵn, điền sẵn; không tự ghi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipProposalItem.Kind">
            <summary><c>alias</c> / <c>newComponentType</c> / <c>newAttribute</c> / <c>editComponentType</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipProposalItem.GroupType">
            <summary>Giá trị <c>TruckComponentGroup</c> (1–5) đã kiểm; null khi AI đưa nhóm lạ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult">
            <summary>
            Kết quả một đơn hàng CK kế toán chi tiết (dùng cho xuất Excel khi click từng ô số liệu)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.OrderCode">
            <summary>Mã đơn hàng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.PartnerCode">
            <summary>Mã đối tác</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.SaleName">
            <summary>Tên sale</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.SalePhoneNumber">
            <summary>SĐT sale</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.CustomerName">
            <summary>Tên khách hàng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.CustomerPhoneNumber">
            <summary>SĐT khách hàng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.TransferFee">
            <summary>Phí chuyển khoản</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.TotalFee">
            <summary>Tổng cước</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.TransferFeeStage">
            <summary>Trạng thái phí CK (stage)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.OrderStatus">
            <summary>Trạng thái đơn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.OrderPhysicalStatus">
            <summary>Trạng thái vật lý</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.OrderDate">
            <summary>Thời gian tạo đơn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.DeliveryDate">
            <summary>Thời gian giao hàng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.SenderName">
            <summary>Người gửi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.SenderPhone">
            <summary>SĐT người gửi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.ReceiverName">
            <summary>Người nhận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.ReceiverPhone">
            <summary>SĐT người nhận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferOrderDetailResult.Note">
            <summary>Ghi chú</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerResult">
            <summary>
            Kết quả trả về từ stored procedure sp_GetBankTransferSummaryByCustomer
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerResult.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerResult.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerResult.CustomerPhoneNumber">
            <summary>
            Số điện thoại khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerResult.TotalOrders">
            <summary>
            Tổng số đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerResult.SumTotalFee">
            <summary>
            Tổng tiền cước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerResult.TotalTransferFee">
            <summary>
            Tổng phí chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerResult.NotCollectAmount">
            <summary>
            Tổng số tiền chưa thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerResult.NotCollectedCount">
            <summary>
            Số lượng đơn chưa thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerResult.CreatedBillAmount">
            <summary>
            Tổng số tiền đã tạo phiếu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerResult.CountCreatedBill">
            <summary>
            Số lượng đơn đã tạo phiếu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerResult.TotalCollected">
            <summary>
            Tổng số tiền đã thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerResult.CountCollected">
            <summary>
            Số lượng đơn đã thu
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerTotalsResult">
            <summary>
            Kết quả dòng Tổng toàn cục (theo bộ lọc) cho báo cáo công nợ CK theo khách hàng.
            Trả về từ stored procedure sp_GetBankTransferSummaryByCustomerTotals — dùng cho
            summary cards + dòng Tổng, tính trên TOÀN BỘ khách hàng khớp filter (không theo trang).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerTotalsResult.TotalCustomers">
            <summary>Tổng số khách hàng (số dòng của báo cáo)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerTotalsResult.TotalOrders">
            <summary>Tổng số đơn hàng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerTotalsResult.SumTotalFee">
            <summary>Tổng tiền cước</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerTotalsResult.TotalTransferFee">
            <summary>Tổng phí chuyển khoản</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerTotalsResult.NotCollectAmount">
            <summary>Tổng số tiền chưa thu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerTotalsResult.NotCollectedCount">
            <summary>Số lượng đơn chưa thu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerTotalsResult.CreatedBillAmount">
            <summary>Tổng số tiền đã tạo phiếu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerTotalsResult.CountCreatedBill">
            <summary>Số lượng đơn đã tạo phiếu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerTotalsResult.TotalCollected">
            <summary>Tổng số tiền đã thu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryByCustomerTotalsResult.CountCollected">
            <summary>Số lượng đơn đã thu</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleResult">
            <summary>
            Kết quả trả về từ stored procedure sp_GetBankTransferSummaryBySale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleResult.SaleId">
            <summary>
            ID sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleResult.SaleName">
            <summary>
            Tên sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleResult.SalePhoneNumber">
            <summary>
            Số điện thoại sale
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleResult.TotalOrders">
            <summary>
            Tổng số đơn hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleResult.SumTotalFee">
            <summary>
            Tổng tiền cước
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleResult.TotalTransferFee">
            <summary>
            Tổng phí chuyển khoản
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleResult.NotCollectAmount">
            <summary>
            Tổng số tiền chưa thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleResult.NotCollectedCount">
            <summary>
            Số lượng đơn chưa thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleResult.CreatedBillAmount">
            <summary>
            Tổng số tiền đã tạo phiếu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleResult.CountCreatedBill">
            <summary>
            Số lượng đơn đã tạo phiếu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleResult.TotalCollected">
            <summary>
            Tổng số tiền đã thu
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleResult.CountCollected">
            <summary>
            Số lượng đơn đã thu
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleTotalsResult">
            <summary>
            Kết quả dòng Tổng toàn cục (theo bộ lọc) cho báo cáo công nợ CK theo Sale.
            Trả về từ stored procedure sp_GetBankTransferSummaryBySaleTotals — dùng cho
            summary cards, tính trên TOÀN BỘ sale khớp filter (không theo trang).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleTotalsResult.TotalSales">
            <summary>Tổng số sale (số dòng của báo cáo)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleTotalsResult.TotalOrders">
            <summary>Tổng số đơn hàng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleTotalsResult.SumTotalFee">
            <summary>Tổng tiền cước</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleTotalsResult.TotalTransferFee">
            <summary>Tổng phí chuyển khoản</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleTotalsResult.NotCollectAmount">
            <summary>Tổng số tiền chưa thu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleTotalsResult.NotCollectedCount">
            <summary>Số lượng đơn chưa thu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleTotalsResult.CreatedBillAmount">
            <summary>Tổng số tiền đã tạo phiếu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleTotalsResult.CountCreatedBill">
            <summary>Số lượng đơn đã tạo phiếu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleTotalsResult.TotalCollected">
            <summary>Tổng số tiền đã thu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.BankTransferSummaryBySaleTotalsResult.CountCollected">
            <summary>Số lượng đơn đã thu</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerReconciliationSpResult">
            <summary>
            Result class for sp_SearchCustomersForReconciliation stored procedure
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerTransferPaymentSummaryResult">
            <summary>
            Kết quả trả về từ stored procedure SP_SearchCustomersForTransferPayment
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerTransferPaymentSummaryResult.CustomerId">
            <summary>
            ID khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerTransferPaymentSummaryResult.CustomerName">
            <summary>
            Tên khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerTransferPaymentSummaryResult.CustomerPhone">
            <summary>
            Số điện thoại khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerTransferPaymentSummaryResult.CustomerEmail">
            <summary>
            Email khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerTransferPaymentSummaryResult.CustomerAddress">
            <summary>
            Địa chỉ khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerTransferPaymentSummaryResult.PendingOrderCount">
            <summary>
            Số lượng đơn hàng chờ thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerTransferPaymentSummaryResult.TotalPendingAmount">
            <summary>
            Tổng số tiền TransferFee chờ thanh toán
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerTransferPaymentSummaryResult.OldestOrderDate">
            <summary>
            Ngày tạo đơn hàng cũ nhất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerTransferPaymentSummaryResult.LatestOrderDate">
            <summary>
            Ngày tạo đơn hàng mới nhất
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerTransferPaymentSummaryResult.ManagerId">
            <summary>
            ID quản lý khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerTransferPaymentSummaryResult.ManagerName">
            <summary>
            Tên quản lý khách hàng
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerTransferPaymentSummaryResult.CanCreateBill">
            <summary>
            Có thể tạo hóa đơn không
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerTransferPaymentSummaryResult.TotalRecord">
            <summary>
            Tổng số bản ghi (cho pagination)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.CustomerTransferPaymentSummaryResult.NumberOfPages">
            <summary>
            Tổng số trang (cho pagination)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.DriverProductivityReportByDateResult">
            <summary>
            Kết quả trả về từ stored procedure sp_GetDriverProductivityReportByDate
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.DriverProductivityReportByDateResult.DriverId">
            <summary>
            ID lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.DriverProductivityReportByDateResult.DriverUserName">
            <summary>
            Tên đăng nhập lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.DriverProductivityReportByDateResult.DriverFullName">
            <summary>
            Tên đầy đủ lái xe
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.DriverProductivityReportByDateResult.ActivityDate">
            <summary>
            Ngày hoạt động
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.DriverProductivityReportByDateResult.PickupCount">
            <summary>
            Số lượng đơn hàng lấy hàng trong ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.DriverProductivityReportByDateResult.DeliveryCount">
            <summary>
            Số lượng đơn hàng giao hàng trong ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.DriverProductivityReportByDateResult.TotalCount">
            <summary>
            Tổng số lượng đơn hàng trong ngày
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.DriverProductivityReportByDateResult.DayOfWeek">
            <summary>
            Tên ngày trong tuần
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.DriverProductivityReportByDateResult.FromDate">
            <summary>
            Thời gian bắt đầu (từ tham số)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.DriverProductivityReportByDateResult.ToDate">
            <summary>
            Thời gian kết thúc (từ tham số)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.DTO.StoredProcedureResults.ReconciliableOrderSpResult">
            <summary>
            Result class for sp_GetReconciliableOrdersByCustomer stored procedure
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Extensions.MediaServiceExtensions">
            <summary>
            Extension methods để cấu hình Media Services
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Extensions.MediaServiceExtensions.AddNewMediaServices(Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.Configuration.IConfiguration)">
            <summary>
            Đăng ký tất cả Media Services mới (ImageService, VideoService, UnifiedMediaService)
            </summary>
            <param name="services">Service collection</param>
            <param name="configuration">Configuration</param>
            <returns>Service collection</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Extensions.MediaServiceExtensions.AddMediaServicesWithBackwardCompatibility(Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.Configuration.IConfiguration)">
            <summary>
            Đăng ký Media Services với backward compatibility
            Giữ lại interface cũ nhưng sử dụng implementation mới
            </summary>
            <param name="services">Service collection</param>
            <param name="configuration">Configuration</param>
            <returns>Service collection</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Extensions.MediaServiceExtensions.AddMediaServicesMigration(Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.Configuration.IConfiguration,System.Boolean)">
            <summary>
            Migration helper - Thay thế dần dần các service cũ
            </summary>
            <param name="services">Service collection</param>
            <param name="configuration">Configuration</param>
            <param name="enableLegacyServices">Có enable legacy services không</param>
            <returns>Service collection</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Extensions.IBackwardCompatibleMediaService">
            <summary>
            Backward Compatible Media Service - Wrapper cho legacy interfaces
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Extensions.PermissionExtensions.ToEntity(Ladaer.BackEnd.Infrastructures.DTO.Models.Itentity.PermissionModel)">
            <summary>
            Chuyển đổi từ PermissionModel sang Permission entity
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Extensions.PermissionExtensions.ToModel(Lada.Framework.Data.Domains.Identity.Permission)">
            <summary>
            Chuyển đổi từ Permission entity sang PermissionModel
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Filters.HangfireAuthorizationFilter">
            <summary>
            Authorization filter cho Hangfire Dashboard.
            Chỉ cho phép truy cập nếu user đã đăng nhập và có role Founder hoặc Admin.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Helpers.DriverActiveOrderFilter">
            <summary>
            Bộ lọc "đơn đang hoạt động" của app tài xế — nơi duy nhất định nghĩa tổ hợp trạng thái nào thì đơn
            xuất hiện trên tab Đơn hàng, và tách được theo nhóm (lấy / giao / trả / trung chuyển).
            </summary>
            <remarks>
            <para>
            Tách khỏi <c>DriverAppOrderService</c> để ca test canh được bằng <c>FakeRepository</c> mà không phải
            dựng cả service với hàng chục phụ thuộc.
            </para>
            <para>
            Nhóm trung chuyển (<see cref="F:Lada.Framework.Data.Enums.OrderPhysicalStatus.Outbound"/>) thêm 2026-09-22: <c>Deploy.AssignTransit</c>
            vẫn gán <c>PicId</c> cho lái xe trung chuyển và đưa đơn về Outbound, nhưng bộ lọc cũ không có mã này nên
            lái xe trung chuyển mở tab Đơn hàng luôn thấy trống. Đơn trung chuyển chỉ để tra cứu — app không mở
            thao tác lấy/giao cho nhóm này.
            </para>
            <para>
            <see cref="P:Ladaer.BackEnd.Infrastructures.Helpers.DriverActiveOrderFilter.IsActive"/> phải là MỘT biểu thức viết tay (không ghép <c>OrElse</c> từ các nhóm) để EF dịch
            thẳng sang SQL; ca test kiểm rằng nó đúng bằng hợp của bốn nhóm.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Helpers.DriverActiveOrderFilter.IsPickup">
            <summary>Đang lấy hàng hoặc lấy thất bại chờ lấy lại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Helpers.DriverActiveOrderFilter.IsDelivery">
            <summary>Đang giao hoặc giao thất bại chờ giao lại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Helpers.DriverActiveOrderFilter.IsReturn">
            <summary>Đang trả hàng về người gửi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Helpers.DriverActiveOrderFilter.IsTransit">
            <summary>
            Đã xuất kho, đang trên xe trung chuyển tới bưu cục kế tiếp. Chỉ cần mã vật lý: mọi đường gán
            Outbound cho một <c>PicId</c> đều là gán lái xe trung chuyển (xem <c>DeployService.AssignTransit</c>).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Helpers.DriverActiveOrderFilter.IsActive">
            <summary>Hợp của bốn nhóm trên — viết tay thành một biểu thức để EF dịch được.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Helpers.DriverActiveOrderFilter.ForGroup(System.String)">
            <summary>
            Bộ lọc thêm theo nhóm app gửi lên qua <c>PredicateObject.Group</c>; <c>null</c> khi nhóm rỗng hoặc
            không nhận ra (giữ nguyên danh sách "tất cả" thay vì trả rỗng vì một chuỗi lạ).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Helpers.DriverOrderMediaMapper">
            <summary>
            Ghép bản ghi <c>Media</c> của một đơn với <c>OrderTrack</c> sinh ra nó và URL đã đổi, thành danh sách
            <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderMediaItem"/> cho app tài xế.
            </summary>
            <remarks>
            Thứ tự trả về: theo thời điểm sự kiện tăng dần (ảnh lấy hàng trước, ảnh giao sau), trong cùng sự kiện
            theo <c>DisplayOrder</c>. Ảnh không đổi được URL bị bỏ qua thay vì trả ô trống cho app.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Helpers.DriverOrderMediaMapper.ToItems(System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Medias.Media},System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Orders.OrderTrack},System.Collections.Generic.IReadOnlyList{System.String})">
            <param name="medias">Bản ghi ảnh của đơn.</param>
            <param name="tracks">Các track mà ảnh trỏ tới (thiếu cũng được — nhóm sẽ không có tên).</param>
            <param name="urls">URL tương ứng từng phần tử của <paramref name="medias"/>, cùng thứ tự.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Helpers.DriverOrderMediaMapper.GroupByOrder(System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Medias.Media},System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Orders.OrderTrack},System.Collections.Generic.IReadOnlyList{System.String})">
            <summary>
            Như <see cref="M:Ladaer.BackEnd.Infrastructures.Helpers.DriverOrderMediaMapper.ToItems(System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Medias.Media},System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Orders.OrderTrack},System.Collections.Generic.IReadOnlyList{System.String})"/> nhưng cho ảnh của nhiều đơn nạp chung một lượt (danh sách đơn): tách theo
            <c>Media.OrderId</c> rồi xếp từng đơn như <see cref="M:Ladaer.BackEnd.Infrastructures.Helpers.DriverOrderMediaMapper.ToItems(System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Medias.Media},System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Orders.OrderTrack},System.Collections.Generic.IReadOnlyList{System.String})"/>. Đơn không còn ảnh nào thì không có khoá.
            </summary>
            <param name="medias">Bản ghi ảnh của nhiều đơn, thứ tự bất kỳ.</param>
            <param name="tracks">Các track mà ảnh trỏ tới, của mọi đơn.</param>
            <param name="urls">URL tương ứng từng phần tử của <paramref name="medias"/>, cùng thứ tự.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Helpers.GoogleMapLinkParser">
             <summary>
             Bóc toạ độ ra khỏi link Google Maps.
            
             Frontend cũng có bản parse riêng (Ladaer.FrontEnd/src/views/orders/shared/googleMapLink.js)
             để xử lý ngay link đầy đủ mà không cần gọi server. Bản này phục vụ link RÚT GỌN
             (maps.app.goo.gl) — browser không đọc được Location header của redirect nên
             bắt buộc phải nhờ server đi theo redirect rồi parse.
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Helpers.GoogleMapLinkParser.PlaceCoordRegex">
            <summary>
            Toạ độ điểm được Google nhúng trong tham số `data`: !3d{lat}!4d{lng}.
            Đây là toạ độ CỦA ĐỊA ĐIỂM, chính xác hơn `@lat,lng` (toạ độ camera).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Helpers.GoogleMapLinkParser.QueryCoordRegex">
            <summary>Toạ độ trong query string: q= / query= / ll= / daddr= / center= / destination=.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Helpers.GoogleMapLinkParser.CameraCoordRegex">
            <summary>Toạ độ camera: /@{lat},{lng},{zoom}z — dùng khi không có toạ độ điểm.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Helpers.GoogleMapLinkParser.PlainCoordRegex">
            <summary>Chuỗi toạ độ thuần "21.028, 105.834" người dùng dán trực tiếp.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Helpers.GoogleMapLinkParser.TryParse(System.String)">
            <summary>
            Tìm toạ độ trong một chuỗi (link hoặc cặp số). Trả về null nếu không thấy
            toạ độ hợp lệ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Helpers.GoogleMapLinkParser.IsValidCoord(System.Double,System.Double)">
            <summary>Toạ độ nằm trong khoảng hợp lệ và không phải điểm 0,0 (Vịnh Guinea).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Helpers.GoogleMapLinkParser.AllowedHostSuffixes">
            <summary>
            Host được phép gọi khi đi theo redirect. Đây là chốt chặn SSRF: người dùng
            dán được URL bất kỳ, nếu không khoá host thì endpoint này thành công cụ để
            server đi thăm mạng nội bộ (169.254.169.254, localhost, IP LAN…).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Helpers.GoogleMapLinkParser.IsAllowedGoogleUrl(System.String,System.Uri@)">
            <summary>
            Kiểm tra một URL có thuộc miền Google được phép hay không. Chỉ nhận http/https
            và so khớp theo nhãn tên miền (chặn kiểu "google.com.evil.tld").
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Helpers.IAddressCoord">
             <summary>
             Hợp đồng tối thiểu để điền toạ độ cho một địa chỉ đơn hàng.
            
             Có nhiều DTO địa chỉ khác nhau (OrderAddressItem cho danh sách,
             OrderDetailAddressModel cho trang tra cứu) nhưng tất cả cần cùng một quy tắc
             điền toạ độ. Dùng interface thay vì viết lại từng nơi — lệch nhau thì cùng
             một địa chỉ sẽ hiện "đã định vị" ở trang này và "chưa định vị" ở trang khác.
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Helpers.IAddressCoord.Lat">
            <summary>Vĩ độ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Helpers.IAddressCoord.Long">
            <summary>Kinh độ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Helpers.IAddressCoord.CoordSource">
            <summary>Nguồn toạ độ: 0 = chưa có, 1 = ghim chính xác, 2 = tâm phường/xã.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Helpers.IAddressCoord.WardId">
            <summary>Id phường/xã (0 với địa chỉ 2 cấp).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Helpers.IAddressCoord.DistrictId">
            <summary>Id quận/huyện.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Helpers.OrderCoordHelper">
             <summary>
             Điền toạ độ cho địa chỉ đơn hàng, dùng chung cho bản đồ triển khai (portal),
             danh sách đơn / trang tra cứu của portal và bản đồ đơn hàng của app lái xe.
            
             Trước đây logic này chỉ nằm riêng trong DeployService nên API của app lái xe
             không có toạ độ gần đúng và luôn trả CoordSource = 0. Tách ra đây để các
             luồng dùng cùng một quy tắc, tránh lệch nhau khi sửa về sau.
             </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Helpers.OrderCoordHelper.LocationCoord">
            <summary>Toạ độ tâm của một đơn vị hành chính.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Helpers.OrderCoordHelper.LocationCoord.#ctor(System.Double,System.Double)">
            <summary>Toạ độ tâm của một đơn vị hành chính.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Helpers.OrderCoordHelper.CollectCoordLocationIds(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Helpers.IAddressCoord})">
            <summary>
            Gom Id đơn vị hành chính cần nạp để tra tâm cho một loạt địa chỉ.
            Địa chỉ 3 cấp tra theo phường/xã, địa chỉ 2 cấp (WardId = 0) tra theo quận/huyện.
            </summary>
            <param name="addresses">Danh sách địa chỉ cần điền toạ độ</param>
            <returns>Danh sách Id Location cần nạp (đã loại trùng)</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Helpers.OrderCoordHelper.BuildCoordLookup(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Categories.Location})">
            <summary>
            Dựng bảng tra toạ độ tâm từ entity Location (dùng khi service có repository).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Helpers.OrderCoordHelper.BuildCoordLookup(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.LocationItem})">
            <summary>
            Dựng bảng tra toạ độ tâm từ DTO LocationItem (dùng khi service chỉ có
            ILocationService, không có repository Location — như OrderService).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Helpers.OrderCoordHelper.FillAddressCoord(Ladaer.BackEnd.Infrastructures.Helpers.IAddressCoord,System.Collections.Generic.IReadOnlyDictionary{System.Int32,Ladaer.BackEnd.Infrastructures.Helpers.OrderCoordHelper.LocationCoord})">
            <summary>
            Điền toạ độ cho một địa chỉ đơn hàng theo 2 tầng (không gọi mạng):
            1 = toạ độ đã ghim sẵn trên đơn, 2 = tâm phường/xã (hoặc quận/huyện với địa chỉ 2 cấp).
            Tầng gọi Google nằm ở DeployService.GeocodeOrderAddresses, chỉ nhân viên
            điều hành gọi được (role Deploy.GetDeployDetail).
            </summary>
            <param name="address">Địa chỉ cần điền toạ độ</param>
            <param name="coordLookup">Bảng tra tâm đơn vị hành chính (xem BuildCoordLookup)</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Helpers.OrderCoordHelper.FillAddressCoord(Ladaer.BackEnd.Infrastructures.Helpers.IAddressCoord,System.Collections.Generic.List{Lada.Framework.Data.Domains.Categories.Location})">
             <summary>
             Quá tải cho các luồng đang truyền thẳng danh sách entity Location
             (DeployService, DriverAppOrderService).
            
             Quét tuyến tính chứ KHÔNG dựng lại lookup: hàm này được gọi trong vòng lặp
             theo từng địa chỉ, dựng dictionary mỗi lần sẽ thành O(số địa chỉ × số phường).
             Luồng nào gọi nhiều nên tự dựng lookup một lần rồi dùng quá tải ở trên.
             </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Hubs.ChatHub">
            <summary>
            Hub đẩy sự kiện chat đa nền tảng về SPA quản trị.
            <para>
            Bốn nhóm, bốn mục đích khác nhau:
            <list type="bullet">
            <item><see cref="F:Ladaer.BackEnd.Infrastructures.Hubs.ChatHub.AgentsGroup"/> — mọi nhân viên đang mở trang chat. Chỉ còn dùng cho kênh
            ở chế độ <c>Shared</c>, nơi ai có quyền cũng thấy mọi hội thoại (§6.3).</item>
            <item><c>chan-{channelId}</c> — những người xem được TOÀN BỘ một kênh đã bật hàng rào:
            trưởng nhóm, chủ kênh, và người có quyền xem tất cả.</item>
            <item><c>staff-{userId}</c> — đúng một người. Dùng để báo cập nhật của hội thoại đang giao
            cho họ trên kênh có hàng rào, mà không phải phát cho cả kênh.</item>
            <item><c>conv-{id}</c> — những người đang mở đúng hội thoại đó. Dùng cho bong bóng tin và
            trạng thái giao nhận.</item>
            </list>
            </para>
            <para>
            <b>Server tự chấm, không tin tham số client gửi lên.</b> Danh sách kênh được vào lấy từ
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatVisibilityResolver"/> ngay lúc kết nối, và <see cref="M:Ladaer.BackEnd.Infrastructures.Hubs.ChatHub.JoinConversation(System.Int32)"/>
            tra lại hội thoại trong phạm vi trước khi cho vào phòng. Không có bước này thì hàng rào
            của 13 endpoint REST vô nghĩa: bản đẩy <c>ConversationUpdated</c> mang theo
            <c>LastMessage</c> — nguyên văn tin của khách.
            </para>
            <para>
            Quyền được chấm ở ngay lớp này, không phó mặc cho giao diện: kết nối đòi
            <c>ChatConversation.Search</c>, vào một hội thoại đòi <c>ChatConversation.GetById</c>.
            Role không nằm trong JWT — <c>ServerRoleAuthorizationHandler</c> tra database, và nó chạy
            cho cả SignalR chứ không riêng controller.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Hubs.ChatHub.AgentsGroup">
            <summary>Nhóm gồm mọi nhân viên đang mở trang chat — chỉ dùng cho kênh chế độ <c>Shared</c></summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Hubs.ChatHub.ConversationGroupPrefix">
            <summary>Tiền tố tên nhóm của một hội thoại</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Hubs.ChatHub.ConversationGroup(System.Int32)">
            <summary>Tên nhóm SignalR của một hội thoại. Khai đúng một chỗ để hub và bản đẩy dùng chung.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Hubs.ChatHub.TryParseConversationGroup(System.String)">
            <summary>
            Mã hội thoại đọc ngược từ tên nhóm; <c>0</c> nếu đây không phải nhóm hội thoại.
            Dùng khi thu hồi phòng: sổ kết nối chỉ giữ tên nhóm, không giữ mã.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Hubs.ChatHub.ChannelGroup(System.Int32)">
            <summary>Tên nhóm của một kênh đã bật hàng rào — chỉ người xem được toàn kênh mới ở trong.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Hubs.ChatHub.StaffGroup(System.Int32)">
            <summary>Tên nhóm riêng của một nhân viên — nơi nhận cập nhật của hội thoại mình đang giữ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Hubs.ChatHub.ResolveScopeGroupsAsync(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.SocialChat.ChatChannel})">
            <summary>
            Những nhóm mà một phạm vi được vào — <b>một luật duy nhất</b>, dùng chung cho lúc kết nối
            và cho lúc thu hồi (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatScopeRevoker"/>).
            <para>
            Tách ra vì hai chỗ ấy phải luôn nói cùng một câu: chỗ nào rộng hơn chỗ kia thì hoặc thu
            hồi nhầm phòng đang cần, hoặc để lại phòng lẽ ra phải gỡ.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Hubs.ChatHub.JoinGroupAsync(System.String)">
            <summary>Vào một nhóm và ghi vào sổ kết nối — hai việc luôn đi cùng nhau.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Hubs.ChatHub.JoinConversation(System.Int32)">
            <summary>
            Vào phòng của một hội thoại để nhận tin nhắn của riêng nó.
            Gọi khi nhân viên mở hội thoại trên khung chat.
            <para>
            Chấm phạm vi tại đây, không chỉ chấm role: role nói "được xem chi tiết hội thoại nói
            chung", còn câu hỏi thật là "hội thoại NÀY có thuộc phạm vi của người này không".
            Bỏ qua bước này thì một lời gọi <c>JoinConversation(id)</c> với mã đoán được là đủ để
            nhận mọi tin nhắn của khách người khác theo thời gian thực.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Hubs.ChatHub.LeaveConversation(System.Int32)">
            <summary>Rời phòng của một hội thoại — gọi khi nhân viên chuyển sang hội thoại khác.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Hubs.ChatHub.GetUserId">
            <summary>
            Id nhân viên lấy từ claim — cùng cặp claim mà <c>UserHelper.GetCurrentUser</c> đọc ở
            tầng controller. Giá trị này giờ quyết định phạm vi dữ liệu chứ không còn chỉ để ghi
            nhật ký, nên đọc thiếu một trong hai claim là đẩy người dùng xuống phạm vi rỗng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Hubs.NotificationHub">
            <summary>
            SignalR Hub cho hệ thống thông báo real-time.
            Clients kết nối qua WebSocket, nhận thông báo push.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Hubs.NotificationHub.OnConnectedAsync">
            <summary>
            Khi client kết nối: thêm vào group theo UserId và Roles
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Hubs.NotificationHub.OnDisconnectedAsync(System.Exception)">
            <summary>
            Khi client ngắt kết nối
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Hubs.NotificationHub.MarkAsRead(System.Guid)">
            <summary>
            Client gọi để đánh dấu thông báo đã đọc
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Hubs.NotificationHub.GetUserId">
            <summary>
            Lấy UserId từ claims
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.AdsMetricsSyncJob">
            <summary>
            Hangfire job kéo số liệu quảng cáo theo ngày về LADA cho mọi tài khoản đã bật đồng bộ
            định kỳ (plan cải tổ giao diện quảng cáo, quyết định Q5).
            <para>
            Trước job này số liệu chỉ về khi ai đó bấm "Đồng bộ" (<c>POST report/sync-now</c>) — trên
            production bảng <c>AdsMetricDaily</c> dừng ở 18/08/2026 vì không ai bấm. Job tái dùng đúng
            đường của nút đó (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsMetricService.SyncAllActiveAccountsAsync(System.DateOnly,System.DateOnly,System.Int32,System.String,System.Threading.CancellationToken)"/>): duyệt tuần
            tự từng tài khoản, lỗi một tài khoản không giết cả lô, ghi <c>AdsSyncLog</c> đứng tên
            "System".
            </para>
            <para>
            <b>Khoảng ngày</b>: <see cref="F:Ladaer.BackEnd.Infrastructures.Jobs.AdsMetricsSyncJob.LookbackDays"/> ngày <b>kết thúc ở hôm nay</b>. Kéo lại vài
            ngày cũ vì nền tảng còn cập nhật chuyển đổi muộn; kéo cả hôm nay vì job chạy mỗi 30 phút
            (08/09/2026, trước đó 5:10 sáng hằng ngày và dừng ở hôm qua) — mục đích là thấy hiệu suất
            <b>trong ngày</b>, mà bỏ hôm nay ra thì chạy dày bao nhiêu cũng vẫn là số của hôm qua.
            Bản ghi upsert theo (Level, EntityId, Date) nên chạy lại không sinh dòng trùng, dòng hôm nay
            bị ghi đè lớn dần theo từng lần kéo.
            </para>
            <para>
            <b>Hệ quả cần biết</b>: mốc "Số liệu đến ngày X" trên thanh ngữ cảnh giờ là hôm nay và là số
            <b>dở dang</b> — nền tảng còn cộng thêm tới hết ngày, nên đừng so ngang một ngày đang chạy
            với một ngày đã trọn. Thanh ngữ cảnh đứng cạnh mốc đó có giờ đồng bộ gần nhất để đọc ra điều
            này. Chi phí quota tăng theo số lần chạy (~144 lời gọi/ngày với 3 tài khoản đang bật, thay vì
            3 khi còn chạy mỗi đêm — sổ nợ N-7); lo quota thì tạm dừng từ <c>/tac-vu-nen</c>.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.AdsMetricsSyncJob.LookbackDays">
            <summary>Số ngày nhìn lại mỗi lần chạy, tính cả hôm nay</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.AdsMetricsSyncJob.SystemUserName">
            <summary>Tên ghi vào <c>AdsSyncLog</c> — cùng quy ước với <see cref="T:Ladaer.BackEnd.Infrastructures.Jobs.AdsScheduleReconcileJob"/></summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.AdsMetricsSyncJob.SystemUserId">
            <summary>Id người dùng cho luồng chạy nền — 0 = không phải tài khoản nào cả</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.AdsMetricsSyncJob.Execute">
            <summary>Kéo số liệu <see cref="F:Ladaer.BackEnd.Infrastructures.Jobs.AdsMetricsSyncJob.LookbackDays"/> ngày gần nhất (tính cả hôm nay) cho các tài khoản đang bật đồng bộ định kỳ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.AdsScheduleReconcileJob">
            <summary>
            Hangfire job dò lệch lịch quảng cáo giữa LADA và nền tảng.
            <para>
            Job <b>chỉ đọc và đánh dấu</b>: chiến dịch nào lệch thì bị đặt <c>SyncStatus = OutOfSync</c>
            kèm chi tiết để UI hiện badge "Lịch lệch". Job <b>không</b> tự sửa lịch ở bất kỳ phía nào —
            người dùng mở chiến dịch rồi tự chọn đẩy lịch LADA lên hay kéo lịch nền tảng về.
            </para>
            <para>
            Chạy mỗi ngày một lần vào lúc ít người dùng nhất. Người chạy job không phải người thật nên
            mọi bản ghi <c>AdsSyncLog</c> đứng tên "System" — xem <see cref="F:Ladaer.BackEnd.Infrastructures.Jobs.AdsScheduleReconcileJob.SystemUserName"/>.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.AdsScheduleReconcileJob.SystemUserName">
            <summary>
            Tên người thực hiện ghi vào <c>AdsSyncLog</c>. Dùng "System" giống các luồng chạy nền
            khác của repo để người đọc log phân biệt được ngay việc nào do job, việc nào do người.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.AdsScheduleReconcileJob.SystemUserId">
            <summary>Id người dùng cho luồng chạy nền — 0 = không phải tài khoản nào cả</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.AdsScheduleReconcileJob.Execute">
            <summary>
            Quét toàn bộ chiến dịch đã đẩy lên nền tảng và đánh dấu chiến dịch có lịch lệch.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.AgencyWebEventDailyJob">
            <summary>
            Hangfire job <c>network-gop-su-kien-ngay</c> (docs/plan-buu-cuc.md §3.8, GĐ D): gộp sự kiện thô trang bưu cục công
            khai (<see cref="T:Lada.Framework.Data.Domains.Network.AgencyWebEvent"/>) thành số theo ngày (<see cref="T:Lada.Framework.Data.Domains.Network.AgencyWebEventDaily"/>) — nguồn của báo cáo
            bưu cục và cột "Gọi 30n".
            <para>
            <b>Idempotent</b>: mỗi ngày được XOÁ rồi CHÈN LẠI trong một transaction, nên bấm "Chạy ngay" hai lần, hay job chạy
            lại sau lỗi, ra đúng một bộ số — không cộng dồn. Ngày tính theo giờ Việt Nam bằng khoảng thời điểm
            (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.DayRange(System.DateTime)"/>), không theo ngày của offset đã lưu.
            </para>
            <para>
            Mỗi lần tính lại <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.AggregateWindowDays"/> ngày (hôm qua + 2 ngày trước): máy chủ tắt
            qua 01:10 một hai đêm thì lần chạy kế tiếp tự bù, không cần ai chạy tay. Hôm nay không gộp (còn đang ghi).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.AgencyWebEventDailyJob.Execute">
            <remarks>
            <c>[DisableConcurrentExecution]</c> (review GĐ D): bấm "Chạy ngay" đúng lúc lịch 01:10 đang chạy thì bản sau chờ
            khoá thay vì chạy chồng (hai bản xoá–chèn cùng ngày làm một bản vấp khoá chính và báo đỏ). Mỗi ngày gộp độc lập:
            một ngày lỗi không bỏ các ngày sau (hôm qua vẫn có số) — lỗi ném lại ở cuối để Hangfire thử lại.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.AgencyWebEventDailyJob.AggregateDayAsync(System.DateTime)">
            <summary>
            Tính lại số của MỘT ngày (giờ Việt Nam): xoá mọi dòng <see cref="T:Lada.Framework.Data.Domains.Network.AgencyWebEventDaily"/> của ngày đó rồi chèn
            lại từ sự kiện thô, trong một transaction. Trả số dòng gộp đã chèn.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.AgencyWebEventCleanupJob">
            <summary>
            Hangfire job <c>network-don-su-kien</c> (plan §3.2, §3.8): xoá cứng sự kiện thô trang bưu cục cũ hơn 13 tháng.
            Số gộp theo ngày (<see cref="T:Lada.Framework.Data.Domains.Network.AgencyWebEventDaily"/>) KHÔNG bị dọn — báo cáo tháng cũ vẫn còn số lượt/phiên, chỉ
            mất bảng nguồn truy cập / trang (cần sự kiện thô).
            <para>Mốc cắt là 00:00 giờ Việt Nam — một ngày không bao giờ bị dọn dở nửa.</para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.AnalyticsDimNightlyJob">
            <summary>
            Hangfire job <c>analytics-nap-dim-dem</c> (docs/plan-mcp-tra-cuu-so-lieu.md §3.3, GĐ A): nạp lại bảy bảng danh mục
            <c>analytics.Dim*</c> cho MCP số liệu — chi nhánh, địa danh, loại hàng, đội xe (không biển số), dải cự ly, bảng giá
            công khai, tham số cước. Idempotent (xoá–chèn trong một transaction), mỗi lượt ghi một dòng <c>analytics.LoadRun</c>.
            </summary>
            <remarks>
            Công tắc <c>Analytics:Enabled</c> TẮT thì job không làm gì (log một dòng) — trên production tính năng tắt tới khi qua
            nghiệm thu GĐ D. Chạy 1:20 sáng, trước job nạp fact vận đơn (1:30, GĐ B) để fact luôn gặp danh mục mới.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.AnalyticsDimNightlyJob.Execute">
            <remarks>
            <c>[DisableConcurrentExecution]</c>: bấm "Chạy ngay" đúng lúc lịch đang chạy thì bản sau chờ khoá thay vì hai bản
            xoá–chèn chồng nhau. Lỗi ném lại để Hangfire thử lại (dòng LoadRun đã ghi failed).
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.AnalyticsShipmentFactJob">
            <summary>
            Hangfire job nạp fact cho MCP số liệu (docs/plan-mcp-tra-cuu-so-lieu.md §3.3): fact vận đơn <c>analytics.ShipmentFact</c>
            (GĐ B), NGAY SAU ĐÓ điểm dừng ước lượng <c>analytics.StopFact</c> (GĐ C — dựng từ fact vận đơn vừa nạp), rồi lần đổ dầu
            <c>analytics.FuelFact</c> (GĐ D), lượt qua trung tâm khai thác <c>analytics.HubEventFact</c> và khiếu nại <c>analytics.ComplaintFact</c>
            (GĐ E — ba bảng này luôn dựng lại cả cửa sổ) — MỘT phương thức cho cả hai lịch: <c>analytics-nap-fact-dem</c>
            (<see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadMode.Nightly"/>, 1:30 sáng, sau danh mục 1:20) và <c>analytics-nap-lai-400-ngay</c>
            (<see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadMode.Rebuild"/>, bấm tay).
            </summary>
            <remarks>
            Chung một phương thức là CỐ Ý: khoá <c>[DisableConcurrentExecution]</c> của Hangfire đặt theo lớp + phương thức, nên
            bấm "Nạp lại 400 ngày" đúng lúc job đêm đang chạy thì bản sau chờ khoá thay vì hai lượt xoá–chèn cùng lô đơn chồng nhau.
            Điểm dừng nằm CHUNG job (không lịch riêng) vì nó đọc fact vận đơn: chạy sau trong cùng khoá là chắc chắn gặp fact mới, và
            đổi <c>Analytics.StopGapMinutes</c> xong chỉ cần bấm một job nạp lại. Chữ ký <c>Execute(mode)</c> giữ nguyên để lịch đã đăng
            ký trong Hangfire không vỡ. Công tắc <c>Analytics:Enabled</c> TẮT thì không làm gì. Lỗi ném lại để Hangfire thử lại (dòng
            LoadRun đã ghi failed; cả hai builder idempotent).
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.AnalyticsCallLogCleanupJob">
            <summary>
            Hangfire job <c>analytics-don-log-12-thang</c> (plan §3.10): xoá <c>dbo.AnalyticsCallLog</c> cũ hơn 12 tháng — yêu cầu §6
            "log lời gọi giữ 12 tháng". Xoá theo lô để không phình log giao dịch. Hằng tuần; bỏ qua khi <c>Analytics:Enabled</c> tắt.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.AttendanceMaintenanceJob">
            <summary>
            Hangfire job bảo trì chấm công: tự đóng các ca treo (lái xe quên chấm ra)
            bằng thời điểm hoạt động giao/lấy hàng muộn nhất TRONG CỬA SỔ CA (trần 20h).
            Chạy hàng ngày lúc ~3:00 AM, quét toàn bộ ca treo bất kể cũ đến đâu.
            </summary>
            <remarks>
            ⚠ Từ 16/08/2026 job không còn bị giới hạn "48h gần đây" nữa. Đêm đầu tiên sau khi bản vá GĐ A
            lên production, nó sẽ đóng phần tồn cũ (147/166 ca treo đo trên DB dev 16/08/2026) và qua đó
            LÀM THAY ĐỔI số công/kíp của kỳ lương đang Draft. Vì vậy việc chụp bảng lương và báo kế toán
            phải làm TRƯỚC khi deploy GĐ A, không phải trước khi chạy migration backfill của GĐ B —
            xem docs/plan-sua-cham-cong-trung.md §4.1.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.AutoPenaltyJob">
            <summary>
            Hangfire job tự động phát hiện vi phạm nộp tiền trễ và sinh phiếu phạt.
            Chạy định kỳ (VD: mỗi 30 phút).
            Sử dụng EarliestCollectedTime (thời gian thu tiền sớm nhất) thay vì BusinessDate cố định.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.AutoPenaltyJob._franchiseLedger">
            <summary>
            Ví bưu cục v2: tiền người của bưu cục nhượng quyền bật ví cầm trên đơn Ví ghi không nộp LADA (Quỹ từ chối — V-05), nên stage
            không bao giờ về Tổng — không được tính là nợ nộp trễ. Null khi dựng không có ví.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.AutoPenaltyJob.Execute">
            <summary>
            Execute job - phát hiện vi phạm nộp tiền trễ dựa trên thời gian thu tiền sớm nhất
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.AutoPenaltyJob.GetCashierDebts">
            <summary>
            Lấy DS người đang cầm tiền từ OrderFin (kèm EarliestCollectedTime)
            Không filter theo ngày — lấy tất cả đơn đang cầm (stage giữa NotCollected và Head)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.AutoPenaltyJob.ComputeCashierDebts(System.Collections.Generic.IEnumerable{System.ValueTuple{Lada.Framework.Data.Domains.Orders.OrderFin,System.Nullable{System.DateTimeOffset}}},System.Collections.Generic.IReadOnlyDictionary{System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletHolder})">
            <summary>
            Cộng nợ theo người cầm tiền: mọi khoản có thời điểm thu và stage giữa "Chưa thanh toán" và "Tổng đã thu". Hàm thuần.
            Ví bưu cục v2: khoản của người thuộc bưu cục nhượng quyền bật ví trên đơn Ví ghi (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletHolder.Covers(System.Nullable{System.DateTimeOffset})"/>
            — cùng mốc màn Quỹ / <c>CollectCashier</c>) KHÔNG tính: tiền đó đã thuộc bưu cục, Quỹ LADA từ chối thu nên stage đứng mãi ở
            "Lái xe đang cầm" — tính vào là phạt nộp trễ khoản không bao giờ nộp được. Từ V-60 khoản đó chuyển sang "Bưu cục giữ" — loại theo
            stage, không chỉ dựa vào người cầm: cước lấy / giao đứng mãi ở 10 nên người chuyển chi nhánh / ví tắt sau khi thu vẫn không bị phạt.
            COD đi tiếp 10 → 11 / 12 khi đối soát khách mà <c>CodCashierId</c> giữ nguyên — khoản 12 chỉ còn được loại nhờ <c>Covers</c>
            (sổ nợ V-70).
            </summary>
            <param name="rows">Dòng tài chính kèm thời điểm tạo đơn.</param>
            <param name="walletHolders">Người cầm tiền thuộc bưu cục nhượng quyền bật ví, theo UserId.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.AutoPenaltyJob.UpdateEarliestTime(System.Collections.Generic.Dictionary{System.Int32,System.DateTimeOffset},System.Int32,System.DateTimeOffset)">
            <summary>
            Cập nhật thời gian thu tiền sớm nhất cho cashier
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.AutoPenaltyJob.CalculateAmountPaid(System.Int32,System.DateTimeOffset)">
            <summary>
            Tính tổng tiền đã nộp trước deadline từ Transaction
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Jobs.AutoPenaltyJob.CashierDebt.EarliestCollectedTime">
            <summary>
            Thời gian thu tiền sớm nhất trong các đơn đang cầm
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.BotVisitCleanupJob">
             <summary>
             Dọn bảng <c>BotVisitDaily</c> — xoá hẳn những ngày đã quá
             <c>Search.BotVisit.RetentionDays</c> (mặc định 90).
            
             <para>
             <b>Job này ra đời cùng lượt thay đổi tạo ra bảng nó dọn</b>, không để lại thành việc phải nhớ.
             Bảng <c>AdsSyncLog</c> của miền quảng cáo đã cho thấy hậu quả của cách làm ngược lại (nợ Ads
             N-7).
             </para>
            
             <para>
             <b>Vì sao bảng này dọn còn <c>SearchMetricDaily</c> thì không.</b> Số liệu hiệu suất tìm kiếm
             là thứ Google xoá mất sau 16 tháng — giữ lại bản của mình là toàn bộ lý do kéo nó về. Lượt bot
             thì ngược lại: nó trả lời "bot nào đang ghé, ghé những đâu", một câu hỏi luôn về hiện tại. Hai
             bảng cùng hình dạng nhưng khác bản chất, nên đừng chép quyết định của bảng này sang bảng kia.
             </para>
            
             <para>
             <b>Xoá cứng, không xoá mềm.</b> Chỉ số duy nhất <c>(Date, Bot, Path)</c> không lọc theo
             <c>IsDeleted</c>, nên một dòng xoá mềm vẫn chiếm chỗ và sẽ chặn lượt ghi của đúng bộ ba ấy nếu
             ngày cũ quay lại (kéo bù, sửa tay). Dọn ở đây cũng không có gì để khôi phục: đây là số đếm gộp,
             không phải chứng từ.
             </para>
            
             <para>
             Không gọi ra ngoài nên tự đăng ký khi khởi động, cùng nhóm với <c>SearchApiLogCleanupJob</c>.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.BotVisitCleanupJob.Execute">
            <summary>Xoá hẳn các ngày đã quá hạn giữ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.ChatDecisionCleanupJob">
            <summary>
            Hangfire job dọn nhật ký quyết định phân phối cũ hơn 180 ngày (giai đoạn D).
            <para>
            Bảng <see cref="T:Lada.Framework.Data.Domains.SocialChat.ChatAssignmentDecision"/> là append-only và ghi <b>một dòng cho mỗi lượt máy
            chạy</b>, kể cả lượt không ai nhận. Ở quy mô đích nó lớn nhanh hơn hẳn bảng phân công, mà
            giá trị của nó thì hết hạn: câu hỏi "sao hôm qua tôi không được chia khách" đáng trả lời,
            câu hỏi ấy về một ngày cách đây một năm thì không.
            </para>
            <para>
            <b>Xoá cứng, không xoá mềm.</b> Xoá mềm ở đây chẳng dọn được gì — dòng vẫn nằm đó, chỉ số
            vẫn phình — trong khi bảng này không phải bằng chứng nghiệp vụ cần đối soát về sau: bằng
            chứng ấy là <c>ChatConversationAssignment</c>, và bảng đó không bị dọn.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.ChatDecisionCleanupJob.RetentionDays">
            <summary>Giữ lại bấy nhiêu ngày — §3.2 chốt 180</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.ChatHistorySyncJob">
            <summary>
            Hangfire job kéo lịch sử hội thoại chat MỚI từ nền tảng về để bù tin webhook không chở tới — ca
            gốc là tin Page trả lời riêng từ bình luận Facebook. Toàn bộ luật nằm ở
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatHistorySyncService"/>; job chỉ gọi và ghi nhật ký.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.ChatHistorySyncJob.Execute">
            <summary>
            <c>[DisableConcurrentExecution]</c>: bấm "Chạy ngay" ở /tac-vu-nen đúng lúc lịch đang chạy thì hai
            lượt cùng chèn một tin vào cùng một hội thoại. <c>[AutomaticRetry(Attempts = 0)]</c>: lượt hỏng
            không cần Hangfire chạy lại — hội thoại gặp lỗi tạm vẫn chưa đánh dấu, lượt sau một phút tự nhặt.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.ChatMediaArchiveJob">
            <summary>
            Hangfire job lưu tệp đính kèm chat (ảnh, video, tin thoại, tệp) từ CDN Zalo/Facebook về máy chủ
            LADA — sổ nợ SC-9. Toàn bộ luật nằm ở <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatMediaArchiveService"/>; job chỉ gọi và ghi nhật ký.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.ChatMediaArchiveJob.Execute">
            <summary>
            <c>[DisableConcurrentExecution]</c>: bấm "Chạy ngay" ở /tac-vu-nen đúng lúc lịch đang chạy thì hai
            lượt cùng tải một tệp và cùng ghi một tin. <c>[AutomaticRetry(Attempts = 0)]</c>: lượt hỏng
            không cần Hangfire chạy lại — lượt kế tiếp 5 phút sau tự nhặt các tin còn chờ, và đếm lần thử
            đã nằm trong từng tin.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.ChatQualityRecomputeJob">
            <summary>
            Hangfire job tính lại điểm chất lượng chat của toàn bộ sale đang phụ trách kênh. Chạy 03:20
            hằng ngày trên cửa sổ trượt 30 ngày (giai đoạn F).
            <para>
            <b>Job này không đổi hành vi phân phối.</b> Nó chỉ ghi hai bảng điểm; điểm có được dùng hay
            không nằm ở công tắc <c>Chat.Quality.AffectsDistribution</c> (mặc định TẮT) mà máy phân phối
            đọc. Tách như thế để điểm được tính và quan sát được <b>trước</b> khi nó có hiệu lực — không
            có bước ấy thì không cách nào đối chiếu trước lúc bật.
            </para>
            <para>
            <b>Vì sao chạy đêm chứ không tính lúc phân phối.</b> Máy phân phối chạy trên đường nóng nhất
            của hệ thống (mỗi tin của khách vào một hội thoại chưa ai giữ); tính trung vị thời gian phản
            hồi 30 ngày ở đúng chỗ ấy là đặt một phép quét bảng tin nhắn vào giữa đường webhook. §3.6
            chốt: máy phân phối <b>chỉ đọc</b> <c>ChatQualitySummary</c>.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.ChatQueueSweepJob">
            <summary>
            Hangfire job quét hàng chờ chat: thử phân phối lại hội thoại chưa ai nhận và báo trưởng
            nhóm khi khách chờ quá lâu. Chạy mỗi 2 phút (giai đoạn D).
            <para>
            <b>Vì sao cần job dù máy đã chạy trên webhook.</b> Máy phân phối chạy đúng lúc tin của
            khách đến; nếu lúc ấy không ai đủ điều kiện — ngoài giờ làm, cả đội đang bận, kênh chưa xếp
            ai phụ trách — thì hội thoại vào hàng chờ và <b>không có sự kiện nào</b> đưa nó ra. Số đo
            D0-5 đếm được <b>12/62</b> hội thoại trên dev có tin đầu tiên rơi ngoài giờ làm, tức khoảng
            một phần năm lưu lượng phụ thuộc hoàn toàn vào lượt quét này.
            </para>
            <para>
            Chu kỳ 2 phút là con số của §3.3, và nó rẻ: số đo Đ4 đếm 21 hội thoại/ngày, nên mỗi lượt
            quét gần như luôn chạy trên một hàng chờ rỗng.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.ChatSlaSweepJob">
            <summary>
            Hangfire job quét hạn phản hồi chat: nhắc người đang giữ khi khách chờ quá lâu, thu hồi và
            chia lại khi chờ lâu hơn nữa. Chạy mỗi 2 phút (giai đoạn E).
            <para>
            <b>Vì sao cần.</b> Giai đoạn D dựng máy tự chia khách, nhưng chia xong rồi thì không ai canh
            nữa — một hội thoại giao cho người đang bận rồi để đó ba tiếng thì hệ thống hoàn toàn im
            lặng. Không có sự kiện nào phát ra khi <i>không có gì xảy ra</i>, nên chỉ một lượt quét theo
            đồng hồ mới phát hiện được.
            </para>
            <para>
            <b>Công tắc <c>Chat.Sla.Enabled</c> mặc định TẮT.</b> Job vẫn đăng ký và vẫn chạy — nó còn
            mang việc dọn trạng thái hết hạn (PP-26, PP-27) vốn không phụ thuộc công tắc — nhưng phần
            nhắc và thu hồi im lặng cho tới khi người vận hành bật. Lý do ở
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaConfigKeys.Enabled"/>: bật sớm là trộn hai hiệu ứng vào bảng đối chiếu của
            cổng D2.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.ChatTokenRefreshJob">
            <summary>
            Hangfire job làm mới access token của các kênh chat sắp hết hạn. Chạy mỗi giờ.
            <para>
            Vì sao phải có job thay vì làm mới lúc gửi tin: access token của Zalo sống 25 giờ, còn
            refresh token sống 3 tháng và <b>chỉ dùng được một lần</b>. Để token hết hạn rồi mới chữa
            thì kênh đã chết một quãng, mà chết im lặng — không có lỗi nào cho tới khi nhân viên bấm gửi.
            </para>
            <para>
            Ngưỡng 2 giờ với chu kỳ 1 giờ nghĩa là mỗi token có ít nhất hai lượt để được làm mới trước
            khi hết hạn: một lượt hỏng vì mạng vẫn còn lượt sau.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.ChatTokenRefreshJob.RefreshThreshold">
            <summary>Làm mới khi token còn hạn dưới ngưỡng này</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.ContentStoreDcrCleanupJob">
            <summary>
            Hangfire job dọn client OAuth do <b>đăng ký động (DCR)</b> tạo ra mà không còn ai dùng, cùng với
            token và authorization đã hết hiệu lực (sổ nợ <b>CS-16</b>).
            </summary>
            <remarks>
            <para>
            <b>Vì sao cần.</b> <c>POST /connect/register</c> là mặt công khai rộng nhất của đợt này:
            <b>không cần đăng nhập</b>, ai gọi cũng được, và mỗi lời gọi hợp lệ tạo <b>một dòng mới</b> trong
            <c>OpenIddictApplications</c>. Claude và ChatGPT tự đăng ký lại mỗi lần kết nối, nên bảng đó phình
            cả khi không có ai phá. Chặn duy nhất hiện có là rate limit 10 lời gọi/phút/IP — tức vẫn 14.400
            dòng/ngày/IP nếu ai đó muốn. Không có lượt dọn thì đây là đường làm đầy database mà không cần một
            tài khoản nào.
            </para>
            <para>
            <b>Ba lớp an toàn để không xoá nhầm.</b> (1) Chỉ đụng client có thuộc tính <c>dcr</c> — client khai
            tay không có nó và <b>không bao giờ</b> bị xoá. (2) Chỉ xoá client đã quá hạn giữ. (3) Chỉ xoá khi
            <b>không còn</b> authorization hay token nào trỏ tới — nghĩa là không ai đang dùng, và cũng tránh
            vỡ khoá ngoại. Luật quyết định nằm ở <see cref="T:Ladaer.BackEnd.Infrastructures.Jobs.DcrCleanupPolicy"/>, có ca test riêng.
            </para>
            <para>
            <b>Thứ tự cố ý:</b> dọn token và authorization <i>trước</i>, rồi mới xét client. Làm ngược lại thì
            client nào cũng "còn token" vì token hết hạn vẫn nằm đó, và job không bao giờ xoá được gì.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.ContentStoreDcrCleanupJob.GiuTokenNgay">
            <summary>Token / authorization hết hiệu lực cũ hơn bấy nhiêu ngày thì dọn.</summary>
            <remarks>
            14 ngày là đúng hạn refresh token dài nhất (<c>ContentStore:OAuth:RefreshTokenDays</c> mặc định
            14) — dọn sớm hơn là cắt phiên của người đang dùng.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.ContentStoreDcrCleanupJob.GiuClientNgay">
            <summary>Client DCR không còn ai dùng và cũ hơn bấy nhiêu ngày thì xoá.</summary>
            <remarks>
            30 ngày, rộng hơn hẳn hạn token: một client vừa đăng ký xong mà người dùng chưa kịp bấm đồng ý
            thì chưa có authorization nào — xoá nó ngay là làm hỏng lượt kết nối đang dở.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.ContentStoreDcrCleanupJob.TranMoiLuot">
            <summary>Trần số client xét mỗi lượt — để một bảng đã phình không làm lượt chạy kéo dài vô hạn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.DcrCleanupPolicy">
            <summary>
            Luật quyết định xoá client DCR — hàm thuần, không chạm OpenIddict, có ca test riêng.
            </summary>
            <remarks>
            Tách ra vì đây là chỗ duy nhất của job <b>xoá dữ liệu</b>: một điều kiện viết lỏng tay ở đây là
            xoá mất client khai tay hoặc cắt phiên của người đang dùng, mà cả hai chỉ lộ ra ở production.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.DcrCleanupPolicy.ThuocTinhDcr">
            <summary>Tên thuộc tính mà <c>McpClientRegistrationService</c> đóng dấu lên client do DCR tạo.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.DcrCleanupPolicy.DocNgayTaoDcr(System.Collections.Generic.IReadOnlyDictionary{System.String,System.Text.Json.JsonElement})">
            <summary>
            Ngày đăng ký của một client DCR, hoặc <c>null</c> nếu <b>không phải</b> client DCR (hoặc dấu
            đóng bị hỏng) — và <c>null</c> nghĩa là <b>không được xoá</b>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.DcrCleanupPolicy.CoTheXoa(System.Nullable{System.DateTimeOffset},System.Int32,System.Int32,System.DateTimeOffset)">
            <summary>
            Xoá được khi: là client DCR, đăng ký trước <paramref name="moc"/>, và <b>không còn</b>
            authorization lẫn token nào trỏ tới.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.ContentStoreSyncPublishedJob">
            <summary>
            Hangfire job đồng bộ trạng thái đăng của kho nội dung: bài đã có <c>PostId</c> mà <c>Post</c> đã
            <c>Đã đăng</c> trong CMS ⇒ bài chuyển sang <c>Đã đăng</c>. Chạy mỗi 15 phút (plan §3.7 bước 5).
            <para>
            <b>Vì sao cần job dù đường xuất bản đã biết mình vừa tạo Post gì.</b> Đường mặc định (§7.11) tạo
            <c>Post</c> ở <c>Chờ xuất bản</c> rồi trả bài lại cho CMS cũ. Người bấm "Đăng" ở đó là người trong
            màn CMS, và <b>CMS không biết gì về kho nội dung</b> — không có sự kiện nào chạy ngược về. Không có
            lượt quét này thì bài nằm mãi ở "Đã duyệt" trong khi nó đã lên website từ lâu, và mọi con số
            thống kê của kho nội dung đọc sai.
            </para>
            <para>
            15 phút là con số của plan, và nó rẻ: mỗi lượt là một phép nối hai bảng lọc theo hai trạng thái,
            gần như luôn trả về rỗng. Người vận hành không muốn chờ thì bấm
            <c>POST /api/ContentPublish/SyncPublishedStatus</c>.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.FranchiseLedgerRecheckJob">
            <summary>
            Job đêm <c>franchise-ledger-recheck</c> (SPEC §3.5, M19): đối chiếu lại Ví của các đơn có cập nhật trong
            <c>FranchiseWallet.RecheckDays</c> ngày gần nhất dính tới bưu cục nhượng quyền, cộng các đơn còn vấn đề mở — bù dòng bị
            sót khi móc sự kiện lỗi, ghi phải thu / phải nộp cho tiền thu ở màn thu ngân, đóng dấu đơn từ app khách. Idempotent.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.FranchiseLedgerRecheckJob.Execute">
            <summary>Chạy một lượt.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.FranchiseSettlementMonthlyJob">
            <summary>
            Job <c>franchise-settlement-monthly</c> (SPEC §3.6): sáng mùng 1 lập NHÁP phiếu đối soát kỳ tháng trước cho mỗi ví có
            dòng chốt trong kỳ. Không phát hành — kế toán xem, điều chỉnh rồi bấm phát hành.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.FranchiseSettlementMonthlyJob.Execute">
            <summary>Lập nháp kỳ trước (theo giờ Việt Nam).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.FranchiseSettlementAutoConfirmJob">
            <summary>Job <c>franchise-settlement-auto-confirm</c>: tự xác nhận phiếu quá hạn 3 ngày làm việc (TS10, SPEC M9).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.FranchiseSettlementAutoConfirmJob.Execute">
            <summary>Chạy một lượt.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.InternalNewsScheduleJob">
            <summary>
            Job <c>internal-news-schedule</c> (docs/plan-bang-tin-noi-bo.md §3.7): 5 phút một lần (1) đăng bài hẹn giờ đã tới
            giờ — gọi ĐÚNG đường đăng của service (ảnh chụp + chuông), không chép logic; (2) chuyển bài quá <c>ExpiresAt</c>
            sang Đã lưu trữ. Mỗi lần đổi trạng thái là một UPDATE có điều kiện theo trạng thái + mốc sửa cuối, nên hai lần chạy
            chồng không đăng hai lần và không gửi chuông hai lần. Chưa có bài nào thì no-op.
            </summary>
            <remarks>
            Mỗi bài đăng trong một phạm vi DI RIÊNG: chuông của một bài lỗi để lại thực thể hỏng trong DbContext, dùng chung
            một context thì mọi bài sau trong cùng lượt cũng lỗi chuông theo (review GĐ A).
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.InternalPriceEffectiveReminderJob">
            <summary>
            Job <c>internal-price-effective-reminder</c> (SPEC §3.11): 08:00 hằng ngày nhắc bưu cục về bản giá nội bộ bắt đầu áp dụng
            sau đúng <c>InternalPrice.ReminderDaysBefore</c> ngày, và phiếu đối soát có hạn xác nhận là hôm nay (quá hôm nay hệ thống
            tự xác nhận).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.InternalPriceEffectiveReminderJob.Execute">
            <summary>Chạy một lượt (ngày theo giờ Việt Nam).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.KpiPeriodCloseJob">
            <summary>
            Job chốt kỳ KPI — chạy sáng sớm mùng 1 hằng tháng, chốt kỳ THÁNG VỪA QUA (plan §3.4).
            </summary>
            <remarks>
            <para>
            Job cố ý mỏng: toàn bộ luật nằm ở <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodCloseService"/> để đường thủ công và
            đường tự động không thể ra hai kết quả khác nhau.
            </para>
            <para>
            <b>Job không được ném ra ngoài</b> (§3.9d). Khác các job khác của repo vốn <c>throw</c> lại
            cho Hangfire retry: ở đây một lần chạy có thể đã ghi <c>KpiResult</c> cho hàng trăm chỉ tiêu,
            nên retry tự động không phải là "chạy lại từ đầu" mà là "chạy lại phần còn lại" — service đã
            idempotent nên vẫn an toàn, nhưng ném ra rồi retry liên tục chỉ làm nhiễu log mà không sửa
            được nguyên nhân thật (nguồn dữ liệu hỏng). Lỗi từng dòng đã được service gói vào tổng kết;
            lỗi hạ tầng thì log ERROR để người quản trị vào chốt lại thủ công trong cửa sổ cho phép.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.KpiPeriodCloseJob.SystemUser">
            <summary>
            Tài khoản đứng tên chốt khi job tự chạy — 0 là quy ước tài khoản hệ thống của repo
            (script seed migration cũng ghi <c>CreatedBy = 0, CreatedByUserName = 'SYSTEM'</c>)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.NotificationCleanupJob">
            <summary>
            Hangfire job dọn dẹp thông báo cũ hơn 90 ngày.
            Chạy hàng ngày lúc 2:00 AM.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.NotificationCleanupJob.RetentionDays">
            <summary>
            Số ngày giữ lại thông báo (retention policy)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.PromotionBudgetAlertJob">
            <summary>
            Hangfire job kiểm tra ngân sách chương trình KM. Chạy hàng ngày.
            Cảnh báo khi ngân sách sử dụng >= 80%.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.PromotionCashbackJob">
            <summary>
            Hangfire job hoàn ví cuối kỳ. Chạy đầu mỗi tháng, tổng hợp đơn thành công tháng trước
            → tính hoàn thưởng theo RewardRule → credit vào PromotionWallet.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.PromotionExpirationJob">
            <summary>
            Hangfire job kiểm tra chương trình KM hết hạn → chuyển status Expired.
            Chạy hàng ngày.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.RecurringJobDefinition">
            <summary>
            Một tác vụ định kỳ mà hệ thống biết cách đăng ký lại: id, lịch mặc định và biểu thức gọi job.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Jobs.RecurringJobDefinition.Id">
            <summary>Id trong Hangfire, ví dụ notification-cleanup.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Jobs.RecurringJobDefinition.DisplayName">
            <summary>Tên hiển thị tiếng Việt trên trang Tác vụ nền.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Jobs.RecurringJobDefinition.Description">
            <summary>Job làm gì, vì sao chạy vào giờ đó.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Jobs.RecurringJobDefinition.Cron">
            <summary>Cron 5 trường theo múi giờ Việt Nam.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Jobs.RecurringJobDefinition.JobName">
            <summary>Tên lớp.phương thức, để trang hiển thị cả khi job chưa đăng ký.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Jobs.RecurringJobDefinition.AutoRegister">
            <summary>
            true: tự đăng ký khi API khởi động (trừ khi đã bị tạm dừng).
            false: chỉ đăng ký khi người vận hành bấm "Đăng ký" trên trang Tác vụ nền.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Jobs.RecurringJobDefinition.Register">
            <summary>Đăng ký (hoặc cập nhật) job này vào Hangfire với lịch mặc định.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.RecurringJobCatalog">
            <summary>
            Danh mục tác vụ định kỳ của hệ thống + cờ "tạm dừng" lưu trong storage Hangfire.
            <para>
            Hangfire lưu lịch trong DB, nên xoá/comment dòng <c>AddOrUpdate</c> trong code KHÔNG gỡ job —
            nó vẫn chạy đều cho tới khi có ai gọi <c>RemoveIfExists</c>. Danh mục này là nguồn sự thật duy nhất
            về job nào tồn tại, chạy lịch gì; trang /tac-vu-nen đọc nó để cho phép tạm dừng / đăng ký lại.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.RecurringJobCatalog.PausedSetKey">
            <summary>
            Set trong storage Hangfire chứa id các job đã bị tạm dừng từ trang Tác vụ nền.
            Đặt cùng chỗ với dữ liệu Hangfire để production và dev không cần thêm bảng hay migration.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.RecurringJobCatalog.Find(System.String)">
            <summary>
            Tìm định nghĩa theo id; null nếu job không nằm trong danh mục (job mồ côi do code cũ để lại).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.RecurringJobCatalog.GetPausedIds(Hangfire.JobStorage)">
            <summary>
            Id các job đã bị tạm dừng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.RecurringJobCatalog.SetPaused(Hangfire.JobStorage,System.String,System.Boolean)">
            <summary>
            Ghi / gỡ cờ tạm dừng cho một job.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.RecurringJobCatalog.RegisterAutoJobs(Hangfire.IRecurringJobManager,Hangfire.JobStorage)">
            <summary>
            Gọi lúc API khởi động: đăng ký mọi job <see cref="P:Ladaer.BackEnd.Infrastructures.Jobs.RecurringJobDefinition.AutoRegister"/>,
            trừ job đã bị tạm dừng — job đó bị gỡ khỏi lịch để chắc chắn không chạy.
            Trả về từng dòng mô tả để ghi log.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.SearchAnalyticsBackfillJob">
             <summary>
             Kéo bù <b>toàn bộ lịch sử</b> Google còn giữ — một việc chạy đúng một lần, bấm tay.
            
             <para>
             <b>Số tháng để rộng hơn mức Google công bố, có chủ đích.</b> Google nói giữ 16 tháng, nhưng đo
             thật 2026-09-16 thì dữ liệu đi xa tới 16,4 tháng lịch. Kéo đúng 16 sẽ bỏ lại 12 ngày cũ nhất —
             đúng phần dễ mất nhất. Mặc định là 17, và phần thừa không tốn gì vì job dừng sau hai lô rỗng.
             </para>
            
             <para>
             <b>Vì sao là một job riêng chứ không phải một nhánh của job hằng ngày.</b> Lượt này đi ngược
             16 tháng, chia thành ~17 lô 30 ngày × 4 mức ≈ 68 lời gọi và mất vài phút. Nhét nó vào job hằng
             đêm thì hoặc nó chạy lại vô ích mỗi đêm, hoặc phải có một cờ "đã chạy chưa" cất ở đâu đó — mà
             một cờ như thế luôn là thứ bị đặt sai ở lần deploy tiếp theo. Tách ra thì việc bật/tắt chính là
             việc bấm hay không bấm.
             </para>
            
             <para>
             <b>Chạy lại được bao nhiêu lần cũng không hỏng gì.</b> Khoá upsert
             <c>(Engine, Level, Date, DimensionHash)</c> làm lượt thứ hai ghi đè lượt thứ nhất thay vì nhân
             đôi. Nó chỉ tốn lời gọi, nên vẫn nên bấm một lần rồi thôi.
             </para>
            
             <para>
             <b>Cron đặt vào 29/02 lúc 03:03 — ngày hiếm nhất có thể, chứ KHÔNG phải một ngày không tồn
             tại.</b> Bản ghi chú đầu tiên ở đây viết là "một ngày không tồn tại", và điều đó <b>sai</b>:
             29/02 có thật trong năm nhuận, lần tới là 2028. Thứ thật sự giữ job này không tự chạy là
             <c>autoRegister: false</c>; cron chỉ là lớp phòng thứ hai. Nếu có ai lỡ đăng ký thì hậu quả
             duy nhất là một lượt kéo thừa vào một ngày 29/02 — vô hại, vì kéo lại không sinh dòng trùng.
             </para>
            
             <para>
             <b>Dừng ngay khi một lô hỏng.</b> Đi tiếp sau một lỗi sẽ để lại một khoảng trống ở giữa lịch
             sử mà không ai biết là trống — và bảng số liệu thì không có cách nào phân biệt "tháng ấy không
             có lưu lượng" với "tháng ấy chưa kéo được". Dừng lại thì lần bấm sau kéo tiếp từ chỗ dở.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchAnalyticsBackfillJob.ChunkDays">
            <summary>
            Độ dài một lô. 30 ngày vì đo 2026-09-16: lô nhiều dòng nhất (tháng 5/2025) trả 13.657 dòng
            ở mức mịn nhất — quá nửa trần 25.000 dòng của một lời gọi, nhưng vẫn trong một trang. Lô
            rộng hơn sẽ thường xuyên phải phân trang; hẹp hơn thì tốn thêm lời gọi vô ích.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchAnalyticsBackfillJob.MaxChunks">
            <summary>
            Trần số lô cho <b>một</b> lượt bấm. 16 tháng ≈ 17 lô; 40 là dây an toàn chống vòng lặp,
            không phải một giới hạn nghiệp vụ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.SearchAnalyticsPullJob">
             <summary>
             Kéo số liệu hiệu suất tìm kiếm của <b>những ngày gần nhất đã chốt</b> về bảng
             <c>SearchMetricDaily</c>.
            
             <para>
             <b>Vì sao cửa sổ trượt chứ không phải "kéo hôm qua".</b> Google chốt số chậm vài ngày, và còn
             sửa lại số của những ngày đã chốt gần nhất. Kéo đúng một ngày rồi thôi là giữ mãi một con số
             tạm thời — và sai vĩnh viễn, vì lượt sau sẽ không bao giờ quay lại ngày đó. Kéo lại một cửa sổ
             10 ngày mỗi đêm thì mỗi ngày được ghi đè 10 lần trước khi trôi ra khỏi tầm với, và khoá upsert
             làm việc ghi đè ấy không sinh dòng trùng.
             </para>
            
             <para>
             <b>Job này KHÔNG kéo bù lịch sử.</b> Lượt kéo 16 tháng là một việc chạy đúng một lần, kéo dài
             vài chục lời gọi — nhét nó vào job hằng đêm thì hoặc nó chạy lại vô ích mỗi đêm, hoặc phải có
             một cờ "đã chạy chưa" nằm đâu đó. Tách thành <see cref="T:Ladaer.BackEnd.Infrastructures.Jobs.SearchAnalyticsBackfillJob"/> bấm tay.
             </para>
            
             <para>
             <b>Chạy lúc 05:23.</b> Lệch khỏi phút tròn và khỏi giờ tròn cùng lý do với các job khác của
             miền này: không xếp hàng cùng lúc với mọi job khác trong hệ thống. Sau 05:00 vì lượt kéo này
             đọc số của những ngày đã qua hẳn, không có gì phải chờ.
             </para>
            
             <para>
             Khai <c>autoRegister: false</c> như ba job gọi Google khác: sau khi deploy nó tồn tại nhưng
             không tự chạy, cho tới khi người vận hành bấm "Đăng ký" ở trang Tác vụ nền. Công tắc
             <c>Search.Google.Enabled</c> còn tắt thì kể cả có đăng ký nó cũng không gọi gì ra ngoài.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchAnalyticsPullJob.TinhCuaSo(System.Int32)">
             <summary>
             Khoảng ngày của lượt chạy này: <c>[hôm nay − N, hôm nay − 1]</c>.
            
             <para>
             Không cần trừ thêm độ trễ chốt số của Google: client viết cứng <c>dataState=final</c>, nên
             những ngày chưa chốt đơn giản là <b>không được trả về</b>. Đo 2026-09-16: hỏi tới hôm nay
             thì <c>final</c> trả tới T−3, không trả T−2 và T−1. Hỏi rộng hơn thực tế chỉ tốn đúng một
             khoảng trống trong phản hồi, còn hỏi hẹp hơn thì có ngày không bao giờ được kéo.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchAnalyticsPullJob.MoTaSoNgay(Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult)">
             <summary>
             Câu nói ra <b>ý nghĩa</b> của con số 0, thay vì để người đọc tự đoán.
            
             <para>
             Ở miền này có ba cách ra số 0 khác hẳn nhau và chúng đòi ba phản ứng khác nhau: chưa kéo
             bao giờ (bấm chạy đi), đã kéo mà Google chưa chốt ngày nào trong cửa sổ (chờ), và đã kéo
             mà website thật sự không có lượt hiển thị nào (đó là một tin, không phải một lỗi).
             </para>
             </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.SearchApiLogCleanupJob">
             <summary>
             Dọn nhật ký lời gọi và nhật ký đổi trạng thái index.
            
             <para>
             <b>Job này ra đời cùng lúc với hai bảng nó dọn</b>, không để lại thành việc phải nhớ — bảng
             <c>AdsSyncLog</c> của miền quảng cáo đã cho thấy hậu quả của cách làm ngược lại (nợ Ads N-7:
             bảng log không có ai dọn).
             </para>
            
             <para>
             <b>Ba thứ được dọn, hai thời hạn.</b> Nhật ký lời gọi là thứ để gỡ lỗi
             trong vài tuần (<c>Search.ApiLogRetentionDays</c>, mặc định 30 ngày). Nhật ký đổi trạng thái là
             thứ để đọc xu hướng, giữ 180 ngày — cố định trong code vì nó không phải nút vặn của vận hành mà
             là một quyết định về ý nghĩa dữ liệu. Hàng đợi thông báo URL đi theo thời hạn của nhật ký lời
             gọi vì nó cùng bản chất: dấu vết của một việc đã xong.
             </para>
            
             <para>
             <b>Việc CHƯA gửi không bao giờ bị dọn.</b> Một dòng còn ở trạng thái chờ là việc chưa làm chứ
             không phải dấu vết; xoá nó là làm mất việc, và mất im lặng.
             </para>
            
             <para>
             Không gọi ra ngoài nên tự đăng ký khi khởi động, khác ba job còn lại.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchApiLogCleanupJob.HistoryRetentionDays">
            <summary>Số ngày giữ nhật ký đổi trạng thái index.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchApiLogCleanupJob.Execute">
            <summary>Xoá hẳn các dòng nhật ký đã quá hạn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.SearchIndexInspectJob">
             <summary>
             Hỏi công cụ tìm kiếm trạng thái index của từng URL trong hàng tồn kho.
            
             <para>
             <b>Thứ tự ưu tiên có lý do.</b> Hạn mức mỗi ngày không đủ để kiểm lại tất cả mãi mãi, nên phải
             chọn: (1) URL <b>chưa từng kiểm</b> — không biết gì là tệ hơn biết một thông tin cũ; (2) URL có
             <c>lastmod</c> <b>mới hơn</b> lần Google thu thập gần nhất — đây chính là câu hỏi của cả đợt,
             "trang nào vừa sửa mà Google chưa đọc lại"; (3) còn lại thì lấy URL lâu chưa kiểm nhất, để mọi
             trang đều được ghé qua theo vòng.
             </para>
            
             <para>
             <b>Gặp 429 là dừng hẳn lượt chạy</b>, không thử lại và không đi tiếp: hết hạn mức thì mọi URL
             còn lại cũng sẽ hỏng y như vậy, và mỗi lần thử thêm là tiêu thêm vào phần hạn mức đang cạn.
             Phần chưa kiểm để lượt sau — hàng đợi tự sắp lại đúng thứ tự ưu tiên trên.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchIndexInspectJob.ActionName">
            <summary>Tên việc ghi vào nhật ký — cũng là khoá đếm hạn mức đã dùng trong ngày.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchIndexInspectJob.Execute">
            <summary>Kiểm trạng thái index cho tới khi hết hàng đợi hoặc hết hạn mức ngày.</summary>
            <remarks>
            <b>Chạy một mình.</b> Người vận hành bấm chạy tay trong lúc lượt theo lịch đang chạy sẽ làm
            hai lượt cùng đọc một sổ đếm hạn mức rồi cùng kiểm một danh sách URL — tiêu gấp đôi hạn mức
            cho đúng ngần ấy thông tin. Lượt thứ hai bị bỏ ngay thay vì xếp hàng chờ: hàng đợi tự sắp
            lại đúng thứ tự ưu tiên ở lượt sau, không có gì để giữ.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchIndexInspectJob.BuildQueueAsync(System.Int32)">
            <summary>
            Xếp hàng đợi theo ba mức ưu tiên đã mô tả ở phần đầu lớp. Sắp xếp trong bộ nhớ vì hàng tồn
            kho chỉ khoảng 150 dòng — viết thành một truy vấn SQL sẽ khó đọc hơn nhiều mà không nhanh hơn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchIndexInspectJob.ApplyStatus(Ladaer.BackEnd.Infrastructures.Jobs.SearchIndexInspectJob.InspectCandidate,Ladaer.BackEnd.Infrastructures.Services.SearchEngines.UrlInspectionResult)">
            <summary>
            Ghi đè trạng thái hiện tại và ghi thêm một dòng lịch sử <b>chỉ khi</b>
            <c>CoverageState</c> hoặc <c>Verdict</c> đổi.
            </summary>
            <returns><c>true</c> nếu trạng thái vừa đổi.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchIndexInspectJob.Cat(System.String,System.Int32)">
            <summary>Cắt một chuỗi về đúng độ dài cột; <c>null</c> giữ nguyên là <c>null</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Jobs.SearchIndexInspectJob.InspectCandidate.Priority">
            <summary>0 = chưa từng kiểm, 1 = đã sửa sau lần Google thu thập, 2 = còn lại.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.SearchInventorySyncJob">
             <summary>
             Dựng lại hàng tồn kho URL mỗi đêm từ chính tệp <c>sitemap.xml</c> mà công cụ tìm kiếm đọc.
            
             <para>
             <b>Job duy nhất của đợt này không gọi ra ngoài</b> — nó chỉ tải một tệp công khai của chính
             website. Nên nó chạy được ngay cả khi mọi công tắc còn tắt, và đó là chủ ý: hàng tồn kho phải
             dựng xong và đối chiếu được bằng mắt <b>trước</b> khi có lời gọi đầu tiên ra Google.
             </para>
            
             <para>
             <b>Số URL dựng được phải bằng số URL trong sitemap tại thời điểm chạy</b> — không phải một con
             số cố định. Sitemap production ngày 15/09/2026 có 151 URL / 148 khác nhau; sau khi giai đoạn
             trước lên production sẽ là 151 URL không trùng nhau.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchInventorySyncJob.Execute">
            <summary>Tải sitemap và ghi lại chênh lệch vào bảng <c>SearchUrl</c>.</summary>
            <remarks>
            <b>Chạy một mình.</b> Hai lượt song song cùng thêm một URL mới sẽ đâm vào chỉ số duy nhất
            trên cột <c>Url</c> và cả hai cùng hỏng.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.SearchSitemapSubmitJob">
             <summary>
             Đọc trạng thái tệp sitemap dưới mắt công cụ tìm kiếm, và nộp lại tệp khi có thay đổi đáng nộp.
            
             <para>
             <b>Hai công tắc, hai vai.</b> <c>Search.Google.Enabled</c> cho phép <b>đọc</b> trạng thái;
             <c>Search.Google.SubmitEnabled</c> cho phép <b>nộp</b>. Khi công tắc nộp còn tắt, job vẫn chạy
             hết logic — kể cả bước quyết định "có đáng nộp không" — rồi ghi vào nhật ký một dòng
             <c>DryRun</c> kèm danh sách URL vừa đổi. Đây là cách duy nhất để biết trước mình sắp báo cho
             Google cái gì; bật công tắc chỉ sau khi đọc dòng đó thấy đúng.
             </para>
            
             <para>
             <b>Không nộp lại mỗi ngày một cách vô điều kiện.</b> Nộp một tệp không đổi gì chỉ dạy công cụ
             tìm kiếm rằng tín hiệu của mình vô nghĩa. Job chỉ nộp khi có URL mới xuất hiện
             hoặc có URL đổi <c>lastmod</c> kể từ đầu ngày hôm qua.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchSitemapSubmitJob.SubmitActionName">
            <summary>Tên việc khi nộp thật.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchSitemapSubmitJob.DryRunActionName">
            <summary>Tên việc khi chạy thử — không có lời gọi nào đi ra.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchSitemapSubmitJob.GetActionName">
            <summary>Tên việc khi đọc trạng thái tệp sitemap.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchSitemapSubmitJob.RecentDays">
             <summary>
             Cửa sổ coi là "vừa đổi", tính bằng <b>ngày</b> chứ không bằng giờ.
            
             <para>
             <b>Vì sao không dùng "24 giờ qua".</b> Thẻ <c>lastmod</c> trong sitemap chỉ ghi ngày, không
             ghi giờ (đo trên sitemap production 15/09/2026: 141/141 thẻ ở dạng <c>2026-09-14</c>), nên
             khi đọc vào nó thành 00:00 của ngày đó. Job chạy 4:17 sáng mà so với mốc "24 giờ trước"
             tức 4:17 hôm qua thì một trang sửa hôm qua có <c>lastmod</c> 00:00 hôm qua luôn <b>rớt</b> —
             và rớt vĩnh viễn, vì hôm sau nó còn cũ hơn. Kết quả là sửa nội dung trang cũ sẽ không bao
             giờ kích hoạt nộp lại sitemap. Lấy mốc là <b>đầu ngày hôm qua</b> thì cả trang sửa hôm qua
             lẫn hôm nay đều lọt.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchSitemapSubmitJob.MaxUrlsInSummary">
            <summary>Số URL tối đa liệt kê trong nhật ký chạy thử — đủ để đọc mà không phình bảng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchSitemapSubmitJob.Execute">
            <summary>Đọc trạng thái sitemap, rồi nộp lại (hoặc chạy thử) khi có thay đổi.</summary>
            <remarks>
            <b>Chạy một mình</b>, cùng lý do với job kiểm trạng thái: hai lượt song song sẽ nộp sitemap
            hai lần liền nhau và cùng ghi vào một dòng trạng thái tệp.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchSitemapSubmitJob.ReadSitemapStatusAsync(System.String)">
            <summary>Đọc trạng thái tệp sitemap và ghi đè dòng trạng thái hiện tại.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchSitemapSubmitJob.GetRecentlyChangedUrlsAsync">
            <summary>URL mới xuất hiện hoặc vừa đổi <c>lastmod</c> kể từ đầu ngày hôm qua.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob">
             <summary>
             Gửi hàng đợi thông báo URL cho công cụ tìm kiếm.
            
             <para>
             <b>Vì sao mười lăm phút một lần chứ không phải mỗi ngày.</b> Giá trị của Indexing API nằm ở chỗ
             nhanh — một tin tuyển dụng mới được Google đọc trong vài phút thay vì chờ lượt thu thập tự
             nhiên. Chạy hằng ngày là vứt bỏ đúng cái lý do dùng nó. Mười lăm phút đủ nhanh mà vẫn gộp được
             nhiều lần sửa liên tiếp của cùng một tin thành một lời gọi.
             </para>
            
             <para>
             <b>Khi công tắc còn tắt, job KHÔNG để hàng đợi tích lại.</b> Nó đánh dấu các việc đang chờ
             thành <see cref="F:Lada.Framework.Data.Enums.SearchNotificationStatus.Skipped"/> kèm lý do, và ghi một dòng nhật ký chạy
             thử liệt kê đúng những URL <b>đã có thể</b> được gửi. Hai lý do:
             <list type="bullet">
             <item>Đọc nhật ký ấy là cách duy nhất biết trước mình sắp báo Google cái gì — điều kiện bắt
             buộc trước lượt ghi đầu tiên theo Nguyên tắc số 1 của cả đợt.</item>
             <item>Để chúng nằm chờ thì ngày bật công tắc sẽ dội ra Google một loạt "vừa cập nhật" cho
             những tin sửa từ hàng tuần trước — đó không phải tín hiệu thật, và đó đúng là thứ Nguyên tắc
             số 1 cấm.</item>
             </list>
             </para>
            
             <para>
             Khai <c>autoRegister: false</c> cùng nhóm với ba job gọi Google: phải có người bấm "Đăng ký"
             trên trang Tác vụ nền sau khi bật công tắc.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob.PublishActionName">
            <summary>Tên việc khi gửi thật — cũng là khoá đếm hạn mức trong ngày.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob.DryRunActionName">
            <summary>
            Tên việc khi chạy thử. Cố ý <b>khác</b> tên chạy thử của job nộp sitemap: hai đường đi ra
            ngoài khác nhau thì phải đếm và đọc được tách nhau.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob.MaxRowsPerRun">
             <summary>
             Số việc tối đa nhặt trong một lượt chạy, trước khi gộp trùng.
            
             <para>
             Trần này <b>không phải</b> hạn mức ngày mà là hàng rào chống một lượt chạy đọc cả bảng vào
             bộ nhớ khi hàng đợi bất ngờ phình (một job đồng bộ chạm hàng loạt tin chẳng hạn). Hạn mức
             ngày được xét riêng, sau khi đã gộp.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob.MaxAttempts">
            <summary>
            Số lượt thử tối đa cho một việc. Hết lượt thì chuyển hẳn sang
            <see cref="F:Lada.Framework.Data.Enums.SearchNotificationStatus.Failed"/> thay vì thử lại mỗi mười lăm phút mãi mãi —
            một URL Google từ chối vì trang thiếu dữ liệu có cấu trúc sẽ bị từ chối y như thế ở lượt
            thứ một nghìn.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob.MaxUrlsInSummary">
            <summary>Số URL tối đa liệt kê trong một dòng nhật ký.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob.Execute">
            <summary>Nhặt hàng đợi, gộp trùng, rồi gửi (hoặc chạy thử) trong phạm vi hạn mức ngày.</summary>
            <remarks>
            <b>Chạy một mình:</b> hai lượt song song sẽ cùng nhặt một dòng và gửi hai lần — vừa tốn hạn
            mức vừa làm sổ đếm sai.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob.GetPendingAsync">
            <summary>Các việc đang chờ, cũ trước — hàng đợi phải công bằng theo thứ tự xếp hàng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob.GroupByUrl(System.Collections.Generic.List{Lada.Framework.Data.Domains.SearchEngines.SearchUrlNotification})">
            <summary>
            Gộp các việc theo URL. Loại thông báo lấy theo <b>việc mới nhất</b> của URL đó.
            </summary>
            <remarks>
            Thứ tự quan trọng và chỉ có một cách đúng: nếu một tin vừa được sửa rồi bị xoá, trạng thái
            sau cùng là "đã gỡ" — báo "vừa cập nhật" cho một trang không còn nữa là sai. Chiều ngược
            lại (xoá rồi khôi phục) thì việc mới nhất là "cập nhật", cũng đúng.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob.DryRunAsync(Lada.Framework.DTO.BaseResult,Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob.NotificationGroup})">
            <summary>
            Chạy thử: ghi đúng thứ sẽ gửi rồi khép các việc lại, không gửi gì.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob.PublishAsync(Lada.Framework.DTO.BaseResult,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob.NotificationGroup},System.Int32)">
            <summary>Gửi thật, dừng đúng ở hạn mức còn lại.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob.Close(Lada.Framework.Data.Domains.SearchEngines.SearchUrlNotification,Lada.Framework.Data.Enums.SearchNotificationStatus,System.String,System.DateTimeOffset)">
            <summary>Khép một việc lại ở trạng thái cuối.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob.NotificationGroup">
            <summary>Một URL cùng mọi việc đang chờ của nó trong lượt chạy này.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.SearchUrlNotifyJob.NotificationGroup.#ctor(System.String,Lada.Framework.Data.Enums.SearchNotificationType,System.Collections.Generic.List{Lada.Framework.Data.Domains.SearchEngines.SearchUrlNotification})">
            <summary>Một URL cùng mọi việc đang chờ của nó trong lượt chạy này.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.MaintenanceScanResult">
            <summary>
            Kết quả một lượt quét — để log và để test khẳng định bằng số thay vì bằng lời.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Jobs.MaintenanceScanResult.ComponentsScanned">
            <summary>Số bộ phận đã xét</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Jobs.MaintenanceScanResult.AlertsCreated">
            <summary>Số cảnh báo mới tạo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Jobs.MaintenanceScanResult.AlertsResolved">
            <summary>Số cảnh báo được đóng lại vì bộ phận đã khoẻ hoặc đã đổi mức</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Jobs.MaintenanceScanResult.AlertsNotified">
            <summary>Số cảnh báo đã gửi thông báo trong lượt này</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Jobs.MaintenanceScanResult.NotificationEnabled">
            <summary>Công tắc gửi thông báo lúc quét</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.TruckMaintenanceScanJob">
            <summary>
            Quét tuổi thọ toàn bộ bộ phận đang lắp, sinh cảnh báo và gửi thông báo.
            </summary>
            <remarks>
            <b>Một công tắc duy nhất cho cả luồng gửi</b> (<c>TruckMaintenance.NotificationEnabled</c>,
            mặc định TẮT): tắt thì job vẫn quét và ghi <c>TruckComponentAlert</c> nhưng để
            <c>NotifiedAt</c> null — đúng chế độ chạy thử của §5.2 bước 4. Hai công tắc liên quan nhau là
            bài học lệch số của đợt GoodsLines, ở đây cố ý chỉ có một.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.TruckMaintenanceScanJob.BuildComponentName(Lada.Framework.Data.Domains.Trucks.TruckComponentType,Lada.Framework.Data.Enums.ComponentPosition)">
            <summary>Tên bộ phận kèm vị trí — "Lốp (Trục 2 - trái ngoài)"</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.TruckMaintenanceScanJob.BuildRemainingText(Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult)">
            <summary>
            Diễn giải "còn bao nhiêu" / "quá bao nhiêu" theo tiêu chí đến trước.
            </summary>
            <remarks>
            Chọn con số nhỏ hơn giữa km và ngày để câu thông báo nói đúng cái sắp chạm trước; tiêu chí
            nào không tính được thì bỏ qua, không bịa số.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.UrlContentFingerprintJob">
             <summary>
             Job tự chữa dấu vân tay nội dung: mỗi đêm tính lại dấu vân tay của mọi URL bài viết,
             dịch vụ và tin tuyển dụng rồi đối chiếu với giá trị đang lưu.
            
             <para>
             <b>Vì sao cần dù ba dịch vụ lưu đã tự đóng dấu.</b> Đường sửa mới thêm về sau — một màn quản trị
             khác, một lệnh nhập hàng loạt, một job đồng bộ — sẽ không tự biết phải đóng dấu. Không có job này
             thì nội dung đổi mà <c>lastmod</c> đứng yên, và không ai phát hiện ra cho tới lúc thắc mắc vì sao
             Google không đọc lại trang. Có job thì sai sót chỉ trễ tối đa một ngày, và dòng cảnh báo chỉ thẳng
             slug nào đang đi qua đường không đóng dấu.
             </para>
            
             <para>
             <b>Dấu vân tay chưa có thì điền im lặng, không dời mốc.</b> Ngay sau khi backfill, cả 91 URL trên
             DB dev đều chưa có dấu vân tay; nếu job coi "chưa có" là "đã đổi" thì toàn bộ website khai vừa sửa
             trong cùng một đêm — đúng loại tín hiệu giả mà cả đợt này được lập ra để tránh.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.UrlContentFingerprintJob.Execute">
            <summary>
            Quét toàn bộ URL của ba nhóm thực thể có nội dung và chữa dấu vân tay lệch.
            </summary>
            <returns>Số dấu vân tay được điền mới và số URL bị dời mốc vì nội dung đã đổi.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.UrlContentFingerprintJob.Apply(Lada.Framework.Data.Domains.Cms.UrlRecord,System.String,System.DateTimeOffset,System.Int32@,System.Int32@)">
            <summary>
            Áp dấu vân tay vừa tính và đếm kết quả. Một URL bị dời mốc ở đây nghĩa là nội dung của nó
            đã đổi qua một đường không đóng dấu — ghi cảnh báo kèm slug để còn lần ra đường đó.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Jobs.VatInvoiceSyncJob">
            <summary>
            Hangfire job để đồng bộ hóa đơn VAT hàng ngày
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Jobs.VatInvoiceSyncJob.Execute">
            <summary>
            Execute job - đồng bộ hóa đơn của ngày hôm qua
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsQueryData">
            <summary><c>data</c> của mọi tool truy vấn fact qua <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine"/> (query_shipments, query_stops, query_vehicles nhien_lieu).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsQueryData.Table">
            <summary>Bảng đã trả — chỉ tool nhiều bảng (query_vehicles); null thì không có khoá.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsQueryData.Rows">
            <summary>Mỗi dòng: khoá = mã chiều / chỉ tiêu (hoặc mã cột phân bố).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsQueryData.Totals">
            <summary>Cùng chỉ tiêu trên toàn bộ kỳ + bộ lọc, không nhóm.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsQueryData.WeightBinLabels">
            <summary>Nhãn mức cân đang dùng — chỉ có khi chiều mức cân được dùng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryFreshnessView.LastLoadedAt">
            <summary>Lần nạp thành công gần nhất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryFreshnessView.CompleteTo">
            <summary>Ngày cuối cùng có số đủ (ngày trước lần nạp gần nhất, giờ Việt Nam).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryFreshnessView.CoverFrom">
            <summary>Ngày đầu tiên có số đủ (mốc của lượt nạp lại 400 ngày thành công gần nhất).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsFactQuery">
            <summary>
            Phần chung của các tool truy vấn fact (docs/plan-mcp-tra-cuu-so-lieu.md §3.4): công tắc mã người, lỗi tham số, độ tươi +
            mốc phủ (NO_DATA), cảnh báo độ tươi / phân trang, vỏ <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsQueryData"/>. Tool chỉ còn dựng request và cảnh báo
            riêng của chủ đề — hai tool không lệch nhau ở luật chung.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsFactQuery.ExposePersonCodesConfigKey">
            <summary>Khoá AppConfig bật/tắt chiều mã người (câu hỏi Q3). Thiếu khoá hoặc giá trị khác "true" = TẮT (fail-closed).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsFactQuery.BuildFailure(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryBuildResult)">
            <summary>Lỗi tham số của engine → vỏ lỗi (mã của lỗi đầu tiên, mọi lỗi ở errors[]).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsFactQuery.FreshnessAsync(System.IServiceProvider,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Độ tươi của chủ đề; <c>Failure</c> khác null = trả NO_DATA: chưa nạp thành công lần nào, hoặc chỉ có lượt đêm mà chưa lượt
            nạp lại cả cửa sổ nào thành công (trả số là trả tổng thiếu lịch sử — review GĐ B).
            </summary>
            <param name="factName">"Fact vận đơn", "Fact điểm dừng" — mở đầu câu báo.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsFactQuery.CompleteTo(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopicFreshness)">
            <summary>Ngày cuối có số đủ = ngày trước lần nạp thành công gần nhất (giờ Việt Nam).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsFactQuery.AddCommonWarnings(System.Collections.Generic.List{System.String},Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryResult,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopicFreshness,System.Int64,System.String)">
            <summary>Cảnh báo chung: lượt nạp lỗi, kỳ vượt ngày đủ số, kỳ trước mốc phủ, không dòng nào, phân trang.</summary>
            <param name="noRowsMessage">Câu khi bộ lọc không khớp dòng nào ("Không có vận đơn nào khớp …").</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsFactQuery.ToData(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryResult,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopicFreshness,System.String)">
            <param name="table">Bảng của tool nhiều bảng (query_vehicles: nhien_lieu); null = tool một bảng, không trả khoá table.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsFactQuery.ToJson(System.Collections.Generic.Dictionary{System.String,System.Object})">
            <summary>Dòng kết quả → JObject giữ null tường minh (serializer của MCP bỏ thuộc tính null của đối tượng C#).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpContract">
            <summary>
            <b>Hợp đồng giữa MCP số liệu (<c>/analytics</c>) và trợ lý AI</b> — chỉ dẫn server (<c>initialize.instructions</c>),
            số hiệu hợp đồng và mã lỗi (docs/plan-mcp-tra-cuu-so-lieu.md §3.7). Nguồn sự thật duy nhất cùng với mô tả từng tool
            và <c>AnalyticsCatalog</c>; tách khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract"/> của kho nội dung vì hai hợp đồng tiến hoá độc lập.
            </summary>
            <remarks>
            <para>
            Luật giữ hợp đồng khỏi lệch pha (bài học <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract"/>): đổi hành vi, đổi tên hay định nghĩa một
            chiều/chỉ tiêu thì sửa mô tả + catalog <b>trong cùng commit</b>, nâng <see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpContract.Version"/> và
            <see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpContract.EffectiveDate"/>. Định nghĩa cũ giữ trong <c>describe_catalog</c> kèm ngày hết hiệu lực (yêu cầu §6).
            </para>
            <para>
            Test <c>AnalyticsContractTests</c> canh: chỉ dẫn mang <see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpContract.Stamp"/> và ≤ 1.500 ký tự, mọi mô tả tool nêu role
            + scope, mọi mã snake_case nhắc trong chỉ dẫn/mô tả tồn tại trong catalog hoặc tham số tool.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpContract.Version">
            <summary>Số hiệu hợp đồng. Nâng khi tên/định nghĩa chiều, chỉ tiêu hoặc hành vi tool đổi.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpContract.EffectiveDate">
            <summary>
            Ngày hành vi của bản hợp đồng này có hiệu lực. 0.1 (GĐ A, 2026-09-23) = chỉ <c>describe_catalog</c>; 0.2 (GĐ B,
            2026-09-24) mở <c>query_shipments</c>; 0.3 (GĐ C, 2026-09-24) mở <c>query_stops</c> + <c>get_price_tables</c>; 0.4 (GĐ D,
            2026-09-26) mở <c>query_vehicles</c>; 0.5 (GĐ E, 2026-09-26) mở <c>query_revenue</c>, <c>query_claims</c>,
            <c>query_hub_throughput</c> và cho <c>don_vi_sale</c> theo công tắc mã người. Là ngày CHỐT HÀNH VI trong code, không phải ngày
            lên production (plan §7 GĐ D: ngày production chưa biết lúc build, hằng không đổi được sau build — ngày production ghi ở
            docs/mcp-tra-cuu-so-lieu.md §10).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpContract.Stamp">
            <summary>Chuỗi trợ lý so với đặc tả nó đang cầm: <c>contract: 0.1 — 2026-09-23</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpContract.ServerVersion">
            <summary>Phiên bản server báo trong <c>initialize.serverInfo.version</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpContract.ServerTitle">
            <summary>Tên hiển thị của server.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpContract.ErrorCodes">
            <summary>Mã lỗi riêng của MCP số liệu (plan §3.7), cộng FORBIDDEN / RATE_LIMITED / UNAVAILABLE dùng chung của lớp MCP.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpContract.ErrorCodes.All">
            <summary>Mọi mã lỗi trợ lý có thể gặp ở /analytics — liệt kê trong chỉ dẫn.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpContract.Instructions">
            <summary>Chỉ dẫn server trả trong <c>initialize</c> ở /analytics — thứ trợ lý đọc trước khi gọi tool đầu tiên.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.IAnalyticsMcpTool">
            <summary>Mặt không generic của mọi tool số liệu — để test hợp đồng và bộ tool duyệt được mọi tool bất kể kiểu tham số.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpTool`1">
            <summary>
            Lớp nền mỏng của mọi tool MCP số liệu (docs/plan-mcp-tra-cuu-so-lieu.md §3.1, §3.10) — kế thừa nguyên trạng
            <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.ContentStoreMcpTool`1"/> (guard quyền, đọc tham số snake_case, vỏ kết quả, không JSON-RPC error),
            và thêm ba thứ riêng của miền số liệu:
            <list type="number">
            <item>role <c>Analytics.Read</c> + scope <c>analytics:read</c>, chỉ đọc, idempotent — cố định, tool con không chọn;</item>
            <item>công tắc <c>Analytics:Enabled</c> TẮT → <c>UNAVAILABLE</c>;</item>
            <item><see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.PiiOutputGuard"/> quét MỌI kết quả trước khi trả (lớp 3 hàng rào dữ liệu cá nhân);</item>
            <item>ghi <c>AnalyticsCallLog</c> cho MỌI lời gọi — kể cả bị guard từ chối, kể cả tham số sai.</item>
            </list>
            </summary>
            <remarks>
            Tool số liệu KHÔNG đăng ký vào DI qua <c>WithTools</c>: chúng chỉ nằm trong bộ tool của mặt <c>/analytics</c>
            (<see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpToolSet"/>), nên về cấu trúc không thể hiện ra ở <c>/mcp</c>.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpTool`1.ArgumentErrorCode">
            <summary>Tham số sai kiểu → <c>INVALID_PARAM</c> (bảng mã lỗi của hợp đồng số liệu, không phải <c>VALIDATION_ERROR</c> của kho nội dung).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpTool`1.ExecuteAnalyticsAsync(`0,System.IServiceProvider,System.Threading.CancellationToken)">
            <summary>Thân tool số liệu. Lỗi nghiệp vụ nằm trong vỏ; đặt <see cref="P:Ladaer.BackEnd.Infrastructures.Mcp.McpToolOutcome.RowCount"/> để ghi nhật ký.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpTool`1.GuardOutput(Ladaer.BackEnd.Infrastructures.Mcp.McpToolOutcome,System.IServiceProvider,System.String)">
            <summary>
            Chạy <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.PiiOutputGuard"/> trên <c>data</c> và <c>extra</c> rồi trả vỏ MỚI mang CHÍNH cây JSON đã quét (không
            dựng lại từ đối tượng gốc — một lần chuyển đổi cho mỗi lời gọi). Có chỗ phải che thì kèm cảnh báo và log LỖI (dấu hiệu
            dữ liệu bẩn lọt vào schema analytics — phải đi tìm nguồn).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpTools">
            <summary>
            Danh sách tool của mặt <c>/analytics</c> — thứ tự hiện trong <c>tools/list</c>. Mô tả từng tool là hợp đồng với trợ
            lý AI (<see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpContract"/>): đổi hành vi thì sửa mô tả trong cùng commit.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpToolSet">
            <summary>
            Bộ tool + chỉ dẫn của mặt <c>/analytics</c>, gán vào <c>McpServerOptions</c> của từng request trong
            <c>ConfigureSessionOptions</c> (xem <c>McpRegister</c>). Singleton: tool là đối tượng không trạng thái, dựng một lần.
            </summary>
            <remarks>
            Spike SDK 2.2.0 (plan §4 GĐ A): ở chế độ Stateless mỗi request nhận một <c>McpServerOptions</c> MỚI từ
            <c>IOptionsFactory</c>, và server đọc <c>tools/list</c>, <c>tools/call</c>, <c>instructions</c> từ đúng bản đó — nên gán
            ở đây là tách hẳn bộ tool theo endpoint. Luôn gán một collection MỚI (<see cref="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpToolSet.CreateCollection"/>), không sửa
            collection có sẵn: collection dùng chung mà ai đó lỡ <c>Add</c> vào là rò giữa các request đồng thời.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpToolSet.Apply(ModelContextProtocol.Server.McpServerOptions)">
            <summary>Thay bộ tool, chỉ dẫn và thông tin server của một request /analytics.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.DescribeCatalogInput">
            <summary>Tham số <c>describe_catalog</c> (T1, yêu cầu §5).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.DescribeCatalogInput.Topic">
            <summary>Chỉ trả một chủ đề: shipments, stops, vehicles, prices, revenue, claims, hubs (trips = vehicles). Bỏ trống = mọi chủ đề.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.DescribeCatalogInput.IncludeLists">
            <summary>Kèm danh mục: chi nhánh/bưu cục, tỉnh, loại hàng, xe (không biển số), dải cự ly, bảng giá công khai, tham số cước. Mặc định false.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.DescribeCatalogInput.ProvinceCode">
            <summary>Mã tỉnh bộ 2 cấp (ví dụ "01") — kèm danh sách xã/phường của tỉnh đó; chỉ có tác dụng khi include_lists = true.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.DescribeCatalogData.Lists">
            <summary>Danh mục theo tên (chi_nhanh, tinh, xa_phuong…) — khoá khớp <c>lookup</c> của chiều.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.CatalogFreshnessView.LastLoadedAt">
            <summary>Lần nạp danh mục thành công gần nhất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.CatalogFreshnessView.Topics">
            <summary>Theo chủ đề nạp (danh_muc, shipments…): lần thành công gần nhất + trạng thái lượt gần nhất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.CatalogTopicFreshnessView.CoverFrom">
            <summary>Ngày đầu tiên có số đủ (fact nạp lại cả cửa sổ); null = chủ đề chưa có lượt nạp lại nào.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.CatalogTopicView.DefaultMetrics">
            <summary>Chỉ tiêu trả khi bỏ trống metrics.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.CatalogTopicView.Histograms">
            <summary>Phân bố nhận ở tham số histogram_of.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.CatalogHistogramView.BinCode">
            <summary>Mã cột nhóm trong rows[] và các nhóm theo thứ tự.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.DescribeCatalogTool">
            <summary>
            <c>describe_catalog</c> — T1: từ điển số liệu (chủ đề, chiều, chỉ tiêu kèm định nghĩa + công thức, mục chưa có dữ
            liệu kèm lý do) sinh thẳng từ <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog"/>, cộng độ tươi từ <c>analytics.LoadRun</c> và — khi
            <c>include_lists</c> — danh mục từ <c>analytics.Dim*</c>.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.DescribeCatalogTool.ListNames">
            <summary>Tên các danh mục trong <c>lists</c> — khớp <c>lookup</c> của chiều trong catalog.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.DescribeCatalogTool.HubAgencyIdsConfigKey">
            <summary>Khoá AppConfig liệt kê Id đơn vị là "trung tâm khai thác" (quyết định Q7, 2026-09-26) — cùng khoá builder lượt qua trung tâm đọc.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.DescribeCatalogTool.HubAgenciesAsync(System.IServiceProvider,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsAgencyRow})">
            <summary>Trung tâm khai thác = các Id đơn vị khai ở AppConfig (Q7) — cùng luật đọc với builder lượt qua trung tâm.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesInput">
            <summary>Tham số <c>get_price_tables</c> (T5, yêu cầu §5).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesInput.Table">
            <summary>Bảng: niem_yet (mặc định) | dai_cu_ly | phu_phi | khu_vuc_xa | dich_vu_cong_them | bang_gia_loai_hang.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesInput.EffectiveDate">
            <summary>Ngày hiệu lực (YYYY-MM-DD, mặc định hôm nay). Bảng giá không lưu ngày hiệu lực: khác hôm nay → cảnh báo NO_HISTORY.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesInput.IncludeHistory">
            <summary>Xin cả lịch sử bảng giá — không có (cảnh báo NO_HISTORY), vẫn trả bảng đang lưu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesData">
            <summary><c>data</c> của get_price_tables.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesData.EffectiveDate">
            <summary>Ngày đã dùng để chọn tham số cước (FeeConfig có ngày hiệu lực); bảng giá luôn là bản đang lưu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesData.IncludesVat">
            <summary>Giá trong bảng ĐÃ GỒM VAT (đo GĐ C) — khác mọi chỉ tiêu tiền của query_shipments.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesData.VatRate">
            <summary>Thuế suất VAT hiệu lực tại effective_date — để quy giá gồm VAT về chưa VAT.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesData.PriceRule">
            <summary>Cách ra cước từ bảng niem_yet (chỉ có ở bảng đó).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesData.Rows">
            <summary>Mỗi dòng: khoá = mã trong describe_catalog topic prices.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesTool">
            <summary>
            <c>get_price_tables</c> — T5: bảng giá CÔNG KHAI và tham số cước đang hiệu lực, đọc thẳng các bảng danh mục
            <c>analytics.Dim*</c> (không kỳ, không nhóm — không qua <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine"/>) bằng login chỉ đọc.
            </summary>
            <remarks>
            <para>
            Giá lưu ĐÃ GỒM VAT (<see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.PricesIncludeVat"/>, đo Việc 0 GĐ C) nên trả kèm cờ <c>gom_vat</c> + thuế suất
            thay vì tự quy đổi từng dòng: bước giá theo cân quy đổi từng dòng rồi cộng sẽ lệch làm tròn so với cước hệ thống tính.
            </para>
            <para>
            Bảng <c>niem_yet</c> trả luật ra cước (<see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.ListedPriceRule"/>) cùng các cột <c>gia_nen</c>,
            <c>moc_nen_kg</c> dựng sẵn cho dòng theo bước — đúng luật <c>FeeService.GetFeeByWeightAxis</c>; test DB tính lại bằng chính
            FeeService trên dữ liệu dev (nghiệm thu 5 phần "khớp engine").
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesTool.MaxRows">
            <summary>Trần số dòng một lời gọi (danh sách xã khu vực xa có thể dài).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesTool.ListedRows(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPriceTables,System.Collections.Generic.List{System.String})">
            <summary>Bảng chung theo cân (GoodsCategoryId null) của mọi dải còn hiệu lực — thứ tự dải, rồi cân, fix trước bước.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesTool.ParameterRow(System.String,System.Nullable{System.Decimal},System.String,System.Nullable{System.DateTime},System.Nullable{System.DateTime},System.String)">
            <summary>Một dòng tham số: ma = mã chỉ tiêu trong catalog (nhãn, đơn vị lấy từ đó).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesTool.FeeParameters">
            <summary>
            Tham số cước hiệu lực tại một ngày — đúng luật <c>FeeConfigProvider.GetValueAsync</c>: dòng có <c>EffectiveFrom</c> muộn
            nhất thắng (rồi Id lớn nhất); không dòng nào → hằng dự phòng <c>FeeConfigProvider.DefaultValues</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesTool.Clean(System.Decimal)">
            <summary>Bỏ số 0 thừa sau dấu phẩy (80000.00 → 80000, 0.500 → 0.5) — cột decimal(18,2)/(12,3) đọc ra giữ scale.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.GetPriceTablesTool.Number(System.Nullable{System.Decimal})">
            <summary>Ô số của dòng: null giữ tường minh; số nguyên in không đuôi ".0" (Newtonsoft in decimal 80000 thành 80000.0).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryClaimsInput">
            <summary>Tham số <c>query_claims</c> (T7, yêu cầu §5 giai đoạn 2 — chỉ số vụ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryClaimsInput.FromDate">
            <summary>Từ ngày, gồm (YYYY-MM-DD, giờ Việt Nam). Bắt buộc; khoảng tối đa 400 ngày.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryClaimsInput.ToDate">
            <summary>Đến ngày, gồm (YYYY-MM-DD, giờ Việt Nam). Bắt buộc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryClaimsInput.DateField">
            <summary>Cột ngày dùng để lọc kỳ: gui (ngày khách gửi — mặc định) | giai_quyet (ngày giải quyết).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryClaimsInput.GroupBy">
            <summary>Mảng mã chiều để nhóm, tối đa 6 (describe_catalog topic claims). Bỏ trống = một dòng tổng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryClaimsInput.Filters">
            <summary>Lọc: {mã chiều: giá trị | [giá trị, …]}; null trong mảng = lọc ô trống; tối đa 500 giá trị mỗi chiều.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryClaimsInput.Metrics">
            <summary>Mảng mã chỉ tiêu. Bỏ trống = so_vu, so_van_don_lien_quan, so_vu_da_giai_quyet.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryClaimsInput.WeightBins">
            <summary>Mốc mức cân (kg, tăng dần, cận trên gồm) thay mốc mặc định của chiều bac_can.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryClaimsInput.Page">
            <summary>Trang, bắt đầu từ 1.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryClaimsInput.PageSize">
            <summary>Số dòng một trang: mặc định 1000, tối đa 5000.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryClaimsInput.OrderBy">
            <summary>Sắp xếp "mã asc|desc, mã asc|desc" — mã phải có trong group_by hoặc metrics. Mặc định theo group_by tăng dần.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryClaimsTool">
            <summary>
            <c>query_claims</c> — T7: khiếu nại của khách trên <c>analytics.ComplaintFact</c>, CHỈ SỐ VỤ (hệ thống không lưu tiền bồi thường, tiền
            hỗ trợ, bên lỗi — AN-3). Cùng engine với các tool fact khác; đơn vị suy qua vận đơn của khiếu nại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryClaimsTool.AddWarnings(System.Collections.Generic.List{System.String},Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryResult,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopicFreshness)">
            <summary>Cảnh báo theo bộ đếm chẩn đoán của đúng tập khiếu nại đã lọc.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryHubThroughputInput">
            <summary>Tham số <c>query_hub_throughput</c> (T8, yêu cầu §5 giai đoạn 2).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryHubThroughputInput.FromDate">
            <summary>Từ ngày, gồm (YYYY-MM-DD, giờ Việt Nam) — theo ngày hàng đến / rời trung tâm. Bắt buộc; khoảng tối đa 400 ngày.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryHubThroughputInput.ToDate">
            <summary>Đến ngày, gồm (YYYY-MM-DD, giờ Việt Nam). Bắt buộc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryHubThroughputInput.GroupBy">
            <summary>Mảng mã chiều để nhóm, tối đa 6 (describe_catalog topic hubs). Bỏ trống = một dòng tổng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryHubThroughputInput.Filters">
            <summary>Lọc: {mã chiều: giá trị | [giá trị, …]}; null trong mảng = lọc ô trống; tối đa 500 giá trị mỗi chiều.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryHubThroughputInput.Metrics">
            <summary>Mảng mã chỉ tiêu. Bỏ trống = so_van_don_qua, so_luot, tong_kg, so_van_don_bq_ngay, thoi_gian_luu_kho_bq_gio.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryHubThroughputInput.WeightBins">
            <summary>Mốc mức cân (kg, tăng dần, cận trên gồm) thay mốc mặc định của chiều bac_can.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryHubThroughputInput.Page">
            <summary>Trang, bắt đầu từ 1.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryHubThroughputInput.PageSize">
            <summary>Số dòng một trang: mặc định 1000, tối đa 5000.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryHubThroughputInput.OrderBy">
            <summary>Sắp xếp "mã asc|desc, mã asc|desc" — mã phải có trong group_by hoặc metrics. Mặc định theo group_by tăng dần.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryHubThroughputTool">
            <summary>
            <c>query_hub_throughput</c> — T8: sản lượng qua trung tâm khai thác trên <c>analytics.HubEventFact</c> (lượt hàng đến / rời các đơn vị
            khai ở AppConfig <c>Analytics.HubAgencyIds</c>). Chỉ tiêu theo ngày (<c>so_van_don_bq_ngay</c>, phân vị) là chỉ tiêu hai tầng của
            engine trên cặp (nhóm, ngày).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryHubThroughputTool.HubsOfLastLoad(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopicFreshness)">
            <summary>Danh sách trung tâm của lượt nạp gần nhất (khoá <c>hubs=</c> trong <c>LoadRun.Message</c>); null khi không đọc được.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryHubThroughputTool.AddWarnings(System.Collections.Generic.List{System.String},Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryResult,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopicFreshness,System.Collections.Generic.IReadOnlyList{System.Int32})">
            <summary>Cảnh báo theo bộ đếm chẩn đoán của đúng tập lượt đã lọc.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryRevenueInput">
            <summary>Tham số <c>query_revenue</c> (T6, yêu cầu §5 giai đoạn 2).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryRevenueInput.FromDate">
            <summary>Từ ngày, gồm (YYYY-MM-DD, giờ Việt Nam). Bắt buộc; khoảng tối đa 400 ngày.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryRevenueInput.ToDate">
            <summary>Đến ngày, gồm (YYYY-MM-DD, giờ Việt Nam). Bắt buộc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryRevenueInput.DateField">
            <summary>Cột ngày dùng để lọc kỳ: tao (ngày tạo đơn) | lay (ngày lấy hàng — mặc định) | giao (ngày giao thành công).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryRevenueInput.GroupBy">
            <summary>Mảng mã chiều để nhóm, tối đa 6 (describe_catalog topic revenue). Bỏ trống = một dòng tổng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryRevenueInput.Filters">
            <summary>Lọc: {mã chiều: giá trị | [giá trị, …]}; null trong mảng = lọc ô trống; tối đa 500 giá trị mỗi chiều.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryRevenueInput.Metrics">
            <summary>Mảng mã chỉ tiêu. Bỏ trống = doanh_thu_cuoc_chua_vat, doanh_thu_niem_yet_tuong_ung, ty_le_giam_bq, so_khach.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryRevenueInput.Page">
            <summary>Trang, bắt đầu từ 1.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryRevenueInput.PageSize">
            <summary>Số dòng một trang: mặc định 1000, tối đa 5000.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryRevenueInput.OrderBy">
            <summary>Sắp xếp "mã asc|desc, mã asc|desc" — mã phải có trong group_by hoặc metrics. Mặc định theo group_by tăng dần.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryRevenueTool">
            <summary>
            <c>query_revenue</c> — T6: doanh thu cước và giảm giá theo nhóm trên <c>analytics.ShipmentFact</c> (cùng bảng fact với
            <c>query_shipments</c>, chủ đề <c>revenue</c> bỏ đơn huỷ bằng điều kiện dòng cố định của catalog). Tỷ trọng 10 khách lớn nhất
            là chỉ tiêu hai tầng có hạng cặp của engine (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.RanksPairs"/>) — không SQL riêng ngoài catalog.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryRevenueTool.AddWarnings(System.Collections.Generic.List{System.String},Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryResult,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopicFreshness)">
            <summary>Cảnh báo theo bộ đếm chẩn đoán của đúng tập đơn (không huỷ) đã lọc.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryShipmentsInput">
            <summary>Tham số <c>query_shipments</c> (T2, yêu cầu §5 + §6).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryShipmentsInput.FromDate">
            <summary>Từ ngày, gồm (YYYY-MM-DD, giờ Việt Nam). Bắt buộc; khoảng tối đa 400 ngày.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryShipmentsInput.ToDate">
            <summary>Đến ngày, gồm (YYYY-MM-DD, giờ Việt Nam). Bắt buộc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryShipmentsInput.DateField">
            <summary>Cột ngày dùng để lọc kỳ: tao (ngày tạo đơn) | lay (ngày lấy hàng — mặc định) | giao (ngày giao thành công).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryShipmentsInput.GroupBy">
            <summary>Mảng mã chiều để nhóm, tối đa 6 (describe_catalog topic shipments). Bỏ trống = một dòng tổng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryShipmentsInput.Filters">
            <summary>Lọc: {mã chiều: giá trị | [giá trị, …]}; null trong mảng = lọc ô trống; tối đa 500 giá trị mỗi chiều.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryShipmentsInput.Metrics">
            <summary>Mảng mã chỉ tiêu. Bỏ trống = so_van_don, so_kien, tong_kg_tinh_cuoc, tong_cuoc_thuc_chua_vat.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryShipmentsInput.WeightBins">
            <summary>Mốc mức cân (kg, tăng dần, cận trên gồm) thay mốc mặc định của chiều bac_can, ví dụ [5, 25, 100].</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryShipmentsInput.HistogramOf">
            <summary>Trả phân bố thay cho chỉ tiêu: van_don_cung_khach_cung_ngay.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryShipmentsInput.Page">
            <summary>Trang, bắt đầu từ 1.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryShipmentsInput.PageSize">
            <summary>Số dòng một trang: mặc định 1000, tối đa 5000.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryShipmentsInput.OrderBy">
            <summary>Sắp xếp "mã asc|desc, mã asc|desc" — mã phải có trong group_by hoặc metrics. Mặc định theo group_by tăng dần.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryShipmentsTool">
            <summary>
            <c>query_shipments</c> — T2: tổng hợp vận đơn trên <c>analytics.ShipmentFact</c> theo chiều/chỉ tiêu của
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog"/>. Kiểm tham số + sinh SQL ở <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine"/> (lớp thuần), chạy ở
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsQueryExecutor"/> (login chỉ đọc); tool chỉ ghép cảnh báo và vỏ kết quả.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryShipmentsTool.AddWarnings(System.Collections.Generic.List{System.String},Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryResult,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopicFreshness)">
            <summary>Cảnh báo theo số liệu thật của lời gọi (bộ đếm chẩn đoán tính trên đúng tập dòng đã lọc).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryStopsInput">
            <summary>Tham số <c>query_stops</c> (T3, yêu cầu §5 — nghĩa ĐD-1 theo lái xe, plan §2.10).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryStopsInput.FromDate">
            <summary>Từ ngày, gồm (YYYY-MM-DD, giờ Việt Nam) — theo ngày của điểm dừng. Bắt buộc; khoảng tối đa 400 ngày.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryStopsInput.ToDate">
            <summary>Đến ngày, gồm (YYYY-MM-DD, giờ Việt Nam). Bắt buộc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryStopsInput.GroupBy">
            <summary>Mảng mã chiều để nhóm, tối đa 6 (describe_catalog topic stops). Bỏ trống = một dòng tổng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryStopsInput.Filters">
            <summary>Lọc: {mã chiều: giá trị | [giá trị, …]}; null trong mảng = lọc ô trống; tối đa 500 giá trị mỗi chiều.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryStopsInput.Metrics">
            <summary>Mảng mã chỉ tiêu. Bỏ trống = so_diem_dung, so_van_don, van_don_bq_moi_diem, diem_bq_moi_lai_xe_ngay.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryStopsInput.WeightBins">
            <summary>Mốc mức cân (kg, tăng dần, cận trên gồm) thay mốc mặc định của chiều bac_can_lon_nhat_tai_diem.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryStopsInput.Page">
            <summary>Trang, bắt đầu từ 1.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryStopsInput.PageSize">
            <summary>Số dòng một trang: mặc định 1000, tối đa 5000.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryStopsInput.OrderBy">
            <summary>Sắp xếp "mã asc|desc, mã asc|desc" — mã phải có trong group_by hoặc metrics. Mặc định theo group_by tăng dần.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryStopsTool">
            <summary>
            <c>query_stops</c> — T3: điểm dừng lấy/giao ƯỚC LƯỢNG (ĐD-1, plan §3.6) trên <c>analytics.StopFact</c>. Cùng engine với
            <c>query_shipments</c> (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine"/>): chỉ tiêu <c>*_lai_xe_ngay</c> là chỉ tiêu hai tầng — engine gộp
            theo (nhóm, lái xe, ngày) trước rồi mới bình quân/phân vị.
            </summary>
            <remarks>
            Nghiệm thu 3 (3 lái xe × 5 ngày đếm tay, ±1 điểm) chưa có người đếm (Q9, 2026-09-24) — mọi kết quả kèm cảnh báo "chưa
            nghiệm thu"; khi nghiệp vụ đếm xong và đạt thì đặt <see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryStopsTool.AcceptanceVerified"/> = true cùng lượt nâng hợp đồng.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryStopsTool.AcceptanceVerified">
            <summary>Định nghĩa ĐD-1 đã qua nghiệm thu 3 với đếm tay chưa.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryStopsTool.AddWarnings(System.Collections.Generic.List{System.String},Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryResult,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopicFreshness)">
            <summary>Cảnh báo theo bộ đếm chẩn đoán của đúng tập điểm dừng đã lọc.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryVehiclesInput">
            <summary>Tham số <c>query_vehicles</c> (thay T4 query_trips, plan §2.10).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryVehiclesInput.Table">
            <summary>Bảng: nhien_lieu (mặc định — lần đổ dầu theo kỳ) | doi_xe (đội xe hiện có, không kỳ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryVehiclesInput.FromDate">
            <summary>Từ ngày, gồm (YYYY-MM-DD, giờ Việt Nam) — theo ngày đổ dầu. Bắt buộc ở nhien_lieu; khoảng tối đa 400 ngày.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryVehiclesInput.ToDate">
            <summary>Đến ngày, gồm (YYYY-MM-DD). Bắt buộc ở nhien_lieu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryVehiclesInput.GroupBy">
            <summary>Mảng mã chiều để nhóm, tối đa 6 (describe_catalog topic vehicles). Bỏ trống = một dòng tổng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryVehiclesInput.Filters">
            <summary>Lọc (chỉ bảng nhien_lieu): {mã chiều: giá trị | [giá trị, …]}; null trong mảng = lọc ô trống.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryVehiclesInput.Metrics">
            <summary>Mảng mã chỉ tiêu. Bỏ trống = mặc định của bảng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryVehiclesInput.Page">
            <summary>Trang (bảng nhien_lieu), bắt đầu từ 1.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryVehiclesInput.PageSize">
            <summary>Số dòng một trang (bảng nhien_lieu): mặc định 1000, tối đa 5000.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryVehiclesInput.OrderBy">
            <summary>Sắp xếp "mã asc|desc, …" (bảng nhien_lieu) — mã phải có trong group_by hoặc metrics.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.FleetQueryData">
            <summary><c>data</c> của query_vehicles bảng doi_xe (đội xe hiện có, không kỳ).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryVehiclesTool">
            <summary>
            <c>query_vehicles</c> — thay T4 <c>query_trips</c> (hệ thống không có bảng chuyến xe, AN-2). Hai bảng: <c>nhien_lieu</c> chạy
            trên engine (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine"/>, <c>analytics.FuelFact</c> + join <c>DimVehicle</c>) theo kỳ ngày đổ; <c>doi_xe</c>
            đọc thẳng <c>analytics.DimVehicle</c> (đội xe HIỆN CÓ, không kỳ) như <c>get_price_tables</c> đọc bảng giá.
            </summary>
            <remarks>
            Tách hai bảng vì hai nguồn khác hạt (plan §7 GĐ D): đếm xe trên fact chỉ ra xe CÓ ĐỔ DẦU trong kỳ (dev: ~15/26 xe mỗi tháng),
            còn đội xe đăng ký phải gồm cả xe đứng. Tiền nhiên liệu trả nguyên số trên phiếu (ĐÃ GỒM THUẾ — không bóc được VAT, AN-22).
            Không có chiều lái xe: nối mã xe với mã lái xe là để lộ vết một người (AN-20).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.QueryVehiclesTool.AddFuelWarnings(System.Collections.Generic.List{System.String},Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryResult,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopicFreshness)">
            <summary>Cảnh báo theo bộ đếm chẩn đoán của đúng tập phiếu đã lọc.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpAccessRequirement">
            <summary>Yêu cầu của policy gác một endpoint MCP (<see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.McpPolicy"/> cho /mcp, <see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.AnalyticsMcpPolicy"/> cho /analytics).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpAccessRequirement.Surface">
            <summary>Mặt MCP mà endpoint này phục vụ — quyết định audience token OAuth phải mang.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpAccessHandler">
            <summary>
            Endpoint MCP chỉ mở cho user đã xác thực, <b>còn sống và không bị khoá</b> (Identity <c>LockoutEnd</c> —
            cơ chế vô hiệu tài khoản của LADA; JWT login/refresh và PAT đều kiểm, đường OAuth phải kiểm ở đây vì
            OpenIddict tự cấp lại token từ principal đã lưu), <b>không phải Founder</b> (plan §1.3, §7.4d), có ít nhất
            một role MCP (<see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.RolePrefixes"/>), và — với token OAuth — <b>token được cấp cho đúng
            resource của endpoint này</b>. Từng tool còn kiểm role/scope riêng (<see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.IMcpToolGuard"/>).
            </summary>
            <remarks>
            <para>
            Gọi <c>context.Fail</c> chứ không chỉ "không Succeed": <c>ServerRoleAuthorizationHandler</c> chạy cho mọi policy và
            Succeed MỌI requirement khi user là Founder — chỉ Fail tường minh mới thắng được bypass đó.
            </para>
            <para>
            <b>Kiểm audience</b> (đợt MCP số liệu): OpenIddict validation nhận token của CẢ HAI resource (<c>AddAudiences</c> cả
            hai), nên nếu không kiểm ở đây thì token xin cho <c>/mcp</c> dùng được ở <c>/analytics</c> và ngược lại. Scope đã
            chặn tool của mặt kia, nhưng hàng rào này làm việc tách hai connector không phụ thuộc vào việc scope luôn được
            cấp đúng. PAT không có audience — PAT gác bằng scope ở từng tool.
            </para>
            <para>
            Endpoint chỉ đòi "có role MCP nào đó", KHÔNG đòi đúng tiền tố của mặt này: token của người chỉ có
            <c>ContentStore.Draft</c> gọi <c>/analytics</c> vẫn tới được tool và nhận <c>FORBIDDEN</c> nêu thiếu
            <c>Analytics.Read</c> — một câu trợ lý đọc được, thay vì HTTP 403 trần.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpAccessHandler.#ctor(Ladaer.BackEnd.Infrastructures.Services.Identity.IUserRoleResolver,Lada.Framework.Data.Repositories.IUserRepository{Lada.Framework.Data.Domains.Identity.User},Microsoft.Extensions.Logging.ILogger{Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpAccessHandler},Ladaer.BackEnd.Infrastructures.Mcp.McpSurfaceRegistry)">
            <remarks>
            <paramref name="surfaces"/> BẮT BUỘC: hàng rào audience phải fail-closed — một cách dựng DI thiếu registry là lỗi
            khởi tạo, không phải một handler âm thầm bỏ qua bước tách token /mcp khỏi /analytics.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpApplicationManager">
            <summary>
            Application manager của OpenIddict với một khác biệt: redirect URI <b>loopback</b> so khớp <b>bỏ qua cổng</b>
            (RFC 8252 §7.3). Claude Code khai <c>http://localhost/callback</c> / <c>http://127.0.0.1/callback</c> không cổng
            rồi mở cổng tạm (ví dụ :3118) mỗi lần đăng nhập; OpenIddict mặc định so chính xác chuỗi nên sẽ trả
            <c>invalid_redirect_uri</c>. Redirect URI không phải loopback (claude.ai, chatgpt.com) vẫn so chính xác.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Auth.LoopbackRedirectUri">
            <summary>Luật thuần so khớp redirect URI loopback — test được không cần OpenIddict.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Auth.LoopbackRedirectUri.Matches(System.String,System.Uri)">
            <summary>Cùng scheme, cùng host (không phân biệt hoa thường), cùng đường dẫn và query; cổng bỏ qua.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpRedirectAllowlist">
            <summary>
            Allowlist redirect URI cho đăng ký client động — luật thuần, đọc từ AppConfig
            <c>ContentStore.McpRedirectAllowlist</c> (cách nhau bằng dấu chấm phẩy; hậu tố <c>*</c> là ký tự đại diện đường dẫn).
            Host loopback khớp mọi cổng (RFC 8252 §7.3); host khác phải trùng cổng. Chỉ nhận https, trừ http loopback.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpClientRegistrationOutcome">
            <summary>Kết quả đăng ký: 201 kèm metadata client, hoặc mã lỗi RFC 7591.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpClientRegistrationValidator">
            <summary>Kiểm metadata đăng ký — luật thuần để test không cần OpenIddict.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpClientRegistrationValidator.Validate(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.McpClientRegistrationRequest,Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpRedirectAllowlist,System.Collections.Generic.List{System.Uri}@)">
            <summary>Null khi hợp lệ; ngược lại là lỗi để trả 400.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpClientRegistrationValidator.CleanClientName(System.String)">
            <summary>Tên client hiển thị trên trang đồng ý — cắt ngắn, bỏ ký tự điều khiển; rỗng → "Client MCP".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpClientRegistrationService">
            <summary>
            Đăng ký client động (RFC 7591) vì OpenIddict 7.6.1 chưa có (issue #2404): tạo public client PKCE trong
            <c>OpenIddictApplications</c> với quyền tối thiểu (authorize, token, revocation, code + refresh, scope của các mặt
            MCP). Claude tạo client mới mỗi lần kết nối — bảng sẽ phình dần, dọn định kỳ là việc sổ nợ.
            </summary>
            <remarks>
            Một client được cấp scope và <c>rsrc:</c> của CẢ HAI mặt (<c>/mcp</c>, <c>/analytics</c>): DCR diễn ra trước khi
            biết người dùng là ai, và client của Claude không cho biết nó định nối mặt nào. Ranh giới thật nằm ở bước đồng ý
            (<c>ConnectController</c> chỉ cấp scope thuộc resource đã xin, và đòi role của mặt đó) và ở audience của token
            (<c>McpAccessHandler</c>) — quyền theo client ở đây chỉ là trần.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpConsentDecision">
            <summary>Kết quả bước đồng ý OAuth: resource + scope sẽ cấp, hoặc lý do từ chối.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpConsentDecision.Resources">
            <summary>Resource ghi vào token (audience).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpConsentDecision.Scopes">
            <summary>Scope sẽ cấp — giao của scope xin với scope thuộc các resource đã xin (+ offline_access nếu xin).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpConsentDecision.DroppedScopes">
            <summary>Scope client xin nhưng không thuộc resource đã xin — bị bỏ, không cấp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpConsentDecision.Denial">
            <summary>Lý do từ chối (tiếng Việt, hiện cho người dùng); null khi được cấp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpConsentDecision.DisplayName">
            <summary>Tên các mặt MCP đang xin, để trang đồng ý nói đúng "kết nối cái gì".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpConsentPolicy">
            <summary>
            Luật cấp quyền ở trang đồng ý OAuth khi một issuer phục vụ HAI mặt MCP (<c>/mcp</c> và <c>/analytics</c>) — luật
            thuần để test không cần OpenIddict.
            </summary>
            <remarks>
            <list type="number">
            <item>Founder bị từ chối (plan Content Store §7.4d).</item>
            <item>Không gửi <c>resource</c> → coi là <c>/mcp</c> (hành vi trước khi có mặt thứ hai; client MCP hiện hành đều gửi
            <c>resource</c> theo RFC 8707).</item>
            <item>User phải có role của MỌI mặt đã xin (<c>ContentStore.*</c> cho /mcp, <c>Analytics.*</c> cho /analytics).</item>
            <item><b>Scope không lọt chéo</b>: chỉ cấp scope thuộc các resource đã xin; scope của mặt kia bị bỏ im lặng (OAuth
            cho phép cấp ít hơn xin — phản hồi token ghi scope thật). Không còn scope nào của mặt đã xin → từ chối.</item>
            </list>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpTokenRequestUserCheckHandler">
            <summary>
            Chặn cấp lại token ở <c>/connect/token</c> (grant <c>refresh_token</c> / <c>authorization_code</c>) khi user
            trong principal đã xoá mềm, đang bị khoá (<c>LockoutEnd</c> — cơ chế vô hiệu tài khoản của LADA), là Founder
            hoặc không còn role của mặt MCP mà token phục vụ (<c>ContentStore.*</c> cho /mcp, <c>Analytics.*</c> cho
            /analytics). OpenIddict mặc định tự cấp lại từ principal đã lưu, không hỏi DB —
            không có handler này thì connector của nhân viên đã nghỉ vẫn sống tới hết hạn refresh token
            (finding security review GĐ C). <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpAccessHandler"/> chặn ở từng lời gọi /mcp; handler này cắt sớm
            hơn một bước, ngay lúc xin token.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Auth.McpTokenRequestUserCheckHandler.DenialReasonAsync(System.Int32,System.Collections.Generic.IEnumerable{System.String})">
            <summary>
            Null nếu user còn dùng được MCP của các resource trong token. Token của resource nào thì user phải còn role
            của mặt đó (token /analytics đòi Analytics.*, token /mcp đòi ContentStore.*); token cũ không ghi resource được
            coi là của /mcp — trước đợt MCP số liệu chỉ có một resource.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Auth.PatAuthenticationHandler">
            <summary>
            Scheme <see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.PatSchemeName"/>: xác thực <c>Authorization: Bearer lada_cs_…</c> bằng
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentAccessTokenService.Validate(System.String)"/>. Principal mang cùng tên claim với token OpenIddict
            (<c>sub</c>, <c>name</c>) cộng claim chuẩn .NET để guard và service dùng chung một cách đọc.
            Không có token PAT → NoResult (policy scheme chỉ chuyển tới đây khi thấy tiền tố).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.ContentStoreMcpTool`1">
            <summary>
            Lớp nền của 13 tool MCP kho nội dung AI — và, qua lớp con mỏng <c>AnalyticsMcpTool&lt;TInput&gt;</c>, của tool MCP số
            liệu (tên lớp giữ nguyên trong đợt đó để không chạm 13 tool đang chạy; đổi tên trung lập là AN-11).
            Mỗi tool là một class con nhỏ: tên snake_case, mô tả tiếng Việt
            (+ một dòng tiếng Anh, ví dụ), role bắt buộc (đúng role action REST tương ứng), scope, và phần thân chỉ gọi
            service GĐ A/B — <b>MCP không có luật riêng</b>, nó là lớp vận chuyển thứ hai bên cạnh REST.
            </summary>
            <remarks>
            Tự cài <see cref="T:ModelContextProtocol.Server.McpServerTool"/> thay vì <c>[McpServerTool]</c> reflection của SDK để: (1) schema tham số sinh
            từ DTO với tên snake_case và mô tả tiếng Việt (<see cref="M:Ladaer.BackEnd.Infrastructures.Mcp.McpJson.BuildInputSchema(System.Type)"/>); (2) tham số đọc bằng
            Newtonsoft như REST; (3) mọi kết quả — kể cả từ chối quyền, tham số sai, lỗi hệ thống — đều là một vỏ
            <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.McpToolOutcome"/> với <c>isError</c>, không bao giờ là JSON-RPC error làm trợ lý mất ngữ cảnh.
            Instance là singleton không trạng thái; service lấy từ <c>request.Services</c> (scope của HTTP request vì
            transport chạy Stateless).
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.ContentStoreMcpTool`1.Metadata">
            <summary>Không dùng attribute reflection của SDK — không có metadata kèm theo.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.ContentStoreMcpTool`1.InvokeCoreAsync(System.Security.Claims.ClaimsPrincipal,System.IServiceProvider,System.Collections.Generic.IDictionary{System.String,System.Text.Json.JsonElement},System.Threading.CancellationToken)">
            <summary>
            Toàn bộ vòng đời một lời gọi, tách khỏi <see cref="T:ModelContextProtocol.Server.RequestContext`1"/> để test gọi thẳng:
            guard quyền → đọc tham số → chạy thân tool → vỏ kết quả + log.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.ContentStoreMcpTool`1.ExecuteAsync(`0,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor,System.IServiceProvider,System.Threading.CancellationToken)">
            <summary>Thân tool: gọi service, trả vỏ kết quả. Lỗi nghiệp vụ nằm trong vỏ, không ném exception.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.ContentStoreMcpTool`1.ArgumentErrorCode">
            <summary>
            Mã lỗi khi tham số sai kiểu/sai enum. Kho nội dung: <c>VALIDATION_ERROR</c> (bảng mã của hợp đồng 0.3); mặt số
            liệu đổi thành <c>INVALID_PARAM</c> cho khớp bảng mã lỗi của hợp đồng của nó.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.ContentStoreMcpTool`1.OnCompletedAsync(Ladaer.BackEnd.Infrastructures.Mcp.McpToolCompletion,System.IServiceProvider,System.Threading.CancellationToken)">
            <summary>
            Gọi ở MỌI đường ra của một lời gọi — kể cả bị guard từ chối (<see cref="P:Ladaer.BackEnd.Infrastructures.Mcp.McpToolCompletion.Caller"/> = null) và
            tham số sai — ngay trước khi trả kết quả. Mặc định không làm gì; tool số liệu dùng để ghi <c>AnalyticsCallLog</c>
            cho mọi lời gọi (plan MCP số liệu §3.10). Ngoại lệ ném ra ở đây bị nuốt + log, không đổi kết quả.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.ContentStoreMcpTool`1.DenyByInput(`0,Ladaer.BackEnd.Infrastructures.Mcp.McpCallerContext)">
            <summary>
            Cổng quyền <b>thứ hai</b>, chạy sau khi đọc tham số: dành cho tool mà quyền phụ thuộc <i>giá trị</i> tham
            số chứ không chỉ tên tool. Trả <c>null</c> là cho qua; trả một câu tiếng Việt là từ chối kèm
            <c>FORBIDDEN</c>. Mặc định không chặn gì.
            </summary>
            <remarks>
            Có vì <c>set_article_status</c>: chuyển sang <c>needs_data</c> là việc trợ lý vừa viết bài làm được
            (nó biết rõ nhất bài thiếu số gì), còn <c>hold</c> / <c>rejected</c> / <c>needs_rewrite</c> là phán xét
            của người duyệt. Một role cho cả tool thì hoặc chặn hết, hoặc mở hết — không diễn đạt được ranh giới đó.
            <para>
            Chạy ở base chứ không ở thân tool để lời từ chối luôn cùng một hình dạng (<c>FORBIDDEN</c> + có log),
            và để không tool nào lỡ trả lời "thành công" trước khi kiểm quyền.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpEmptyInput">
            <summary>Tool không tham số (list_service_pages).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpToolCompletion">
            <summary>Một lời gọi tool vừa xong — đưa cho <c>OnCompletedAsync</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpToolCompletion.User">
            <summary>Principal của request (có thể chưa xác thực).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpToolCompletion.Caller">
            <summary>Người gọi đã qua guard; null khi guard từ chối.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpToolCompletion.Arguments">
            <summary>Tham số JSON-RPC nguyên gốc.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants">
            <summary>
            Hằng số dùng chung của lớp MCP + OAuth — một nơi để không lệch chuỗi. Có hai mặt MCP trên cùng API
            (<see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.McpSurfaceKind"/>): kho nội dung AI (GĐ C đợt Content Store) và số liệu vận hành (đợt MCP số liệu);
            thứ khác nhau giữa hai mặt gom ở <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.McpSurfaceRegistry"/>.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.ServerName">
            <summary>Tên server báo cho client MCP (initialize.serverInfo.name).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.AnalyticsServerName">
            <summary>Tên server của mặt số liệu (initialize.serverInfo.name trên /analytics).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.PolicySchemeName">
            <summary>Policy scheme chọn PAT hay OpenIddict theo tiền tố token; challenge chuyển sang handler MCP (401 + resource_metadata).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.AnalyticsPolicySchemeName">
            <summary>Policy scheme của /analytics — như <see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.PolicySchemeName"/> nhưng challenge trỏ PRM của /analytics.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.AnalyticsChallengeScheme">
            <summary>Scheme <c>AddMcp</c> thứ hai: phục vụ PRM <c>/.well-known/oauth-protected-resource/analytics</c> và challenge của /analytics.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.AnalyticsMcpPolicy">
            <summary>Authorization policy gác /analytics (như <see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.McpPolicy"/>, thêm kiểm audience của token OAuth).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.PatSchemeName">
            <summary>Scheme xác thực PAT <c>lada_cs_…</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.LoginCookieScheme">
            <summary>Cookie phiên đăng nhập ngắn hạn cho trang đăng nhập/đồng ý OAuth (/connect/*).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.McpPolicy">
            <summary>Authorization policy gác endpoint /mcp: đã xác thực, không Founder, có ≥ 1 role MCP, token OAuth cấp cho đúng resource /mcp.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.McpIpRateLimitPolicy">
            <summary>Rate limit theo IP cho /mcp (trước xác thực) — chặn dội, còn 60/phút/user làm ở middleware sau xác thực.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.ScopeAnalyticsRead">
            <summary>Scope duy nhất của MCP số liệu — chỉ đọc (không có analytics:write).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.AllScopes">
            <summary>Mọi scope MCP (OAuth + PAT), không gồm offline_access.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.ScopeRolePrefixes">
            <summary>
            Scope → tiền tố role của mặt MCP sở hữu scope đó — MỘT nguồn cho OAuth (<see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.McpSurfaceRegistry"/> suy
            danh sách scope của từng mặt từ đây) và PAT (<c>ContentAccessTokenService</c>). Thêm scope/mặt mới thì thêm ở đây.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.RolePrefixOfScope(System.String)">
            <summary>Tiền tố role của mặt mà scope thuộc về — token xin scope của mặt nào thì user phải có role của mặt đó.</summary>
            <exception cref="T:System.ArgumentOutOfRangeException">Scope không thuộc mặt MCP nào (người gọi phải lọc bằng <see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.AllScopes"/> trước).</exception>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.ScopesOfRolePrefix(System.String)">
            <summary>Scope của một mặt MCP, theo thứ tự <see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.AllScopes"/>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.ScopeClaimType">
            <summary>Claim scope của principal PAT (mỗi scope một claim). Principal OpenIddict dùng claim riêng của nó (oi_scp).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.ClientIdClaimType">
            <summary>Claim nhận diện client: "pat:&lt;id&gt;" hoặc client_id OpenIddict. Tên riêng (tiền tố lada_) để không đụng claim OpenIddict tự quản.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.RolePrefixes">
            <summary>
            Tiền tố role mở cửa lớp MCP (AN-9): user phải có ≥ 1 role mang một trong các tiền tố này mới qua được endpoint,
            trang đăng nhập OAuth và bước cấp token. Role cụ thể của từng tool vẫn kiểm riêng ở <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.IMcpToolGuard"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.IsMcpRole(System.String)">
            <summary>Role thuộc lớp MCP (mang một trong <see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.RolePrefixes"/>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.RolePrefixesText">
            <summary>Danh sách tiền tố viết cho người đọc: "ContentStore.* hoặc Analytics.*".</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.MaxRequestBodyBytes">
            <summary>Giới hạn payload một lời gọi MCP — đặc tả §9 (512 KB), cùng số với REST.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.AppConfigKeys">
            <summary>Khoá AppConfig đọc lúc chạy (cache 1 giờ trong AppConfigService).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.ErrorCodes">
            <summary>Mã lỗi riêng của lớp MCP, ngoài bảng ContentStoreErrorCodes (không phải lỗi nghiệp vụ).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.ErrorCodes.Unavailable">
            <summary>Mặt MCP đang tắt bằng công tắc riêng (Analytics:Enabled = false).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.ErrorCodes.Cancelled">
            <summary>Lời gọi bị huỷ giữa chừng — CHỈ ghi vào nhật ký lời gọi, trợ lý không nhận vỏ kết quả nào.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpIpAllowlist">
            <summary>
            Whitelist IP cho endpoint MCP — luật thuần, không DB, test được: nhận danh sách "IP hoặc CIDR"
            (cách nhau bằng dấu phẩy / chấm phẩy / xuống dòng) từ AppConfig <c>ContentStore.McpAllowedIps</c>.
            IPv4 ánh xạ trong IPv6 (::ffff:1.2.3.4) được đưa về IPv4 trước khi so.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpIpAllowlist.Count">
            <summary>Số luật hợp lệ đã nạp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpIpAllowlist.Invalid">
            <summary>Mục trong cấu hình không đọc được — log để người vận hành sửa, không âm thầm bỏ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpJson">
            <summary>
            JSON của lớp MCP: <b>snake_case</b> theo đặc tả §5 (<c>topic_code</c>, <c>body_markdown</c>…), enum là chuỗi
            (<c>pending_review</c>, <c>gpt_image_2</c>), trong khi REST vẫn PascalCase — đúng như <c>ContentStoreJson</c>
            đã dự tính ("GĐ C tự chuyển sang snake_case ở lớp tool").
            </summary>
            <remarks>
            Hai bộ serializer, một luật đặt tên (<see cref="M:Ladaer.BackEnd.Infrastructures.Mcp.McpJson.ToSnakeCase(System.String)"/>):
            <list type="bullet">
            <item>Newtonsoft đọc/ghi dữ liệu thật — DTO GĐ A/B viết cho Newtonsoft (<c>[JsonExtensionData]</c> kiểu <c>JToken</c>,
            enum nhận cả số lẫn tên) nên không đổi serializer để khỏi lệch hành vi với REST.</item>
            <item>System.Text.Json chỉ để <b>sinh JSON Schema</b> tham số tool (<see cref="M:Ladaer.BackEnd.Infrastructures.Mcp.McpJson.BuildInputSchema(System.Type)"/>): .NET 9 có
            sẵn <c>JsonSchemaExporter</c>, kèm mô tả tiếng Việt lấy từ XML doc của DTO để trợ lý đọc đúng nghĩa từng trường.</item>
            </list>
            Khoá từ điển (<c>self_score.sections.A_facts</c>, <c>placeholder_counts.RealNumber</c>) là DỮ LIỆU, không đổi.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpJson.ToSnakeCase(System.String)">
            <summary>
            PascalCase → snake_case. Khác Newtonsoft/STJ mặc định ở một điểm: số đứng sau chữ thường được tách
            (<c>GptImage2</c> → <c>gpt_image_2</c> như Phụ lục A đặc tả), còn số sau chữ hoa thì dính
            (<c>CategoryL2</c> → <c>category_l2</c>, <c>H2Key</c> → <c>h2_key</c>, <c>BlogB2b</c> → <c>blog_b2b</c>).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpJson.ToSnakeCasePath(System.String)">
            <summary>
            Đường dẫn trường trong <c>ContentStoreIssue.Field</c> (<c>Images[3].PromptEn</c>, <c>SelfScore.Sections.A_facts</c>)
            → dạng trợ lý nhìn thấy (<c>images[3].prompt_en</c>). Đoạn có dấu gạch dưới sẵn (khoá dữ liệu) giữ nguyên.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpJson.ParseEnumLoose(System.Type,System.String)">
            <summary>Đọc chuỗi enum "mềm": bỏ mọi ký tự không phải chữ/số rồi so không phân biệt hoa thường — nhận cả
            <c>pending_review</c>, <c>PendingReview</c>, <c>gpt_image_2</c>, <c>gptImage2</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpJson.McpEnumConverter">
            <summary>Enum ↔ chuỗi snake_case; đọc mềm (xem <see cref="M:Ladaer.BackEnd.Infrastructures.Mcp.McpJson.ParseEnumLoose(System.Type,System.String)"/>), nhận cả số.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpJson.Settings">
            <summary>Cấu hình Newtonsoft dùng cho MỌI tham số vào và kết quả ra của tool MCP.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpJson.ParseArguments``1(System.Collections.Generic.IDictionary{System.String,System.Text.Json.JsonElement},System.Collections.Generic.List{System.String}@)">
            <summary>
            Tham số JSON-RPC (<c>arguments</c>) → DTO. Khoá không có trong DTO được trả về để tool cảnh báo
            (thường là trợ lý viết camelCase/PascalCase thay vì snake_case) chứ không âm thầm bỏ.
            </summary>
            <exception cref="T:Ladaer.BackEnd.Infrastructures.Mcp.McpArgumentException">JSON sai kiểu / enum sai giá trị — kèm đường dẫn trường.</exception>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpJson.KnownPropertyNames(System.Type)">
            <summary>Tên JSON (snake_case) của các thuộc tính DTO — để nhận ra khoá lạ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpJson.RemoveNewtonsoftExtensionData(System.Text.Json.Serialization.Metadata.JsonTypeInfo)">
            <summary>
            Thuộc tính <c>[Newtonsoft.JsonExtensionData]</c> kiểu <c>IDictionary&lt;string, JToken&gt;</c> (Brief.Extra) không có
            nghĩa trong schema và STJ không biết JToken — bỏ khỏi metadata trước khi sinh schema.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpJson.BuildInputSchema(System.Type)">
            <summary>
            JSON Schema (draft 2020-12) cho tham số một tool, sinh từ chính DTO GĐ A/B: tên snake_case, enum liệt kê
            giá trị kèm nghĩa tiếng Việt, <c>required</c> cho trường không nullable kiểu chuỗi/số/bool, <c>description</c>
            lấy từ <c>&lt;summary&gt;</c> của DTO (file Ladaer.BackEnd.xml).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpJson.IsRequired(System.Text.Json.Serialization.Metadata.JsonPropertyInfo,System.Object)">
            <summary>
            Bắt buộc = không nullable VÀ không có giá trị mặc định trong DTO: chuỗi khởi tạo rỗng (<c>= string.Empty</c>)
            hay số/enum còn ở <c>default</c> là "chưa có giá trị" → bắt buộc; <c>int Limit = 20</c>, <c>string Format = "html"</c>
            là tuỳ chọn; <c>bool</c> không bao giờ bắt buộc (vắng = false). List/object không nullable đều có <c>= new()</c> → tuỳ chọn.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpArgumentException">
            <summary>Tham số tool sai kiểu / sai enum — có đường dẫn trường để trợ lý sửa đúng chỗ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpXmlDocs">
            <summary>
            Đọc <c>&lt;summary&gt;</c> từ file XML doc của assembly (<c>Ladaer.BackEnd.xml</c>, sinh vì
            <c>GenerateDocumentationFile=True</c>) để đưa vào <c>description</c> của schema tool. Không có file thì
            schema vẫn đúng, chỉ thiếu mô tả.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpRegister">
            <summary>
            Đăng ký toàn bộ lớp MCP + OAuth 2.1 — một nơi để đọc được cả bức tranh. Hai mặt MCP trên cùng API, cùng issuer
            OAuth, cùng trang đăng nhập/đồng ý, cùng DCR và PAT (<see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.McpSurfaceRegistry"/>):
            <list type="bullet">
            <item><c>/mcp</c> — kho nội dung AI (GĐ C đợt Content Store, plan §3.4): 13 tool, role <c>ContentStore.*</c>, scope <c>content:*</c>.</item>
            <item><c>/analytics</c> — số liệu vận hành (đợt MCP số liệu, docs/plan-mcp-tra-cuu-so-lieu.md §3.1): tool số liệu,
            role <c>Analytics.Read</c>, scope <c>analytics:read</c>, PRM và chỉ dẫn riêng.</item>
            </list>
            Gồm: OpenIddict (server + validation + EF store trên LadaDbContext), scheme PAT, hai policy scheme chọn scheme theo
            tiền tố token, hai handler challenge MCP (401 + resource_metadata, mỗi cái phục vụ PRM của một mặt), hai policy,
            một server MCP Streamable HTTP stateless mà <c>ConfigureSessionOptions</c> đổi bộ tool + chỉ dẫn theo endpoint, và
            ba điểm mắc vào pipeline.
            </summary>
            <remarks>
            Luật mà trợ lý AI đọc nằm ở <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract"/> (kho nội dung) và
            <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.Analytics.AnalyticsMcpContract"/> (số liệu) — đổi hành vi thì sửa ở đó <b>trong cùng commit</b>, đừng để chỉ dẫn
            nói một đằng code làm một nẻo.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpRegister.ConfigureSurfaceSessionAsync(Microsoft.AspNetCore.Http.HttpContext,ModelContextProtocol.Server.McpServerOptions,System.Threading.CancellationToken)">
            <summary>
            <c>HttpServerTransportOptions.ConfigureSessionOptions</c>: chọn bộ tool + chỉ dẫn theo mặt của endpoint đã route
            (<see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.McpSurfaceMetadata"/>). Ở chế độ Stateless SDK 2.2.0 gọi hàm này MỖI request trên một
            <c>McpServerOptions</c> mới dựng từ <c>IOptionsFactory</c> — kết luận spike GĐ A, xem plan §4.
            </summary>
            <remarks>
            Thiếu metadata là lỗi cấu hình → ném (fail-closed), không đoán mặt theo chuỗi path. Mặt kho nội dung giữ nguyên
            options factory dựng (13 tool + chỉ dẫn 0.3) — hành vi <c>/mcp</c> không đổi.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpRegister.RegisterAnalyticsServices(Microsoft.Extensions.DependencyInjection.IServiceCollection,Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings)">
            <summary>Dịch vụ của miền số liệu (docs/plan-mcp-tra-cuu-so-lieu.md GĐ A).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpRegister.ConfigureKeys(Microsoft.Extensions.DependencyInjection.OpenIddictServerBuilder,Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreMcpSettings,Microsoft.AspNetCore.Hosting.IWebHostEnvironment)">
            <summary>
            Khoá ký (RSA PEM, bắt buộc bất đối xứng) và khoá mã hoá (đối xứng base64). Thiếu: Production → dừng khởi động
            (token OAuth mà mất hiệu lực mỗi lần deploy là lỗi vận hành, không được im lặng); môi trường khác → khoá tạm + cảnh báo
            để máy dev không vỡ vì thiếu cấu hình.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpRegister.UseContentStoreMcpGate(Microsoft.AspNetCore.Builder.IApplicationBuilder)">
            <summary>
            Trước UseAuthentication: request-id, giới hạn thân, công tắc McpEnabled (503), whitelist IP (403) — chỉ path của
            hai mặt MCP (cùng công tắc tổng và whitelist: cả hai chỉ mở cho dải IP của Anthropic).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpRegister.UseContentStoreMcpUserRateLimit(Microsoft.AspNetCore.Builder.IApplicationBuilder)">
            <summary>Sau UseAuthorization: N lời gọi / phút / user → 429 — chỉ path của hai mặt MCP (chung một hạn mức mỗi user).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpRegister.MapContentStoreMcp(Microsoft.AspNetCore.Routing.IEndpointRouteBuilder)">
            <summary>
            Map endpoint của hai mặt MCP: mỗi mặt gắn <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.McpSurfaceMetadata"/> (để <see cref="M:Ladaer.BackEnd.Infrastructures.Mcp.McpRegister.ConfigureSurfaceSessionAsync(Microsoft.AspNetCore.Http.HttpContext,ModelContextProtocol.Server.McpServerOptions,System.Threading.CancellationToken)"/>
            chọn bộ tool), policy của nó (qua policy scheme của nó) và rate limit theo IP (600/phút). Rate limiter
            chạy sau <c>UseAuthentication</c> từ 2026-10-16 (để giới hạn toàn cục tính theo user), nên policy IP này
            cũng đứng sau xác thực; hàng rào trước xác thực của MCP là whitelist IP ở <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.Middleware.McpGateMiddleware"/>.
            </summary>
            <remarks>
            Không trả builder: convention nào gắn thêm vào một builder duy nhất sẽ chỉ áp lên một mặt — hàng rào nào cần cho
            endpoint MCP thì thêm TRONG vòng lặp này để cả hai mặt cùng nhận.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract">
            <summary>
            <b>Hợp đồng giữa server và trợ lý AI</b> — chỉ dẫn server (<c>initialize.instructions</c>) và những câu luật
            mà mô tả tool dùng chung. Đây là <b>nguồn sự thật duy nhất</b>: trợ lý đọc nó tự động mỗi phiên, không cần ai
            nhắc, kể cả lượt chạy tự động lúc 6 giờ sáng.
            </summary>
            <remarks>
            <para>
            <b>Luật giữ hợp đồng khỏi lệch pha</b> (phản hồi của trợ lý AI 2026-09-13): đổi hành vi thì sửa mô tả
            <b>trong cùng commit</b>, và nâng <see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract.Version"/> + <see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract.EffectiveDate"/>. Trợ lý so số hiệu này
            với đặc tả nó đang cầm để biết bên nào cũ. Tài liệu nào ghi khác mô tả tool thì <b>mô tả tool đúng</b>.
            </para>
            <para>
            Lịch sử đã cắn phải: cơ chế ô chờ <c>[[CẦN …]]</c> bị bỏ 2026-09-12 trong code nhưng chỉ dẫn server vẫn ghi
            "giữ nguyên ô [[CẦN …]] cho số liệu chưa có", nên trợ lý vừa được bảo để ô lại vừa bị cảnh báo
            <c>LEGACY_PLACEHOLDER</c> vì đã để ô — server tự mâu thuẫn với chính nó suốt một ngày.
            </para>
            <para>
            Ca test <c>McpContractTests</c> canh: không mô tả tool nào còn dạy để ô chờ, và chỉ dẫn server luôn mang số
            hiệu hợp đồng.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract.Version">
            <summary>Số hiệu hợp đồng. Nâng khi hành vi hoặc luật viết bài đổi, không nâng khi chỉ sửa câu chữ.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract.EffectiveDate">
            <summary>
            Ngày hành vi của bản hợp đồng này bắt đầu có hiệu lực. 0.3 = mở hàng đợi viết lại: người duyệt đánh dấu
            <c>needs_rewrite</c> được (kèm lý do bắt buộc) và có tool <c>list_articles</c> để trợ lý lấy hàng đợi đó.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract.Stamp">
            <summary>Chuỗi trợ lý so với đặc tả nó đang cầm: <c>contract: 0.3 — 2026-09-13</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract.NgayBoOCho">
            <summary>Ngày bỏ cơ chế ô chờ <c>[[CẦN …]]</c> — luật số liệu vẫn nhắc lại ngày này, không phải ngày hợp đồng.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract.QuyTacSoLieu">
            <summary>
            Luật số liệu — câu thay thế cơ chế ô chờ. Dùng chung cho mô tả <c>create_article_draft</c> và
            <c>update_article</c> để hai chỗ không bao giờ nói hai điều khác nhau.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract.CachLamThayOCho">
            <summary>
            Cảnh báo khi bài còn chuỗi <c>[[CẦN …]]</c> — nói <b>cách làm đúng</b>, không chỉ nói cách cũ đã bỏ.
            Tầng service phát cảnh báo này (<c>ContentArticleService</c>, <c>ContentPublishService</c>) nên giữ cùng
            một lời để trợ lý đọc đâu cũng thấy một luật.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract.Instructions">
            <summary>Chỉ dẫn server trả trong <c>initialize</c> — thứ trợ lý đọc trước khi gọi tool đầu tiên.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpSurfaceKind">
            <summary>Hai "mặt" MCP trên cùng API: kho nội dung (<c>/mcp</c>) và số liệu vận hành (<c>/analytics</c>).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpSurfaceMetadata">
            <summary>
            Metadata gắn lên endpoint <c>MapMcp</c> để <c>ConfigureSessionOptions</c> biết request thuộc mặt nào — đọc metadata
            của endpoint đã route chắc hơn so khớp chuỗi path (không lo PathBase, dấu / cuối, hoa thường).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpSurface">
            <summary>
            Mọi thứ khác nhau giữa hai mặt MCP, gom một chỗ: đường dẫn, resource OAuth (= URL người dùng nhập vào connector),
            PRM, tiền tố role, scope, scheme challenge và policy. Mọi so khớp path / resource / tiền tố role của lớp MCP đi qua
            đây — không rải chuỗi <c>"/analytics"</c> hay <c>"ContentStore."</c> khắp nơi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpSurface.Path">
            <summary>Đường dẫn endpoint trên API: "/mcp", "/analytics".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpSurface.Resource">
            <summary>Resource OAuth — ĐÚNG URL người dùng nhập vào connector (không dấu / cuối).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpSurface.ResourceMetadataUrl">
            <summary>URL tài liệu PRM (RFC 9728) của mặt này — <c>&lt;issuer&gt;/.well-known/oauth-protected-resource&lt;path&gt;</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpSurface.RolePrefix">
            <summary>Tiền tố role mở cửa mặt này: "ContentStore.", "Analytics.".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpSurface.Scopes">
            <summary>Scope OAuth thuộc mặt này (không gồm offline_access).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpSurface.DisplayName">
            <summary>Tên hiển thị trên PRM và trang đồng ý.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpSurface.ChallengeScheme">
            <summary>Scheme <c>AddMcp</c> — phục vụ PRM và ghi <c>WWW-Authenticate: Bearer resource_metadata=…</c> khi 401.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpSurface.PolicyScheme">
            <summary>Policy scheme chọn PAT/OpenIddict theo tiền tố token, chuyển challenge/forbid sang <see cref="P:Ladaer.BackEnd.Infrastructures.Mcp.McpSurface.ChallengeScheme"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpSurface.AuthorizationPolicy">
            <summary>Authorization policy gác endpoint.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpSurfaceRegistry">
            <summary>Hai mặt MCP dựng từ appsettings — singleton.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpSurfaceRegistry.IsMcpPath(Microsoft.AspNetCore.Http.PathString)">
            <summary>Request thuộc path của một mặt MCP nào đó.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpSurfaceRegistry.FindByResource(System.String)">
            <summary>Mặt có resource đúng nguyên văn (so không phân biệt dấu / cuối); null khi không khớp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpSurfaceRegistry.AllScopes">
            <summary>Scope OAuth của mọi mặt (không gồm offline_access).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpCallerContext">
            <summary>Người gọi tool sau khi qua guard — dựng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor"/> cho service GĐ A/B.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpCallerContext.Client">
            <summary>"mcp:&lt;client_id&gt;" (OAuth) hoặc "pat:&lt;id&gt;" — vào cột ContentAuditLog.Client (≤ 100 ký tự).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpToolDeniedException">
            <summary>Guard từ chối — mã lỗi là <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.ErrorCodes"/>, thông điệp tiếng Việt trả thẳng cho trợ lý.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.IMcpToolGuard">
            <summary>
            Kiểm quyền cho MỖI lời gọi tool: đã xác thực → không phải Founder (plan §7.4d) → có ≥ 1 role MCP
            (<see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.RolePrefixes"/>) → có role của tool (đúng role mà action REST tương ứng đòi) → token có
            scope của tool (content:read / content:write / analytics:read).
            Role đọc từ DB qua <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserRoleResolver"/> (cache 15 phút), không từ claim — như REST.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpPrincipal">
            <summary>Đọc claim từ principal của cả hai scheme (OpenIddict dùng tên claim JWT: sub, name, oi_scp; PAT thêm claim chuẩn .NET).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpPrincipal.GetScopes(System.Security.Claims.ClaimsPrincipal)">
            <summary>Hợp của claim "scope" (PAT, một claim mỗi scope hoặc cách nhau bằng dấu cách) và scope OpenIddict (oi_scp).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpPrincipal.GetClient(System.Security.Claims.ClaimsPrincipal)">
            <summary>"pat:&lt;id&gt;" hoặc "mcp:&lt;client_id&gt;" — client_id đặt lúc đồng ý, dự phòng lấy presenter của OpenIddict.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpPrincipal.GetAudiences(System.Security.Claims.ClaimsPrincipal)">
            <summary>
            Audience của token OAuth = resource đã cấp lúc đồng ý (OpenIddict ghi claim riêng <c>oi_aud</c> khi đọc token,
            cộng claim chuẩn <c>aud</c> phòng khi token đọc theo đường khác). PAT không có audience.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpToolOutcome">
            <summary>
            Vỏ kết quả của mọi tool — chính là <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreResult`1"/> ở dạng snake_case, để trợ lý đọc
            một cấu trúc cho cả 13 tool: <c>success</c>, <c>data</c>, <c>error_code</c>, <c>message</c>, <c>errors[]</c>
            (kèm <c>field</c>/<c>position</c>), <c>warnings[]</c>, <c>extra</c>, <c>request_id</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpToolOutcome.RequestId">
            <summary>Mã yêu cầu — cùng chuỗi ghi vào ContentAuditLog.RequestId và log server, để tra vết.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpToolOutcome.RowCount">
            <summary>Số dòng dữ liệu tool trả — CHỈ để ghi nhật ký lời gọi (AnalyticsCallLog), không gửi cho trợ lý.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.McpToolOutcome.From``1(Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreResult{``0})">
            <summary>Kết quả service → vỏ MCP. Tên trường trong Errors và khoá Extra đổi sang snake_case; mã lỗi giữ nguyên (hợp đồng §5.4).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.McpIssue">
            <summary>Một vi phạm — bản snake_case của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreIssue"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.McpIssue.Field">
            <summary>Đường dẫn trường theo tên tham số tool: <c>images[3].prompt_en</c>, <c>self_score.sections.A_facts</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Middleware.McpGateMiddleware">
            <summary>
            Cổng TRƯỚC xác thực cho /mcp, theo thứ tự rẻ → đắt: gắn request-id → giới hạn thân request 512 KB →
            công tắc <c>ContentStore.McpEnabled</c> (tắt → 503, REST/OAuth vẫn sống) → whitelist IP
            (<c>ContentStore.McpIpWhitelistEnabled</c> + <c>ContentStore.McpAllowedIps</c>, sai IP → 403).
            Chỉ mắc vào path MCP (xem <c>McpRegister.UseContentStoreMcpGate</c>).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Middleware.McpUserRateLimiter">
            <summary>
            Giới hạn N lời gọi / phút / <b>user</b> cho /mcp (N = AppConfig <c>ContentStore.McpRateLimitPerMinute</c>, mặc định 60).
            Luật thuần trên <see cref="T:System.Threading.RateLimiting.PartitionedRateLimiter`1"/>; một limiter cho mỗi ngưỡng để đổi ngưỡng
            lúc chạy không cần khởi động lại. Singleton.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Middleware.McpUserRateLimitMiddleware">
            <summary>
            Chạy SAU UseAuthorization (đã có user) cho path MCP: lời gọi thứ N+1 trong một phút của cùng user → 429 kèm
            Retry-After. Rate limit theo IP (chống dội, 600/phút) làm ở policy <see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.McpConstants.McpIpRateLimitPolicy"/>;
            whitelist IP trước xác thực nằm ở <see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.Middleware.McpGateMiddleware"/>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.CreateArticleDraftTool">
            <summary><c>create_article_draft</c> — tool chính, đặc tả §5.2.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.UpdateArticleTool">
            <summary><c>update_article</c> — đặc tả §5.2.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.GetArticleTool">
            <summary><c>get_article</c> — đặc tả §5.2.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListArticlesTool">
            <summary>
            <c>list_articles</c> — đặc tả §5.2. Bọc <c>IContentArticleService.Search</c> (đường REST của màn danh sách
            cũng đi qua đúng hàm này) và cắt bớt cột: danh sách là để <b>chọn bài</b>, đọc bài là việc của
            <c>get_article</c>.
            </summary>
            <remarks>
            Sinh ra cho hàng đợi viết lại (quyết định 2026-09-13): trước đó trợ lý không có tool nào liệt kê bài, nên
            muốn viết lại 55 bài cũ phải dán tay danh sách mã bài mỗi phiên — không xong trong một lượt, phiên sau
            không biết bài nào đã làm, nên vừa sót vừa trùng.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListArticlesTool.LimitToiDa">
            <summary>Trần số dòng một lời gọi — danh sách dài hơn thì phân trang bằng <c>page</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.SetArticleStatusTool">
            <summary><c>set_article_status</c> — đặc tả §5.2 (trừ approved: GĐ E).</summary>
            <remarks>
            <b>Quyền phụ thuộc đích</b> (phản hồi của trợ lý AI 2026-09-13). Hợp đồng bảo trợ lý "cả bài phụ thuộc số
            chưa có thì set_article_status needs_data", nhưng tool đòi <c>ContentStore.Edit</c> mà tài khoản trợ lý chỉ
            có Search/GetById/Draft — chỉ dẫn dạy một việc mà server từ chối làm, suốt từ 0.2.
            <para>
            Chữa bằng cách mở đúng một đích: <c>ContentStore.Draft</c> chuyển được sang <c>needs_data</c> — nó vừa viết
            bài, nó biết rõ nhất bài thiếu số gì. Mọi đích còn lại vẫn đòi <c>Edit</c>, vì <c>hold</c> / <c>rejected</c> /
            <c>needs_rewrite</c> là phán xét của người duyệt (ranh giới "trợ lý nhận hàng đợi, không tạo hàng đợi").
            Cấp thẳng <c>Edit</c> cho tài khoản trợ lý thì mở hết cả ba đích kia — không làm.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Mcp.Tools.SetArticleStatusTool.DichChoDraft">
            <summary>Đích duy nhất mà role <c>ContentStore.Draft</c> tự chuyển được.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Mcp.Tools.SetArticleStatusTool.DenyByInput(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleStatusModel,Ladaer.BackEnd.Infrastructures.Mcp.McpCallerContext)">
            <summary>
            Không có <c>ContentStore.Edit</c> thì chỉ đi được tới <see cref="F:Ladaer.BackEnd.Infrastructures.Mcp.Tools.SetArticleStatusTool.DichChoDraft"/>. Thiếu <c>status</c> thì
            cho qua để service trả VALIDATION_ERROR — "quên tham số" không phải chuyện thiếu quyền.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.RenderArticleTool">
            <summary><c>render_article</c> — đặc tả §5.2.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.CheckSlugTool">
            <summary><c>check_slug</c> — đặc tả §5.3.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListServicePagesTool">
            <summary><c>list_service_pages</c> — đặc tả §5.3.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListPeopleTool">
            <summary><c>list_people</c> — đặc tả §5.3.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ContentStoreMcpTools">
            <summary>
            Danh sách 13 tool đăng ký vào server — thứ tự hiện trong <c>tools/list</c>. Mô tả từng tool là hợp đồng với
            trợ lý AI (<see cref="T:Ladaer.BackEnd.Infrastructures.Mcp.McpServerContract"/>): đổi hành vi thì sửa mô tả trong cùng commit.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.CreateTopicsInput">
            <summary>Tham số <c>create_topics</c> — danh sách đề bài (đặc tả §5.1).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.CreateTopicsInput.Topics">
            <summary>Các đề bài cần thêm vào hàng đợi; mã trùng bị từ chối từng dòng, tiêu đề trùng ≥ 85% chỉ cảnh báo.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.GetArticleInput">
            <summary>Tham số <c>get_article</c> — chọn bài bằng MỘT trong ba khoá, và chọn phần muốn nhận để tiết kiệm ngữ cảnh.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.GetArticleInput.ArticleId">
            <summary>Id bài (ưu tiên nếu gửi kèm mã đề/slug).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.GetArticleInput.TopicCode">
            <summary>Mã đề bài dạng W2-01.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.GetArticleInput.Slug">
            <summary>Slug bài (không dấu, gạch nối).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.GetArticleInput.IncludeBody">
            <summary>Kèm thân bài Markdown (có thể tới 200 KB). Mặc định true.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.GetArticleInput.IncludeImages">
            <summary>Kèm bộ ảnh. Mặc định true.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.GetArticleInput.IncludeScore">
            <summary>Kèm phiếu tự chấm. Mặc định true.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListArticlesInput">
            <summary>
            Tham số <c>list_articles</c> — bộ lọc của <c>IContentArticleService.Search</c> viết phẳng ra, mọi trường
            đều tuỳ chọn. Không có khoá nào thì trả trang đầu của toàn kho, mới sửa lên trước.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListArticlesInput.Status">
            <summary>Lọc theo trạng thái bài; needs_rewrite chính là hàng đợi viết lại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListArticlesInput.CategoryL2">
            <summary>Mã nhánh L2, ví dụ "A2".</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListArticlesInput.PageType">
            <summary>Lọc theo loại trang.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListArticlesInput.WeekNo">
            <summary>Tuần của đề bài.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListArticlesInput.Keyword">
            <summary>Tìm chứa chuỗi trong tiêu đề, slug hoặc mã đề.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListArticlesInput.DraftedBy">
            <summary>Lọc theo người/máy đã nháp, ví dụ "claude-routine" (khớp đúng cả chuỗi).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListArticlesInput.Limit">
            <summary>Số dòng một trang. Mặc định 20, tối đa 50.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListArticlesInput.Page">
            <summary>Trang thứ mấy, đếm từ 1. Mặc định 1.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListArticlesRow">
            <summary>
            Một dòng kết quả <c>list_articles</c> — <b>rút gọn có chủ đích</b>: đủ để chọn bài và biết phải sửa gì,
            không có thân bài. Cần cả bài thì gọi <c>get_article</c> cho đúng bài đã chọn.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListArticlesRow.StatusReason">
            <summary>Câu người duyệt ghi khi đánh dấu — với needs_rewrite đây là yêu cầu sửa.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListArticlesRow.CurrentVersionNo">
            <summary>Số phiên bản hiện tại — dùng làm <c>expected_version</c> khi gọi update_article.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.CheckSlugInput">
            <summary>Tham số <c>check_slug</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.CheckSlugInput.Slug">
            <summary>Slug muốn dùng, dạng van-chuyen-tu-dong-di-tinh.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.RenderArticleInput">
            <summary>Tham số <c>render_article</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.RenderArticleInput.ArticleId">
            <summary>Id bài.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Mcp.Tools.RenderArticleInput.Format">
            <summary>"html" (mặc định) hoặc "markdown".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.ListTopicsTool">
            <summary><c>list_topics</c> — đặc tả §5.1.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.CreateTopicsTool">
            <summary><c>create_topics</c> — đặc tả §5.1.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.UpdateTopicStatusTool">
            <summary><c>update_topic_status</c> — đặc tả §5.1.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Mcp.Tools.AppendRunLogTool">
            <summary><c>append_run_log</c> — đặc tả §5.1.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Middleware.FrontendOriginMiddleware">
            <summary>
            Middleware kiểm tra request có đến từ frontend hợp lệ không.
            Yêu cầu header X-LADA-Client với giá trị khớp cấu hình trong appsettings.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Middleware.FrontendOriginMiddleware.BypassPaths">
            <summary>
            Danh sách đường dẫn được bỏ qua kiểm tra (không phân biệt hoa thường)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Middleware.FrontendOriginMiddleware.ShouldBypass(System.String)">
            <summary>
            Kiểm tra xem đường dẫn có nằm trong danh sách bỏ qua không
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Middleware.FrontendOriginMiddlewareExtensions">
            <summary>
            Extension method để đăng ký middleware
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Networking.ClientIpResolver">
            <summary>
            <b>Một luật duy nhất</b> để cả API biết IP thật của client: whitelist IP của MCP, rate limit theo IP,
            và nhật ký đăng ký client DCR đều đọc ở đây.
            </summary>
            <remarks>
            <para>
            <b>Luật:</b> chỉ tin <c>X-Forwarded-For</c> khi kết nối đến từ proxy nội bộ (loopback / dải private),
            và khi đó lấy <b>phần tử cuối cùng</b> — là hop do chính proxy tin cậy nối vào (nginx
            <c>$proxy_add_x_forwarded_for</c>, IIS ARR, ngrok đều NỐI THÊM chứ không ghi đè), còn các phần tử
            trước là do client tự khai nên giả được. Kết nối thẳng từ ngoài thì dùng <c>RemoteIpAddress</c>.
            Header có mà không đọc được thì trả <c>null</c> — <b>không đoán</b>, để bên gọi đóng an toàn.
            </para>
            <para>
            <b>Vì sao gộp về đây (sổ nợ CS-23, đóng 2026-09-07):</b> trước đó tồn tại <b>hai</b> luật lệch nhau.
            <c>McpIpAllowlist</c> lấy phần tử cuối (đúng), còn <c>RateLimitingRegister.GetClientIpAddress</c> lấy
            phần tử <b>đầu</b> — nghĩa là sau khi dựng reverse proxy, bất kỳ ai cũng tự khai
            <c>X-Forwarded-For: &lt;IP bịa&gt;</c> để đổi phân vùng rate limit và bơm request không giới hạn.
            Bản cũ còn gọi <c>MapToIPv4()</c> cho <b>mọi</b> IPv6, nên một IPv6 công cộng có 4 byte cuối rơi vào
            dải riêng (ví dụ <c>2001:db8::a00:1</c> → <c>10.0.0.1</c>) bị coi là proxy nội bộ và được tin header.
            </para>
            <para>
            <b>Có hai proxy tin cậy nối tiếp</b> thì phần tử cuối là IP proxy trong → whitelist từ chối (đóng an
            toàn); khi đó đăng ký <c>ForwardedHeadersMiddleware</c> với <c>KnownProxies</c>/<c>KnownNetworks</c>
            thay vì nới luật này. Xem <c>docs/checklist-production-content-store.md</c> §5.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Networking.ClientIpResolver.Resolve(Microsoft.AspNetCore.Http.HttpContext)">
            <summary>IP thật của client, hoặc <c>null</c> khi không xác định được.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Networking.ClientIpResolver.ResolveKey(Microsoft.AspNetCore.Http.HttpContext)">
            <summary>
            Chuỗi phân vùng cho rate limit: IP đã giải, hoặc <c>"unknown"</c>.
            </summary>
            <remarks>
            Gộp mọi trường hợp không giải được vào <b>một</b> phân vùng là cố ý: kẻ gửi
            <c>X-Forwarded-For</c> rác không tự tách mình ra khỏi hạn mức của người khác được, mà lại nằm
            chung với nhau nên bị chặn sớm hơn.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Networking.ClientIpResolver.IsPrivate(System.Net.IPAddress)">
            <summary>
            IP thuộc dải nội bộ? IPv4: 10/8, 172.16/12, 192.168/16. IPv6 <b>thật</b>: link-local, site-local,
            unique-local — <b>không</b> ép <c>MapToIPv4()</c>, vì 4 byte cuối của một IPv6 công cộng không nói
            lên điều gì về việc nó có nội bộ hay không.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Networking.RateLimitPartitionKey">
            <summary>
            Khoá phân vùng cho giới hạn toàn cục: <b>theo user</b> khi request đã xác thực, <b>theo IP</b> khi chưa.
            </summary>
            <remarks>
            <para>
            Phải chạy <b>sau</b> <c>UseAuthentication</c> thì <c>HttpContext.User</c> mới có — xem thứ tự middleware ở
            <c>GeneralRegister.ConfigAndRunApp</c>. Đặt trước xác thực thì mọi request đều rơi về IP và cả văn phòng
            (một IP NAT) lại chia nhau một hạn mức như bản cũ.
            </para>
            <para>
            Chỉ tin danh tính đã được middleware xác thực <b>kiểm chữ ký</b>; không tự đọc header Authorization để
            lấy <c>sub</c>, vì khi đó ai cũng bịa được token với <c>sub</c> ngẫu nhiên để tự cấp cho mình một phân vùng
            mới và né giới hạn theo IP.
            </para>
            <para>
            Tiền tố <c>user:</c> / <c>ip:</c> là cố ý: một user có id trùng dạng chuỗi với một IP không bao giờ chung
            phân vùng, và nhìn log biết ngay phân vùng thuộc loại nào.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Networking.RateLimitPartitionKey.Partition">
            <summary>Kết quả giải khoá phân vùng.</summary>
            <param name="Key">Chuỗi phân vùng, ví dụ <c>user:42</c> hoặc <c>ip:203.0.113.5</c>.</param>
            <param name="IsUser"><c>true</c> khi phân vùng theo user đã xác thực.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Networking.RateLimitPartitionKey.Partition.#ctor(System.String,System.Boolean)">
            <summary>Kết quả giải khoá phân vùng.</summary>
            <param name="Key">Chuỗi phân vùng, ví dụ <c>user:42</c> hoặc <c>ip:203.0.113.5</c>.</param>
            <param name="IsUser"><c>true</c> khi phân vùng theo user đã xác thực.</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Networking.RateLimitPartitionKey.Partition.Key">
            <summary>Chuỗi phân vùng, ví dụ <c>user:42</c> hoặc <c>ip:203.0.113.5</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Networking.RateLimitPartitionKey.Partition.IsUser">
            <summary><c>true</c> khi phân vùng theo user đã xác thực.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Networking.RateLimitPartitionKey.Resolve(Microsoft.AspNetCore.Http.HttpContext)">
            <summary>
            Theo user khi <c>HttpContext.User</c> đã xác thực và có claim định danh (<c>sub</c> hoặc
            <c>NameIdentifier</c>, cùng luật với <see cref="M:Lada.Framework.Infrastructures.Helpers.UserHelper.GetUserId(System.Security.Claims.ClaimsPrincipal)"/>); còn lại theo IP qua
            <see cref="M:Ladaer.BackEnd.Infrastructures.Networking.ClientIpResolver.ResolveKey(Microsoft.AspNetCore.Http.HttpContext)"/>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAuthRequest">
            <summary>
            Yêu cầu tạo URL xác thực OAuth cho một kết nối.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAuthRequest.ConnectionId">
            <summary>Id kết nối — sẽ được nhúng vào tham số state để callback biết thuộc kết nối nào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAuthRequest.State">
            <summary>Chuỗi state đã ký/mã hoá, dùng chống CSRF</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAuthRequest.RedirectUri">
            <summary>Redirect URI đã đăng ký với nền tảng (ghi đè giá trị trong kết nối nếu có)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAuthResult">
            <summary>
            Kết quả trao đổi code / refresh token với nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAuthResult.Success">
            <summary>Thành công hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAuthResult.AccessToken">
            <summary>Access token mới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAuthResult.RefreshToken">
            <summary>Refresh token mới (nền tảng chỉ trả về ở lần cấp quyền đầu tiên)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAuthResult.ExpiresAt">
            <summary>Thời điểm access token hết hạn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAuthResult.ErrorMessage">
            <summary>Thông báo lỗi bằng tiếng Việt khi thất bại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAuthResult.PlatformErrorCode">
            <summary>Mã lỗi gốc của nền tảng — giữ nguyên để tra cứu tài liệu</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsProbeResult">
            <summary>
            Kết quả kiểm tra kết nối (nút "Kiểm tra kết nối" trên form cấu hình).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsProbeResult.Success">
            <summary>Gọi được API nền tảng hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsProbeResult.Message">
            <summary>Thông báo tiếng Việt cụ thể: thiếu field nào, token sai, hay thiếu quyền</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsProbeResult.MissingFields">
            <summary>Danh sách key field credential đang thiếu hoặc sai — để UI highlight đúng ô nhập</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsProbeResult.AccessibleAccountCount">
            <summary>Số tài khoản quảng cáo truy cập được (nếu nền tảng cho biết)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsProbeResult.PlatformErrorCode">
            <summary>Mã lỗi gốc của nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsProbeResult.DurationMs">
            <summary>Thời gian gọi (ms)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountDto">
            <summary>
            Tài khoản quảng cáo lấy từ nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountDto.ExternalId">
            <summary>Id tài khoản bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountDto.Name">
            <summary>Tên tài khoản</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountDto.CurrencyCode">
            <summary>Mã tiền tệ của tài khoản (không giả định VND)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountDto.TimeZone">
            <summary>Múi giờ của tài khoản</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountDto.IsManager">
            <summary>Là tài khoản quản lý (MCC / manager)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountDto.IsTestAccount">
            <summary>Là tài khoản test của nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountDto.Status">
            <summary>Trạng thái đã chuẩn hoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountDto.PlatformPayloadJson">
            <summary>Dữ liệu đặc thù nền tảng chưa map được vào canonical model</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountFetchError">
            <summary>
            Lỗi khi đọc thông tin một tài khoản quảng cáo cụ thể.
            Tách riêng để một tài khoản lỗi không làm sập cả lần đồng bộ, nhưng lỗi vẫn được
            đưa lên tới service để ghi vào sync log — nếu chỉ log ra console thì người dùng
            không có cách nào biết vì sao đồng bộ ra 0 tài khoản.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountFetchError.ExternalAccountId">
            <summary>Id tài khoản bên nền tảng (nếu biết)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountFetchError.Message">
            <summary>Thông báo lỗi tiếng Việt</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountFetchError.PlatformErrorCode">
            <summary>Mã lỗi gốc của nền tảng — giữ nguyên để tra tài liệu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountFetchError.Endpoint">
            <summary>Thao tác đã gọi khi gặp lỗi, dùng làm nhãn Endpoint trong sync log</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountFetchError.DiagnosticJson">
            <summary>
            Bối cảnh lần gọi (id tài khoản, login-customer-id, câu truy vấn) dạng JSON.
            Không chứa thông tin mật — chỉ để trả lời được câu "gọi cái gì với tham số nào".
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountFetchResult">
            <summary>
            Kết quả đọc danh sách tài khoản quảng cáo: phần đọc được và phần lỗi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountFetchResult.Accounts">
            <summary>Các tài khoản đọc được đầy đủ thông tin</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountFetchResult.Errors">
            <summary>Các tài khoản nền tảng có trả về nhưng không đọc được chi tiết</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountFetchResult.AccessibleCount">
            <summary>Số tài khoản nền tảng khai là truy cập được (trước khi đọc chi tiết)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto">
            <summary>
            Chiến dịch lấy từ nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.ExternalId">
            <summary>Id chiến dịch bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.ExternalAccountId">
            <summary>Id tài khoản quảng cáo bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.Name">
            <summary>Tên chiến dịch</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.Status">
            <summary>Trạng thái đã chuẩn hoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.Objective">
            <summary>Mục tiêu đã chuẩn hoá (suy ra từ channel type / objective của nền tảng)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.BudgetType">
            <summary>Loại ngân sách</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.BudgetAmount">
            <summary>Giá trị ngân sách theo đơn vị tiền tệ của tài khoản (đã chia micros)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.CurrencyCode">
            <summary>Mã tiền tệ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.ExternalBudgetId">
            <summary>Id ngân sách bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.BiddingStrategy">
            <summary>Chiến lược đặt giá của nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.StartDate">
            <summary>Ngày bắt đầu chạy</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.EndDate">
            <summary>Ngày kết thúc</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.ChannelType">
            <summary>Loại kênh của nền tảng (Google AdvertisingChannelType)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.ChannelSubType">
            <summary>Loại kênh con của nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.PlatformPayloadJson">
            <summary>Cấu hình đặc thù nền tảng chưa map được — không được làm mất dữ liệu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto.RawResponseJson">
            <summary>Payload gốc từ nền tảng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupDto">
            <summary>
            Nhóm quảng cáo lấy từ nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupDto.ExternalId">
            <summary>Id nhóm bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupDto.ExternalCampaignId">
            <summary>Id chiến dịch cha bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupDto.Name">
            <summary>Tên nhóm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupDto.Status">
            <summary>Trạng thái đã chuẩn hoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupDto.CpcBid">
            <summary>Giá thầu CPC tối đa (đã chia micros)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupDto.CurrencyCode">
            <summary>Mã tiền tệ của giá thầu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupDto.GroupType">
            <summary>Loại nhóm của nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupDto.PlatformPayloadJson">
            <summary>Cấu hình đặc thù nền tảng chưa map được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupDto.RawResponseJson">
            <summary>Payload gốc từ nền tảng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleDto">
            <summary>
            Một khung giờ chạy quảng cáo lấy từ nền tảng (ad schedule criterion).
            Ánh xạ 1-1 với <c>AdScheduleInfo</c> của Google — thuộc cấp chiến dịch, không phải cấp nhóm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleDto.ExternalId">
            <summary>Id criterion bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleDto.ExternalCampaignId">
            <summary>Id chiến dịch cha bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleDto.DayOfWeek">
            <summary>Thứ trong tuần</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleDto.StartHour">
            <summary>Giờ bắt đầu, 0–23</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleDto.StartMinute">
            <summary>Phút bắt đầu (Google chỉ dùng 0, 15, 30, 45)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleDto.EndHour">
            <summary>Giờ kết thúc, 0–24 (24 = hết ngày)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleDto.EndMinute">
            <summary>Phút kết thúc (Google chỉ dùng 0, 15, 30, 45)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleDto.BidModifier">
            <summary>
            Hệ số điều chỉnh giá thầu theo đúng dạng của Google (1.2 = +20%, 0.5 = -50%).
            <c>null</c> = nền tảng không set (UI Google hiện "—"); <c>0.0</c> = -100%, khác hẳn null.
            Adapter phải phân biệt hai trường hợp này bằng cờ <c>HasBidModifier</c> của proto,
            không so sánh giá trị — proto3 trả 0.0 cho field chưa set.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleDto.Status">
            <summary>Trạng thái đã chuẩn hoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleDto.RawResponseJson">
            <summary>Payload gốc từ nền tảng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAdDto">
            <summary>
            Một quảng cáo cụ thể trong nhóm, lấy về từ nền tảng (Google: <c>ad_group_ad</c>).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAdDto.ExternalId">
            <summary>
            Id quảng cáo bên nền tảng, dạng <b>id trần</b>.
            <para>
            Google trả resource name <c>customers/{cid}/adGroupAds/{adGroupId}~{adId}</c>, nhưng DTO
            này chỉ chứa <c>{adId}</c>. Việc ghép lại thành resource name là việc của adapter — nơi
            duy nhất biết định dạng của từng nền tảng. Lưu dạng ghép vào canonical entity từng gây
            hai lỗi: ghép lần hai khi bật/tắt quảng cáo, và số liệu cấp quảng cáo không khớp được.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAdDto.ExternalGroupId">
            <summary>Id nhóm quảng cáo cha bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAdDto.ExternalCampaignId">
            <summary>Id chiến dịch cha bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAdDto.Name">
            <summary>
            Tên hiển thị.
            <para>
            Google hầu như luôn để rỗng <c>ad.name</c> với quảng cáo tìm kiếm, nên adapter dựng tên
            từ tiêu đề đầu tiên của mẫu quảng cáo. Không bao giờ để trống — danh sách toàn dòng
            không tên thì người dùng không phân biệt được quảng cáo nào.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAdDto.AdType">
            <summary>Loại quảng cáo theo tên enum của nền tảng (ví dụ RESPONSIVE_SEARCH_AD)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAdDto.Status">
            <summary>Trạng thái đã chuẩn hoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAdDto.ApprovalStatus">
            <summary>
            Trạng thái xét duyệt của nền tảng, giữ nguyên tên gốc (APPROVED / DISAPPROVED /
            APPROVED_LIMITED…). Không dịch sang enum của LADA: mỗi nền tảng có tập giá trị riêng
            và người dùng cần tra đúng tên đó trong tài liệu nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAdDto.ReviewStatus">
            <summary>Trạng thái review của nền tảng (REVIEW_IN_PROGRESS / REVIEWED…)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAdDto.FinalUrl">
            <summary>URL đích đầu tiên, để người dùng đối chiếu nhanh</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAdDto.RawResponseJson">
            <summary>Payload gốc từ nền tảng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto">
            <summary>
            Một từ khoá lấy về từ nền tảng — dùng cho <b>cả từ khoá thường và từ khoá phủ định</b>,
            phân biệt bằng <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.IsNegative"/>.
            <para>
            Một DTO cho hai loại vì Google dùng chung resource <c>ad_group_criterion</c> /
            <c>campaign_criterion</c>, chỉ khác cờ <c>negative</c>. Tách hai DTO sẽ nhân đôi mọi tầng
            bên trên mà không thêm thông tin gì.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.ExternalId">
            <summary>
            Criterion id bên nền tảng, dạng <b>id trần</b> (không phải
            <c>{adGroupId}~{criterionId}</c>) — cùng quy ước với <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAdDto.ExternalId"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.ExternalCampaignId">
            <summary>Id chiến dịch cha bên nền tảng — luôn có, kể cả với từ khoá cấp nhóm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.ExternalGroupId">
            <summary>
            Id nhóm cha bên nền tảng. <c>null</c> khi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.Level"/> là
            <see cref="F:Lada.Framework.Data.Enums.AdsEntityLevel.Campaign"/> (từ khoá phủ định cấp chiến dịch không thuộc nhóm nào).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.Level">
            <summary>Cấp của từ khoá — chỉ nhận Campaign hoặc Group</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.IsNegative">
            <summary>Là từ khoá phủ định (loại trừ) hay từ khoá thường (nhắm chọn)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.Text">
            <summary>Nội dung từ khoá, không kèm dấu ngoặc biểu thị kiểu khớp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.MatchType">
            <summary>Kiểu khớp đã chuẩn hoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.CpcBid">
            <summary>
            Giá thầu CPC riêng của từ khoá. <c>null</c> = nền tảng không set (dùng giá thầu của nhóm).
            Adapter phải kiểm cờ <c>HasCpcBidMicros</c> của proto chứ không so giá trị: proto3 trả
            0 cho field chưa set, mà 0 với giá thầu là con số có nghĩa hoàn toàn khác.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.CurrencyCode">
            <summary>Mã tiền tệ của giá thầu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.Status">
            <summary>Trạng thái đã chuẩn hoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.ApprovalStatus">
            <summary>
            Trạng thái xét duyệt, giữ nguyên tên gốc của nền tảng.
            Từ khoá phủ định không được nền tảng xét duyệt nên field này rỗng — đúng, không phải lỗi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.QualityScore">
            <summary>
            Điểm chất lượng (Google: 1–10). <c>null</c> khi nền tảng chưa có đủ dữ liệu để chấm,
            hoặc với từ khoá phủ định (không được chấm điểm).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.RawResponseJson">
            <summary>Payload gốc từ nền tảng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMetricDto">
            <summary>
            Một dòng số liệu theo ngày lấy từ nền tảng.
            Chi phí đã được chia micros trong adapter — không bao giờ trả micros ra ngoài.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMetricDto.Level">
            <summary>Cấp của số liệu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMetricDto.ExternalId">
            <summary>Id đối tượng bên nền tảng (campaign / ad group / ad id)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMetricDto.ExternalAccountId">
            <summary>Id tài khoản quảng cáo bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMetricDto.Date">
            <summary>Ngày của số liệu (từ segments.date)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMetricDto.Impressions">
            <summary>Số lần hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMetricDto.Clicks">
            <summary>Số lần nhấp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMetricDto.Cost">
            <summary>Chi phí theo đơn vị tiền tệ của tài khoản</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMetricDto.CurrencyCode">
            <summary>Mã tiền tệ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMetricDto.Conversions">
            <summary>Số chuyển đổi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMetricDto.ConversionValue">
            <summary>Giá trị chuyển đổi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMetricDto.Ctr">
            <summary>Tỷ lệ nhấp (%)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMetricDto.Cpc">
            <summary>Chi phí trung bình mỗi lần nhấp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMetricDto.VideoViews">
            <summary>Số lượt xem video</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMetricDto.RawResponseJson">
            <summary>Payload gốc của dòng số liệu</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest">
            <summary>
            Yêu cầu đẩy một chiến dịch từ LADA lên nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest.ExternalAccountId">
            <summary>Id tài khoản quảng cáo bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest.Name">
            <summary>Tên chiến dịch</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest.Objective">
            <summary>Mục tiêu chuẩn hoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest.BudgetType">
            <summary>Loại ngân sách</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest.BudgetAmount">
            <summary>Giá trị ngân sách theo đơn vị tiền tệ của tài khoản</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest.StartDate">
            <summary>Ngày bắt đầu chạy</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest.EndDate">
            <summary>Ngày kết thúc</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest.DesiredStatus">
            <summary>
            Trạng thái mong muốn khi tạo. Mặc định Paused để tránh bug làm tiêu tiền ngoài ý muốn.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest.Groups">
            <summary>Danh sách nhóm quảng cáo kèm mẫu QC và targeting</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest.PlatformPayloadJson">
            <summary>Cấu hình đặc thù nền tảng do UI gửi lên (render từ Capabilities)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupPublishRequest">
            <summary>
            Một nhóm quảng cáo trong yêu cầu publish.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupPublishRequest.Name">
            <summary>Tên nhóm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupPublishRequest.CpcBid">
            <summary>Giá thầu CPC tối đa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupPublishRequest.Creatives">
            <summary>Danh sách mẫu quảng cáo trong nhóm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupPublishRequest.Targeting">
            <summary>Targeting của nhóm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupPublishRequest.PlatformPayloadJson">
            <summary>Cấu hình đặc thù nền tảng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativePublishRequest">
            <summary>
            Mẫu quảng cáo trong yêu cầu publish.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativePublishRequest.Headlines">
            <summary>Danh sách headline</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativePublishRequest.Descriptions">
            <summary>Danh sách description</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativePublishRequest.FinalUrl">
            <summary>URL đích</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativePublishRequest.Path1">
            <summary>Đường dẫn hiển thị 1</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativePublishRequest.Path2">
            <summary>Đường dẫn hiển thị 2</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativePublishRequest.ImageUrl">
            <summary>URL ảnh</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativePublishRequest.VideoUrl">
            <summary>URL video</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsTargetingPublishRequest">
            <summary>
            Targeting trong yêu cầu publish.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsTargetingPublishRequest.Keywords">
            <summary>Danh sách từ khoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsTargetingPublishRequest.LocationIds">
            <summary>Danh sách mã vị trí của nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsTargetingPublishRequest.LanguageIds">
            <summary>Danh sách mã ngôn ngữ của nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsTargetingPublishRequest.AgeFrom">
            <summary>Độ tuổi tối thiểu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsTargetingPublishRequest.AgeTo">
            <summary>Độ tuổi tối đa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsTargetingPublishRequest.Gender">
            <summary>Giới tính nhắm chọn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsTargetingPublishRequest.PlatformPayloadJson">
            <summary>Cấu hình targeting đặc thù nền tảng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleApplyRequest">
            <summary>
            Yêu cầu áp lịch quảng cáo lên nền tảng: một lô thao tác đã được
            <c>AdsScheduleDiff</c> tính sẵn, gửi trong <b>một</b> request atomic.
            <para>
            Cố ý gộp cả xoá/thêm/sửa vào một request thay vì ba lần gọi: đổi được một nửa lịch
            là trạng thái tệ nhất — người dùng không biết khung nào đã đổi, khung nào chưa,
            mà giá thầu thì đã thay đổi thật.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleApplyRequest.ExternalAccountId">
            <summary>Id tài khoản quảng cáo bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleApplyRequest.ExternalCampaignId">
            <summary>Id chiến dịch bên nền tảng — lịch là criterion cấp chiến dịch</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleApplyRequest.Operations">
            <summary>
            Các thao tác cần gửi, đã theo đúng thứ tự an toàn (xoá trước, rồi thêm, rồi sửa)
            do <c>AdsScheduleDiffResult.AllOperations</c> sắp.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupBidOperation">
            <summary>
            Một dòng đổi giá thầu của nhóm quảng cáo cần gửi lên nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupBidOperation.ExternalGroupId">
            <summary>Id nhóm bên nền tảng (id trần, không phải resource name)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupBidOperation.CpcBid">
            <summary>
            Giá thầu mới, đơn vị <b>tiền tệ</b> của tài khoản (VND: đồng) — adapter tự đổi ra micros.
            Không bao giờ truyền micros xuống đây: cả LADA lẫn giao diện đều nói bằng đơn vị tiền.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupBidOperation.GroupName">
            <summary>Tên nhóm — chỉ để dựng câu lỗi cho người đọc, không gửi lên nền tảng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupBidApplyRequest">
            <summary>
            Yêu cầu đổi giá thầu cho một lô nhóm quảng cáo <b>trong cùng một tài khoản</b>,
            gửi trong một request atomic.
            <para>
            Cùng lý do gộp như lịch chạy và từ khoá: đổi được một nửa lô là trạng thái tệ nhất —
            tiền đã đổi thật trên một phần nhóm mà LADA không biết phần nào.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupBidApplyRequest.ExternalAccountId">
            <summary>Id tài khoản quảng cáo bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupBidApplyRequest.Operations">
            <summary>Các nhóm cần đổi giá thầu</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordApplyRequest">
            <summary>
            Yêu cầu áp từ khoá lên nền tảng: một lô thao tác đã được <c>AdsKeywordDiff</c> tính sẵn,
            gửi trong <b>một</b> request atomic.
            <para>
            Cố ý gộp cả xoá/thêm/sửa vào một request thay vì ba lần gọi, cùng lý do như lịch chạy:
            đổi được một nửa là trạng thái tệ nhất. Riêng với từ khoá còn tệ hơn — xoá xong nhưng
            thêm lỗi thì chiến dịch mất từ khoá phủ định mà vẫn chạy, tiền chảy ra ngay.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordApplyRequest.ExternalAccountId">
            <summary>Id tài khoản quảng cáo bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordApplyRequest.ExternalCampaignId">
            <summary>Id chiến dịch bên nền tảng — luôn có, kể cả khi áp cho một nhóm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordApplyRequest.ExternalGroupId">
            <summary>
            Id nhóm bên nền tảng. <c>null</c> = lô này là <b>từ khoá phủ định cấp chiến dịch</b>
            (Google: <c>campaign_criterion</c>); có giá trị = từ khoá cấp nhóm
            (Google: <c>ad_group_criterion</c>).
            <para>
            Một lô không được trộn hai cấp: hai cấp là hai loại operation khác nhau của Google, và
            trộn vào sẽ làm mô tả trên hộp xác nhận nói sai phạm vi ảnh hưởng.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordApplyRequest.Operations">
            <summary>
            Các thao tác cần gửi, đã theo đúng thứ tự an toàn (xoá trước, rồi thêm, rồi sửa)
            do <c>AdsKeywordDiffResult.AllOperations</c> sắp.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignUpdateRequest">
            <summary>
            Yêu cầu cập nhật chiến dịch đã tồn tại trên nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignUpdateRequest.ExternalAccountId">
            <summary>Id tài khoản quảng cáo bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignUpdateRequest.ExternalCampaignId">
            <summary>Id chiến dịch bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignUpdateRequest.Name">
            <summary>Tên mới (null = không đổi)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignUpdateRequest.Status">
            <summary>Trạng thái mới (null = không đổi)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignUpdateRequest.BudgetAmount">
            <summary>Ngân sách mới (null = không đổi)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignUpdateRequest.StartDate">
            <summary>Ngày bắt đầu mới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignUpdateRequest.EndDate">
            <summary>Ngày kết thúc mới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignUpdateRequest.PlatformPayloadJson">
            <summary>Cấu hình đặc thù nền tảng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMutateResult">
            <summary>
            Kết quả một lần ghi dữ liệu ra nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMutateResult.Success">
            <summary>Thành công hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMutateResult.Message">
            <summary>Thông báo tiếng Việt (kể cả khi lỗi)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMutateResult.ExternalCampaignId">
            <summary>Id chiến dịch bên nền tảng sau khi tạo/sửa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMutateResult.ExternalBudgetId">
            <summary>Id ngân sách bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMutateResult.ExternalGroupIds">
            <summary>
            Id các đối tượng con đã tạo, dùng để lưu ExternalId về canonical entity.
            Key là tên/định danh do LADA gửi lên, value là id bên nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMutateResult.ExternalAdIds">
            <summary>Id các quảng cáo đã tạo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMutateResult.ExternalScheduleIds">
            <summary>
            Id criterion của các khung giờ vừa tạo. Key là <c>AdsScheduleSlot.WindowKey</c>
            (thứ + giờ bắt đầu + giờ kết thúc), value là criterion id bên nền tảng.
            <para>
            Cần khoá theo khung giờ chứ không theo index: nhờ vậy service gắn được ExternalId
            vào đúng dòng LADA. Gắn lệch một dòng là lần đẩy sau sẽ sửa/xoá sai khung giờ.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMutateResult.ExternalKeywordIds">
            <summary>
            Criterion id của các từ khoá vừa tạo. Key là <c>AdsKeywordOperation.IdentityKey</c>
            (cấp + phủ định + kiểu khớp + nội dung đã chuẩn hoá), value là criterion id bên nền tảng.
            <para>
            Khoá theo danh tính chứ không theo index, cùng lý do như <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMutateResult.ExternalScheduleIds"/>:
            gắn lệch một dòng là lần đẩy sau sẽ sửa/xoá <b>sai từ khoá</b> — với từ khoá phủ định thì
            đó là xoá mất lá chắn của một truy vấn khác.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMutateResult.PlatformErrorCode">
            <summary>Mã lỗi gốc của nền tảng — giữ nguyên để tra cứu tài liệu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMutateResult.RawResponseJson">
            <summary>Payload gốc trả về từ nền tảng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapterFactory">
            <summary>
            Tra cứu adapter theo nền tảng. Thêm nền tảng mới chỉ cần đăng ký thêm một
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter"/> vào DI, không phải sửa factory.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapterFactory.GetAdapter(Lada.Framework.Data.Enums.AdsPlatform)">
            <summary>
            Lấy adapter của nền tảng. Ném <see cref="T:System.NotSupportedException"/> kèm thông báo
            tiếng Việt nếu nền tảng chưa được triển khai.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapterFactory.TryGetAdapter(Lada.Framework.Data.Enums.AdsPlatform)">
            <summary>
            Lấy adapter của nền tảng, trả về null nếu chưa có — dùng khi chỉ cần dò xem có hỗ trợ hay không.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapterFactory.GetAllCapabilities">
            <summary>Năng lực của mọi nền tảng đã đăng ký, để UI dựng danh sách chọn nền tảng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformAdapterFactory">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformAdapterFactory.GetAdapter(Lada.Framework.Data.Enums.AdsPlatform)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformAdapterFactory.TryGetAdapter(Lada.Framework.Data.Enums.AdsPlatform)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformAdapterFactory.GetAllCapabilities">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities">
            <summary>
            Mô tả năng lực của một nền tảng quảng cáo.
            UI dùng object này để render form cấu hình kết nối và bật/tắt các chức năng,
            nhờ vậy thêm nền tảng mới không phải sửa frontend.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.Platform">
            <summary>Nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.DisplayName">
            <summary>Tên hiển thị của nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.ApiVersion">
            <summary>Phiên bản API đang dùng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.IsImplemented">
            <summary>Nền tảng đã được triển khai hay chỉ là placeholder cho giai đoạn sau</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanFetchAccounts">
            <summary>Lấy được danh sách tài khoản quảng cáo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanFetchCampaigns">
            <summary>Lấy được danh sách chiến dịch</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanFetchGroups">
            <summary>Lấy được danh sách nhóm quảng cáo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanFetchMetrics">
            <summary>Lấy được số liệu theo ngày</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanFetchSchedules">
            <summary>Đọc được lịch chạy quảng cáo (ad schedule) của chiến dịch</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanFetchAds">
            <summary>
            Đọc được danh sách quảng cáo cụ thể trong từng nhóm (Google: <c>ad_group_ad</c>).
            Tách khỏi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanFetchGroups"/> vì nền tảng có thể cho đọc nhóm mà không cho
            đọc chi tiết từng quảng cáo — UI ẩn tab "Quảng cáo" theo cờ này.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanFetchKeywords">
            <summary>
            Đọc được danh sách từ khoá về từ nền tảng (an toàn, chỉ đọc).
            Tách khỏi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.SupportsKeywordTargeting"/>: nền tảng có thể nhắm mục tiêu bằng
            từ khoá khi tạo chiến dịch nhưng chưa có đường đọc lại danh sách đó.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.SupportedMetricLevels">
            <summary>Các cấp lấy số liệu mà nền tảng hỗ trợ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanPublishCampaign">
            <summary>Tạo được chiến dịch mới trên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanUpdateCampaign">
            <summary>Cập nhật được chiến dịch đã tồn tại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanChangeStatus">
            <summary>Bật/tạm dừng được chiến dịch</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.SupportedObjectives">
            <summary>Các mục tiêu chiến dịch nền tảng hỗ trợ tạo từ LADA</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.SupportedBudgetTypes">
            <summary>Các loại ngân sách nền tảng hỗ trợ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanChangeBudget">
            <summary>Đổi được ngân sách của chiến dịch đã đẩy lên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanEditSchedules">
            <summary>
            Sửa được lịch chạy quảng cáo (thêm/xoá khung giờ, đổi % giá thầu theo giờ).
            Tách riêng khỏi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanFetchSchedules"/> vì đọc lịch an toàn còn ghi lịch
            đổi giá thầu là tiêu tiền thật — frontend đọc cờ này để ẩn/hiện chức năng sửa
            thay vì hard-code nền tảng vào UI.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanEditKeywords">
            <summary>
            Sửa được từ khoá trên nền tảng (thêm/xoá/đổi giá thầu từ khoá).
            Tách khỏi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanFetchKeywords"/> vì đọc từ khoá thì an toàn còn ghi từ khoá là
            <b>đổi cấu hình đang tiêu tiền</b>: thêm từ khoá khớp rộng có thể làm chi phí tăng vọt.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.SupportsNegativeKeywords">
            <summary>
            Nền tảng có khái niệm <b>từ khoá phủ định</b> (loại trừ truy vấn) hay không.
            UI ẩn hẳn tab khi cờ này <c>false</c> — không hiện tab rỗng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.SupportsCampaignLevelNegativeKeywords">
            <summary>
            Nền tảng có từ khoá phủ định ở <b>cấp chiến dịch</b> hay không (áp cho mọi nhóm bên trong).
            <para>
            Phải tách khỏi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.SupportsNegativeKeywords"/> vì hai cấp là hai tab khác nhau
            trong UI: nền tảng chỉ có phủ định cấp nhóm thì tab cấp chiến dịch không được xuất hiện.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.ScheduleBidModifierStrategies">
            <summary>
            Các chiến lược đặt giá <b>có</b> áp dụng % điều chỉnh giá thầu theo khung giờ.
            <para>
            Đặt ở đây thay vì hard-code trong service: nền tảng nào biết luật của nền tảng đó.
            Tên viết theo enum của nền tảng (SNAKE_CASE); so sánh đi qua
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.ClassifyScheduleBidModifier(System.String)"/> nên không phụ thuộc cách viết hoa/gạch dưới.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.ScheduleBidModifierIgnoredStrategies">
            <summary>
            Các chiến lược đặt giá <b>bỏ qua</b> % điều chỉnh giá thầu theo khung giờ
            (nhưng vẫn tôn trọng khung giờ chạy/không chạy).
            <para>
            Cần liệt kê riêng chứ không suy ra bằng "không nằm trong danh sách áp dụng":
            còn một nhóm thứ ba là <b>chưa xác định được</b>, và nói sai về tiền thì tệ hơn nói "chưa rõ".
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.ClassifyScheduleBidModifier(System.String)">
            <summary>
            Chiến lược đặt giá của chiến dịch có áp dụng % điều chỉnh theo khung giờ hay không.
            Trả <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleBidModifierSupport.Unknown"/> khi chưa tra được chắc chắn —
            UI phải nói đúng là "chưa xác định", tuyệt đối không đoán.
            </summary>
            <param name="biddingStrategy">
            Chiến lược lấy từ <c>AdsCampaign.BiddingStrategy</c>. Adapter Google lưu giá trị
            <c>BiddingStrategyType.ToString()</c> (PascalCase, ví dụ "ManualCpc") nên hàm này
            bỏ gạch dưới và viết hoa hết trước khi so sánh.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.NormalizeStrategy(System.String)">
            <summary>Bỏ gạch dưới + viết hoa để so "MANUAL_CPC" với "ManualCpc" ra cùng một khoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanEditGroupBid">
            <summary>Nền tảng cho phép sửa giá thầu của <b>nhóm quảng cáo</b> từ LADA hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanEditKeywordBid">
            <summary>Nền tảng cho phép sửa giá thầu riêng của <b>từ khoá</b> từ LADA hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.GroupBidStrategies">
            <summary>
            Các chiến lược đặt giá <b>có</b> dùng giá thầu của nhóm/từ khoá khi đấu giá.
            <para>
            Danh sách <b>riêng</b>, không dùng chung với <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.ScheduleBidModifierStrategies"/>:
            hai thứ khác nhau. Ví dụ <c>TARGET_SPEND</c> vẫn áp dụng % điều chỉnh theo khung giờ
            nhưng <b>bỏ qua</b> giá thầu nhóm (giới hạn giá thầu của nó nằm ở cấp chiến dịch).
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.GroupBidIgnoredStrategies">
            <summary>
            Các chiến lược đặt giá <b>bỏ qua</b> giá thầu nhóm/từ khoá khi đấu giá.
            <para>
            Ghi vẫn ghi được và Google không báo lỗi — y hệt cái bẫy của % điều chỉnh theo khung giờ —
            nên không thể dựa vào API để biết nó có tác dụng. Phải cảnh báo trên UI dựa vào danh sách này.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.ClassifyGroupBid(System.String)">
            <summary>
            Chiến lược đặt giá của chiến dịch có dùng giá thầu nhóm/từ khoá hay không.
            Trả <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupBidSupport.Unknown"/> khi chưa tra được chắc chắn —
            UI phải nói đúng là "chưa xác định" chứ không được đoán.
            </summary>
            <param name="biddingStrategy">
            Chiến lược lấy từ <c>AdsCampaign.BiddingStrategy</c>. Adapter Google lưu
            <c>BiddingStrategyType.ToString()</c> (PascalCase, ví dụ "ManualCpc") nên hàm này
            bỏ gạch dưới và viết hoa hết trước khi so sánh.
            </param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.SupportsValidateOnly">
            <summary>
            Nền tảng cho phép kiểm tra trước khi ghi thật (dry-run).
            Google Ads có <c>validate_only</c>, các nền tảng khác chưa chắc có.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.HasAdGroupLevel">
            <summary>
            Chiến dịch của nền tảng có tầng nhóm quảng cáo (AdGroup) hay không.
            Performance Max dùng AssetGroup nên cờ này phải đọc từ Capabilities, đừng giả định.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.SupportsKeywordTargeting">
            <summary>Nền tảng nhắm mục tiêu bằng từ khoá (Search) hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.SupportsLocationTargeting">
            <summary>Nền tảng nhắm mục tiêu theo vị trí địa lý hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.SupportsLanguageTargeting">
            <summary>Nền tảng nhắm mục tiêu theo ngôn ngữ hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CreativeLimits">
            <summary>
            Giới hạn mẫu quảng cáo của nền tảng — service validate theo object này,
            tuyệt đối không hard-code số 30/90 vào tầng nghiệp vụ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.RequiresOAuth">
            <summary>Nền tảng dùng OAuth (cần bấm "Cấp quyền" để lấy refresh token)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.RequiresDeveloperToken">
            <summary>Nền tảng yêu cầu developer token riêng ngoài OAuth</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CredentialFields">
            <summary>Danh sách field credential UI cần render</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.Notes">
            <summary>Ghi chú cho người cấu hình (tiếng Việt)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleBidModifierSupport">
            <summary>
            Chiến lược đặt giá của chiến dịch có áp dụng % điều chỉnh giá thầu theo khung giờ hay không.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleBidModifierSupport.Unknown">
            <summary>
            Chưa tra được chắc chắn. UI phải nói đúng là "chưa xác định" chứ không được đoán —
            đoán sai ở phần giá thầu là tiêu tiền thật của người dùng.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleBidModifierSupport.Applied">
            <summary>Nền tảng áp dụng % điều chỉnh theo khung giờ</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleBidModifierSupport.Ignored">
            <summary>
            Nền tảng bỏ qua % điều chỉnh theo khung giờ, nhưng vẫn tôn trọng
            khung giờ chạy/không chạy. Đặt % vẫn ghi được, chỉ là không có tác dụng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupBidSupport">
            <summary>
            Chiến lược đặt giá của chiến dịch có dùng giá thầu của nhóm quảng cáo / từ khoá hay không.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupBidSupport.Unknown">
            <summary>
            Chưa tra được chắc chắn. UI phải nói đúng là "chưa xác định" chứ không được đoán —
            đoán sai ở phần giá thầu là tiêu tiền thật của người dùng.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupBidSupport.Applied">
            <summary>Nền tảng dùng giá thầu của nhóm/từ khoá khi đấu giá</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupBidSupport.Ignored">
            <summary>
            Nền tảng bỏ qua giá thầu của nhóm/từ khoá (chiến lược tự động tự đặt giá).
            Ghi vẫn ghi được và đọc lại vẫn thấy giá trị, chỉ là không ảnh hưởng phân phối.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativeLimits">
            <summary>
            Giới hạn mẫu quảng cáo của một nền tảng.
            Cả backend (validate) và frontend (đếm ký tự realtime) đều đọc từ đây,
            nhờ vậy khi Google đổi giới hạn chỉ phải sửa một chỗ trong adapter.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativeLimits.MinHeadlines">
            <summary>Số tiêu đề tối thiểu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativeLimits.MaxHeadlines">
            <summary>Số tiêu đề tối đa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativeLimits.MaxHeadlineLength">
            <summary>Độ dài tối đa của một tiêu đề (ký tự)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativeLimits.MinDescriptions">
            <summary>Số mô tả tối thiểu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativeLimits.MaxDescriptions">
            <summary>Số mô tả tối đa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativeLimits.MaxDescriptionLength">
            <summary>Độ dài tối đa của một mô tả (ký tự)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativeLimits.MaxPathLength">
            <summary>Độ dài tối đa của mỗi đoạn đường dẫn hiển thị (Path1/Path2)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativeLimits.SupportsDisplayPath">
            <summary>Nền tảng có dùng Path1/Path2 (đường dẫn hiển thị) hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativeLimits.RequiresFinalUrl">
            <summary>Bắt buộc phải có URL đích</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativeLimits.RequiresImage">
            <summary>Bắt buộc phải có ảnh</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativeLimits.MaxKeywordsPerGroup">
            <summary>Số từ khoá tối đa cho một nhóm quảng cáo (0 = không giới hạn / không áp dụng)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCredentialField">
            <summary>
            Một field credential trong form cấu hình kết nối.
            Frontend render động theo danh sách này — không hard-code field của từng nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCredentialField.Key">
            <summary>
            Khoá field. Trùng tên property của <c>AdsConnection</c> thì lưu thẳng vào cột,
            còn lại lưu vào <c>CredentialPayloadJson</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCredentialField.Label">
            <summary>Nhãn hiển thị (tiếng Việt)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCredentialField.Type">
            <summary>Loại input: text | password | url | select</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCredentialField.Required">
            <summary>Bắt buộc nhập</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCredentialField.Placeholder">
            <summary>Gợi ý trong ô nhập</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCredentialField.HelpText">
            <summary>Hướng dẫn lấy giá trị này ở đâu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCredentialField.IsSecret">
            <summary>
            Là thông tin mật — API trả về dạng đã che (abcd***wxyz),
            khi lưu nếu giá trị gửi lên còn chứa *** thì giữ nguyên giá trị cũ trong DB.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCredentialField.DefaultValue">
            <summary>Giá trị mặc định</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCredentialField.Options">
            <summary>Danh sách lựa chọn khi Type = select</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCredentialFieldOption">
            <summary>
            Một lựa chọn của field dạng select.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCredentialFieldOption.Value">
            <summary>Giá trị lưu xuống</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCredentialFieldOption.Label">
            <summary>Nhãn hiển thị</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter">
            <summary>
            Phần adapter Google Ads phụ trách <b>giá thầu của nhóm quảng cáo</b> (<c>ad_group.cpc_bid_micros</c>).
            <para>
            Tách khỏi file chính vì đây là đường ghi <b>chạm tiền trực tiếp</b>: một con số sai ở đây là
            tiền thật tiêu sai ngay phiên đấu giá kế tiếp. Giá thầu của từ khoá không nằm ở đây — nó đi
            lại đúng đường <c>ApplyKeywordsAsync</c> (<c>ad_group_criterion</c>) trong
            <c>GoogleAdsAdapter.Keywords.cs</c>, cố ý một đường ghi cho một loại đối tượng.
            </para>
            <para>
            Các helper dùng chung (<c>ExecuteWithRetryAsync</c>, <c>Failure</c>, <c>FailureFrom</c>)
            nằm ở <c>GoogleAdsAdapter.cs</c> — cùng một partial class nên gọi trực tiếp được.
            </para>
            </summary>
            <summary>
            Adapter Google Ads (API v25).
            Xác thực OAuth, kiểm tra kết nối, đọc tài khoản / chiến dịch / nhóm / số liệu.
            Phần ghi (tạo &amp; sửa chiến dịch, đổi trạng thái, đổi ngân sách) nằm ở
            <c>GoogleAdsAdapter.Write.cs</c> — tách riêng vì đó là phần tiêu tiền thật.
            </summary>
            <summary>
            Phần adapter Google Ads phụ trách <b>quảng cáo cụ thể trong nhóm</b> và <b>từ khoá</b>
            (cả từ khoá thường và từ khoá phủ định, cả cấp nhóm và cấp chiến dịch).
            <para>
            Tách khỏi file chính vì đây là hai cây đối tượng riêng của Google
            (<c>ad_group_ad</c>, <c>ad_group_criterion</c>, <c>campaign_criterion</c>) và phần ghi từ khoá
            là <b>thao tác đổi cấu hình đang tiêu tiền</b>: xoá một từ khoá phủ định là mở cửa cho truy vấn
            rác chạy lại ngay lập tức. Gom vào một chỗ để dễ soát lại.
            </para>
            <para>
            Các helper dùng chung (<c>SearchAsync</c>, <c>ExecuteWithRetryAsync</c>, <c>Failure</c>,
            <c>FailureFrom</c>, <c>ExtractCriterionId</c>, <c>CriterionResource</c>) nằm ở
            <c>GoogleAdsAdapter.cs</c> — cùng một partial class nên gọi trực tiếp được.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.UpdateGroupBidsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupBidApplyRequest,System.Boolean,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.AdwordsScope">
            <summary>Scope OAuth duy nhất mà Google Ads API dùng</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.AuthorizationEndpoint">
            <summary>Endpoint hiện consent screen của Google</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.TokenEndpoint">
            <summary>Endpoint đổi code / refresh token</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.MaxRetryAttempts">
            <summary>Số lần thử lại tối đa khi gặp lỗi tạm thời (quota, mạng)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.Platform">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.GetCapabilities">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.BuildAuthorizationUrl(Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAuthRequest)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.ExchangeCodeAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.RefreshTokenAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.PostTokenRequestAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.Collections.Generic.Dictionary{System.String,System.String},System.Threading.CancellationToken)">
            <summary>
            Gọi endpoint token của Google và dịch lỗi sang tiếng Việt.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.TranslateOAuthError(System.String,System.String)">
            <summary>
            Dịch mã lỗi OAuth của Google sang thông báo hành động được cho người cấu hình.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.TestConnectionAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.FetchAccountsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.AppendClientAccountsAsync(Google.Ads.GoogleAds.Lib.GoogleAdsClient,System.String,Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAccountFetchResult,System.Collections.Generic.HashSet{System.String},System.Threading.CancellationToken)">
            <summary>
            Liệt kê các tài khoản nằm dưới một tài khoản quản lý (MCC) và thêm vào kết quả.
            Truy vấn chạy với chính MCC làm operating customer nên chỉ cần một lần gọi cho cả cây,
            kể cả tài khoản cấp cháu. Lỗi ở đây không làm sập lần đồng bộ — MCC vẫn được giữ lại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.FetchCampaignsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.FetchAdGroupsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.FetchSchedulesAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.FetchMetricsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.DateOnly,System.DateOnly,Lada.Framework.Data.Enums.AdsMetricLevel,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.PublishCampaignAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.ValidateCampaignAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.MutateCampaignTreeAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest,System.Boolean,System.Threading.CancellationToken)">
            <summary>
            Tạo cả cây ngân sách → chiến dịch → nhóm → quảng cáo → từ khoá trong **một** request atomic.
            Tạo rời từng bước mà lỗi giữa đường sẽ để lại rác trên tài khoản Google
            (ngân sách mồ côi, chiến dịch không có quảng cáo) mà LADA không biết để dọn.
            <paramref name="validateOnly"/> = true thì Google chỉ kiểm tra, không tạo gì thật.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.BuildCampaignTreeOperations(System.String,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest)">
            <summary>
            Dựng danh sách operation kèm bảng tra thứ tự để đọc lại id sau khi tạo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.ReadMutateResponse(Google.Ads.GoogleAds.V25.Services.MutateGoogleAdsResponse,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.CampaignTreePlan)">
            <summary>
            Ghép id nền tảng trả về vào từng cấp bằng cách đi song song danh sách operation đã gửi
            và danh sách kết quả — Google trả kết quả đúng thứ tự operation.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.UpdateCampaignAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignUpdateRequest,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.ChangeStatusAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,Lada.Framework.Data.Enums.AdsEntityLevel,System.String,Lada.Framework.Data.Enums.AdsEntityStatus,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.ChangeBudgetAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.String,System.Decimal,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.ExecuteSingleOperationAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,Google.Ads.GoogleAds.V25.Services.MutateOperation,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Gửi một operation đơn lẻ qua GoogleAdsService.Mutate và dịch lỗi sang tiếng Việt.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.ApplySchedulesAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleApplyRequest,System.Boolean,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.BuildScheduleCriterion(System.String,Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperation)">
            <summary>
            Dựng criterion lịch quảng cáo để tạo mới.
            Thứ/giờ của <c>AdScheduleInfo</c> là bất biến bên Google nên mọi thay đổi thứ/giờ
            đều đi qua đây (tạo mới) chứ không phải update.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.CriterionResource(System.String,System.String,System.String)">
            <summary>
            Resource name của một campaign criterion.
            Định dạng có dấu ngã: <c>customers/{cid}/campaignCriteria/{campaignId}~{criterionId}</c>.
            Nguồn: https://developers.google.com/google-ads/api/rest/reference/rest/v21/customers.campaignCriteria
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.ExtractCriterionId(System.String)">
            <summary>
            Lấy phần id con (sau dấu ngã) từ resource name ghép của Google.
            <para>
            Chỉ là lớp gọi lại <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ExtractChildIdFromResourceName(System.String)"/> — logic
            nằm ở mapper để unit test chạm được (adapter cần một <c>GoogleAdsClient</c> thật).
            Giữ tên cũ vì trong adapter phần lớn đối tượng con là criterion.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.TempResource(System.String,System.String,System.Int32)">
            <summary>
            Resource name tạm với id âm — dùng để nối các cấp trong cùng một request atomic.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.ParseKeyword(System.String)">
            <summary>
            Đọc match type từ cú pháp quen thuộc của Google Ads Editor:
            <c>[từ khoá]</c> = khớp chính xác, <c>"từ khoá"</c> = khớp cụm, còn lại = khớp rộng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.BuildAdKey(System.String,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativePublishRequest)">
            <summary>
            Khoá nhận lại id quảng cáo sau khi tạo: tên nhóm + headline đầu tiên.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.CampaignTreePlan">
            <summary>
            Danh sách operation kèm bảng tra thứ tự để ghép id nền tảng trả về vào đúng cấp.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.CampaignTreeNode.Key">
            <summary>Khoá do LADA gửi lên (tên nhóm / khoá quảng cáo) để nhận lại id</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.SearchAsync(Google.Ads.GoogleAds.Lib.GoogleAdsClient,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Chạy một câu GAQL và trả về toàn bộ dòng (tự phân trang).
            Dùng cho dữ liệu cấu hình (tài khoản, chiến dịch, nhóm) — số dòng nhỏ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.SearchStreamAsync(Google.Ads.GoogleAds.Lib.GoogleAdsClient,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Chạy một câu GAQL bằng SearchStream — dùng cho số liệu theo ngày (nhiều dòng).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.ExecuteWithRetryAsync``1(System.Func{System.Threading.Tasks.Task{``0}},System.String,System.Threading.CancellationToken)">
            <summary>
            Thử lại với thời gian chờ tăng dần khi Google trả lỗi tạm thời (quota, rate limit, mạng).
            Lỗi nghiệp vụ (sai quyền, sai câu truy vấn) không thử lại — thử lại chỉ tốn quota mà không đổi kết quả.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.IsTransient(System.Exception)">
            <summary>
            Lỗi có đáng thử lại không: hết quota, quá tải, timeout, hoặc lỗi nội bộ của Google.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.DescribeGoogleError(System.Exception)">
            <summary>
            Dịch lỗi Google Ads sang thông báo tiếng Việt, kèm mã lỗi gốc để tra tài liệu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.NormalizeErrorCode(System.String)">
            <summary>
            Mã lỗi của Google là một message dạng JSON — rút gọn lại thành chuỗi ngắn để lưu log.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.TranslateApiError(System.String,System.String)">
            <summary>
            Chuyển các mã lỗi Google hay gặp thành hướng dẫn xử lý cụ thể.
            Mã không nằm trong danh sách vẫn giữ nguyên thông báo gốc của Google để không mất thông tin.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.GuessMissingFieldsFromError(System.String)">
            <summary>
            Suy ra field credential cần sửa từ mã lỗi, để UI highlight đúng ô nhập.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.FetchAdsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.BuildAdDisplayName(Google.Ads.GoogleAds.V25.Resources.Ad)">
            <summary>
            Dựng tên hiển thị của một quảng cáo.
            <para>
            <c>ad.name</c> hầu như luôn rỗng với quảng cáo tìm kiếm (Google chỉ cho đặt tên ở vài loại),
            nên lấy tiêu đề đầu tiên của mẫu quảng cáo thay thế. Không bao giờ trả chuỗi rỗng: danh sách
            toàn dòng không tên thì người dùng không phân biệt được đang bật/tắt quảng cáo nào — đúng cái
            nhầm lẫn dẫn tới tắt sai thứ đang chạy tốt.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.FetchKeywordsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.MapAdGroupKeywords(System.Collections.Generic.List{Google.Ads.GoogleAds.V25.Services.GoogleAdsRow},System.String)">
            <summary>
            Map các dòng <c>ad_group_criterion</c> thành DTO từ khoá cấp nhóm.
            Gộp cả từ khoá thường và phủ định — Google dùng chung một resource, chỉ khác cờ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.MapCampaignKeywords(System.Collections.Generic.List{Google.Ads.GoogleAds.V25.Services.GoogleAdsRow},System.String)">
            <summary>
            Map các dòng <c>campaign_criterion</c> thành DTO từ khoá <b>phủ định</b> cấp chiến dịch.
            <para>
            GAQL cố ý không lọc <c>negative = TRUE</c> nên phải lọc tại đây. Từ khoá cấp chiến dịch
            <b>không phủ định</b> là chuyện Google không dùng cho tìm kiếm — bỏ qua, vì hiện nó lên
            danh sách "từ khoá phủ định cấp chiến dịch" là nói sai với người dùng.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.ApplyKeywordsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordApplyRequest,System.Boolean,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.BuildAdGroupKeywordOperation(System.String,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordApplyRequest,Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperation,System.String@)">
            <summary>
            Dựng operation cho từ khoá <b>cấp nhóm</b> (<c>ad_group_criterion</c>).
            Trả <c>null</c> kèm <paramref name="error"/> tiếng Việt khi dữ liệu không đủ để gửi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.BuildCampaignKeywordOperation(System.String,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordApplyRequest,Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperation,System.String@)">
            <summary>
            Dựng operation cho từ khoá phủ định <b>cấp chiến dịch</b> (<c>campaign_criterion</c>).
            <para>
            Không có nhánh Update: từ khoá phủ định cấp chiến dịch không có giá thầu, mà text và kiểu
            khớp là bất biến bên Google. Mọi thay đổi đều là xoá + tạo lại.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsAdapter.AdGroupCriterionResource(System.String,System.String,System.String)">
            <summary>
            Resource name của một ad group criterion.
            Định dạng có dấu ngã: <c>customers/{cid}/adGroupCriteria/{adGroupId}~{criterionId}</c>.
            <para>
            Đây là <b>nơi duy nhất</b> ghép dạng này. Canonical entity luôn lưu criterion id trần —
            lưu dạng ghép từng gây hai lỗi ở <c>AdsItem</c>: ghép lần hai khi đổi trạng thái, và số
            liệu theo cấp không bao giờ khớp được.
            </para>
            Nguồn: https://developers.google.com/google-ads/api/rest/reference/rest/v25/customers.adGroupCriteria
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.IGoogleAdsClientFactory">
            <summary>
            Tạo <see cref="T:Google.Ads.GoogleAds.Lib.GoogleAdsClient"/> từ credentials lưu trong <see cref="T:Lada.Framework.Data.Domains.Ads.AdsConnection"/>.
            Credentials không nằm trong appsettings — người dùng nhập ở trang cấu hình kết nối.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.IGoogleAdsClientFactory.CreateClient(Lada.Framework.Data.Domains.Ads.AdsConnection)">
            <summary>
            Tạo client cho một kết nối. Ném <see cref="T:System.InvalidOperationException"/> (tiếng Việt)
            nếu thiếu credential bắt buộc — gọi <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.IGoogleAdsClientFactory.ValidateCredentials(Lada.Framework.Data.Domains.Ads.AdsConnection)"/> trước để có danh sách field thiếu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.IGoogleAdsClientFactory.ValidateCredentials(Lada.Framework.Data.Domains.Ads.AdsConnection)">
            <summary>
            Kiểm tra đủ credential để gọi API chưa. Trả về danh sách key field còn thiếu (rỗng = đủ).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsClientFactory">
            <inheritdoc />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsClientFactory.DefaultApiVersion">
            <summary>Phiên bản API mặc định khi kết nối không cấu hình</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsClientFactory.ValidateCredentials(Lada.Framework.Data.Domains.Ads.AdsConnection)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsClientFactory.CreateClient(Lada.Framework.Data.Domains.Ads.AdsConnection)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsClientFactory.NormalizeCustomerId(System.String)">
            <summary>
            Bỏ dấu gạch ngang và khoảng trắng khỏi customer id (Google hiển thị dạng 123-456-7890).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql">
            <summary>
            Toàn bộ câu truy vấn GAQL của module quảng cáo nằm ở một chỗ.
            Lý do: khi Google đổi tên field hoặc sunset version, chỉ phải sửa file này
            thay vì đi tìm chuỗi query rải rác trong adapter.
            Quy ước: field tiền tệ của Google là micros — adapter luôn chia qua
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.FromMicros(System.Int64)"/> trước khi trả ra ngoài.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.Customer">
            <summary>
            Thông tin một tài khoản quảng cáo (chạy với chính customer id đó làm operating customer).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.CustomerClients">
            <summary>
            Các tài khoản nằm dưới một tài khoản quản lý (MCC), kể cả cấp cháu (level > 1).
            Cần thiết vì <c>ListAccessibleCustomers</c> chỉ trả về tài khoản mà email đã cấp quyền
            truy cập trực tiếp — thường chỉ là MCC, không có tài khoản con chạy quảng cáo.
            Bỏ tài khoản đã ẩn để danh sách trong LADA không bị rác.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.Campaigns">
            <summary>
            Danh sách chiến dịch kèm ngân sách, chiến lược giá và khoảng thời gian chạy.
            Bỏ chiến dịch đã xoá để danh sách trong LADA không bị rác.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdGroups">
            <summary>
            Danh sách nhóm quảng cáo. Thêm điều kiện chiến dịch bằng
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdGroupsByCampaignFilter(System.String,System.String)"/> khi cần giới hạn.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.CampaignAdSchedules">
            <summary>
            Lịch chạy quảng cáo của chiến dịch (ad schedule).
            <para>
            Ad schedule là <c>campaign_criterion</c> kiểu AD_SCHEDULE — thuộc cấp chiến dịch,
            không phải cấp nhóm. Lọc <c>type = 'AD_SCHEDULE'</c> để không kéo cả criterion
            vị trí / ngôn ngữ (cùng nằm trong bảng này).
            </para>
            <para>
            <c>campaign_criterion.bid_modifier</c> có thể **không được set** — khác hẳn với set = 0.0
            (0.0 nghĩa là -100%). Adapter phải kiểm tra cờ <c>HasBidModifier</c> chứ không so giá trị.
            </para>
            Không lấy criterion đã REMOVED để danh sách trong LADA không bị rác.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.CampaignMetrics">
            <summary>
            Số liệu theo ngày ở cấp chiến dịch.
            <c>segments.date</c> trong SELECT là thứ tách số liệu thành từng ngày —
            thiếu nó Google trả về một dòng tổng cho cả khoảng thời gian.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdGroupMetrics">
            <summary>Số liệu theo ngày ở cấp nhóm quảng cáo.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdMetrics">
            <summary>Số liệu theo ngày ở cấp từng quảng cáo.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdGroupAds">
            <summary>
            Danh sách quảng cáo cụ thể trong các nhóm (cấu trúc, không có số liệu).
            <para>
            Khác <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdMetrics"/>: câu đó cũng <c>FROM ad_group_ad</c> nhưng chỉ lấy
            <c>ad.id</c> + metrics theo ngày. Câu này lấy tên / loại / trạng thái xét duyệt để
            dựng được danh sách quảng cáo trong nhóm.
            </para>
            <para>
            <b>Bẫy:</b> <c>ad_group_ad.ad.name</c> hầu như luôn rỗng với quảng cáo tìm kiếm —
            Google chỉ cho đặt <c>name</c> ở một số loại quảng cáo. Vì vậy lấy kèm
            <c>responsive_search_ad.headlines</c> để adapter dựng tên hiển thị từ tiêu đề đầu tiên,
            tránh danh sách toàn dòng trống tên.
            </para>
            Bỏ quảng cáo đã REMOVED để danh sách trong LADA không bị rác.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdGroupKeywords">
            <summary>
            Từ khoá cấp nhóm quảng cáo — <b>cả từ khoá thường và từ khoá phủ định</b>.
            <para>
            Google dùng chung một resource <c>ad_group_criterion</c> cho hai loại, phân biệt bằng
            cờ <c>negative</c>. Câu này cố ý <b>không</b> lọc theo <c>negative</c> trong WHERE:
            một lần gọi lấy đủ cả hai loại (tiết kiệm quota), adapter tự chia theo cờ.
            </para>
            <para>
            <b>Bẫy proto3:</b> <c>ad_group_criterion.negative</c> và <c>cpc_bid_micros</c> có thể
            <b>chưa được set</b>, khác hẳn với set = <c>false</c> / <c>0</c>. Adapter phải kiểm cờ
            <c>HasNegative</c> / <c>HasCpcBidMicros</c> chứ không so giá trị — cùng cái bẫy
            <c>HasBidModifier</c> đã ghi ở <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.CampaignAdSchedules"/>.
            </para>
            <para>
            <c>quality_info</c> và <c>approval_status</c> chỉ có với từ khoá thường; từ khoá phủ
            định không được Google chấm điểm nên hai field đó sẽ rỗng — đúng như vậy, không phải lỗi.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.CampaignNegativeKeywords">
            <summary>
            Từ khoá phủ định cấp chiến dịch (áp cho mọi nhóm bên trong chiến dịch).
            <para>
            Cùng bảng <c>campaign_criterion</c> với lịch chạy quảng cáo nhưng lọc
            <c>type = 'KEYWORD'</c> thay vì <c>'AD_SCHEDULE'</c> — đây là câu <b>mới</b>,
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.CampaignAdSchedules"/> giữ nguyên không sửa.
            </para>
            <para>
            Cố ý <b>không</b> lọc <c>negative = TRUE</c> trong WHERE mà để adapter kiểm cờ
            <c>HasNegative</c>/<c>Negative</c>: query trả về tập rộng hơn rồi lọc ở tầng adapter
            thì không phụ thuộc vào việc Google có cho lọc field đó hay không, và không tốn thêm
            lần gọi nào (adapter vốn đã đi qua từng dòng).
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.KeywordMetrics">
            <summary>
            Số liệu theo ngày ở cấp từ khoá.
            <para>
            Phải là <c>FROM keyword_view</c>, <b>không</b> phải <c>ad_group_criterion</c>:
            resource <c>ad_group_criterion</c> chỉ mang cấu trúc và không có metrics nào.
            </para>
            Chỉ từ khoá thường mới có số liệu — từ khoá phủ định không chạy nên không xuất hiện
            trong <c>keyword_view</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdGroupsByCampaignFilter(System.String,System.String)">
            <summary>
            Thêm điều kiện giới hạn theo một chiến dịch vào câu truy vấn nhóm quảng cáo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdSchedulesByCampaignFilter(System.String,System.String)">
            <summary>
            Thêm điều kiện giới hạn theo một chiến dịch vào câu truy vấn lịch quảng cáo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdGroupAdsByCampaignFilter(System.String,System.String)">
            <summary>Giới hạn câu <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdGroupAds"/> theo một chiến dịch.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdGroupAdsByGroupFilter(System.String,System.String)">
            <summary>Giới hạn câu <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdGroupAds"/> theo một nhóm quảng cáo.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdGroupKeywordsByCampaignFilter(System.String,System.String)">
            <summary>Giới hạn câu <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdGroupKeywords"/> theo một chiến dịch.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdGroupKeywordsByGroupFilter(System.String,System.String)">
            <summary>Giới hạn câu <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.AdGroupKeywords"/> theo một nhóm quảng cáo.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.CampaignKeywordsByCampaignFilter(System.String,System.String)">
            <summary>Giới hạn câu <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.CampaignNegativeKeywords"/> theo một chiến dịch.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsGaql.WithDateRange(System.String,System.DateOnly,System.DateOnly)">
            <summary>
            Điền khoảng ngày vào câu truy vấn số liệu (Google nhận định dạng yyyy-MM-dd).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper">
            <summary>
            Chuyển đổi giữa kiểu dữ liệu của Google Ads và canonical model của LADA.
            Toàn bộ phép đổi micros nằm ở đây — tuyệt đối không nhân/chia 1.000.000 rải rác trong adapter,
            vì sai chiều một lần là chi phí lệch một triệu lần.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.MicrosPerUnit">
            <summary>Hệ số micros của Google (1 đơn vị tiền tệ = 1.000.000 micros)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToMicros(System.Decimal)">
            <summary>
            Đổi số tiền theo đơn vị tiền tệ của tài khoản sang micros để gửi lên Google.
            Làm tròn về số nguyên gần nhất (Google chỉ nhận số nguyên).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.FromMicros(System.Int64)">
            <summary>
            Đổi micros nhận từ Google về đơn vị tiền tệ của tài khoản.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.FromMicros(System.Nullable{System.Int64})">
            <summary>
            Đổi micros nhận từ Google về đơn vị tiền tệ, coi null là 0.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.FromMicros(System.Double)">
            <summary>
            Đổi micros dạng số thực về đơn vị tiền tệ (một vài metric của Google khai báo double,
            ví dụ <c>metrics.average_cpc</c>). Vẫn đi qua đúng một chỗ chia micros.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.NormalizeCustomerId(System.String)">
            <summary>
            Bỏ dấu gạch ngang khỏi customer id (Google hiển thị dạng 123-456-7890, API nhận 1234567890).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ExtractIdFromResourceName(System.String)">
            <summary>
            Lấy id số cuối cùng trong một resource name của Google
            (ví dụ "customers/123/campaigns/456" → "456").
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ExtractChildIdFromResourceName(System.String)">
            <summary>
            Lấy <b>id con trần</b> từ resource name ghép của Google.
            <para>
            Google định danh mọi đối tượng con bằng <c>{parentId}~{childId}</c>:
            <c>adGroupAds/{adGroupId}~{adId}</c>, <c>adGroupCriteria/{adGroupId}~{criterionId}</c>,
            <c>campaignCriteria/{campaignId}~{criterionId}</c>, <c>keywordViews/{adGroupId}~{criterionId}</c>.
            </para>
            <para>
            <b>Vì sao cần hàm riêng:</b> <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ExtractIdFromResourceName(System.String)"/> chỉ cắt theo dấu "/"
            nên trả về cả cụm ghép. Dùng nó cho đối tượng con chính là lỗi đã làm
            <c>AdsItem.ExternalId</c> lưu sai định dạng — kéo theo hai hậu quả: đổi trạng thái ghép
            id lần thứ hai thành <c>{groupId}~{groupId}~{adId}</c>, và số liệu theo cấp không bao giờ
            khớp được vì phía số liệu trả id trần.
            </para>
            <para>
            Chuẩn của LADA: canonical <b>luôn</b> lưu id trần; việc ghép lại chỉ xảy ra trong adapter.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToEntityStatus(System.String)">
            <summary>
            Trạng thái Google (ENABLED / PAUSED / REMOVED) → trạng thái canonical.
            Giá trị lạ (UNKNOWN / UNSPECIFIED) map về Draft để không hiển thị sai là đang chạy.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToGoogleStatus(Lada.Framework.Data.Enums.AdsEntityStatus)">
            <summary>
            Trạng thái canonical → chuỗi trạng thái Google.
            Draft không tồn tại bên Google nên đẩy lên thành PAUSED (an toàn về chi phí).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToObjective(System.String)">
            <summary>
            AdvertisingChannelType của Google → mục tiêu canonical.
            Google không có khái niệm "objective" như Facebook, nên đây chỉ là suy luận gần đúng;
            giá trị gốc luôn được giữ trong <c>ChannelType</c> và <c>PlatformPayloadJson</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToChannelType(Lada.Framework.Data.Enums.AdsObjective)">
            <summary>
            Mục tiêu canonical → AdvertisingChannelType của Google.
            Phase 2 chỉ hỗ trợ Search nên mọi mục tiêu đều tạo chiến dịch SEARCH;
            khi mở thêm loại chiến dịch thì sửa ở đây, không sửa ở tầng nghiệp vụ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToBudgetPeriod(Lada.Framework.Data.Enums.AdsBudgetType)">
            <summary>
            Loại ngân sách canonical → BudgetDeliveryMethod / period của Google.
            Google Ads chỉ có ngân sách theo ngày cho chiến dịch Search;
            ngân sách trọn chiến dịch không được hỗ trợ nên gọi hàm này với Lifetime sẽ báo lỗi rõ ràng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToGoogleStartDateTime(System.DateOnly)">
            <summary>
            Đổi ngày sang định dạng yyyy-MM-dd mà Google Ads dùng cho start_date_time.
            V25 nhận chuỗi "yyyy-MM-dd HH:mm:ss" — phần giờ để 00:00:00 nghĩa là tính theo ngày.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToGoogleEndDateTime(System.DateOnly)">
            <summary>
            Đổi ngày kết thúc sang định dạng Google. Phần giờ 23:59:59 để chạy hết ngày cuối.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ParseGoogleDate(System.String)">
            <summary>
            Đọc ngày Google trả về. V25 trả "yyyy-MM-dd HH:mm:ss" cho start_date_time / end_date_time,
            các field cũ trả "yyyy-MM-dd" hoặc "yyyyMMdd". Trả null nếu không parse được.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToDayOfWeek(System.String)">
            <summary>
            Thứ trong tuần của Google (MONDAY…SUNDAY) → <see cref="T:System.DayOfWeek"/> của .NET.
            <para>
            Không dùng ép kiểu số: enum Google là MONDAY = 2 (0 = UNSPECIFIED, 1 = UNKNOWN)
            còn .NET là Sunday = 0. Ép kiểu sẽ lệch ngày — lịch chạy sai hẳn một thứ.
            Giá trị lạ trả về null để service bỏ qua dòng thay vì ghi sai thứ.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToMinute(System.String)">
            <summary>
            Phút của Google (<c>MinuteOfHour</c>: ZERO / FIFTEEN / THIRTY / FORTY_FIVE) → số phút.
            Google chỉ cho 4 mốc này; giá trị lạ coi như 0 để không dựng ra khung giờ vô nghĩa.
            Tên enum trong SDK C# là dạng PascalCase (Zero, Fifteen, Thirty, FortyFive) —
            nhận cả dạng SNAKE_CASE của GAQL cho chắc.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToGoogleDayOfWeek(System.DayOfWeek)">
            <summary>
            Chiều ghi: <see cref="T:System.DayOfWeek"/> của .NET → enum thứ của Google.
            <para>
            Đổi theo tên, tuyệt đối không ép kiểu số: .NET Sunday = 0 còn Google MONDAY = 2.
            Ép kiểu là ghi lịch lệch một thứ lên tài khoản thật.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToGoogleMinute(System.Int32)">
            <summary>
            Chiều ghi: số phút → enum <c>MinuteOfHour</c> của Google.
            Google chỉ nhận 4 mốc 0/15/30/45; số khác bị chặn từ tầng validate
            (<c>AdsScheduleDiff.Validate</c>) nên tới đây mà lạ là lỗi lập trình → ném luôn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToKeywordMatchType(System.String)">
            <summary>
            Kiểu khớp của Google (EXACT / PHRASE / BROAD) → kiểu khớp canonical.
            <para>
            Trả <c>null</c> với UNSPECIFIED / UNKNOWN / giá trị lạ. <b>Cố ý không</b> quy về
            <see cref="F:Lada.Framework.Data.Enums.AdsKeywordMatchType.Broad"/>: khớp rộng là kiểu ăn truy vấn không liên quan
            và đốt ngân sách nhanh nhất, nên đoán sai về phía đó là đoán sai về phía tốn tiền.
            Adapter bỏ qua dòng và ghi log — cùng cách xử lý như <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToDayOfWeek(System.String)"/>.
            </para>
            <para>
            Nhận cả SNAKE_CASE của GAQL và PascalCase của SDK C# (<c>MatchType.ToString()</c>).
            Đổi theo tên, tuyệt đối không ép kiểu số: enum Google có UNSPECIFIED = 0, UNKNOWN = 1
            nên EXACT = 2 chứ không phải 1 như canonical.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToGoogleKeywordMatchType(Lada.Framework.Data.Enums.AdsKeywordMatchType)">
            <summary>
            Chiều ghi: kiểu khớp canonical → enum kiểu khớp của Google.
            <para>
            Giá trị canonical lạ thì <b>ném lỗi</b> chứ không trả UNSPECIFIED: gửi UNSPECIFIED lên
            Google sẽ bị nền tảng tự hiểu, và cái nó hiểu có thể là khớp rộng — tức là tạo ra một
            từ khoá tốn tiền hơn hẳn thứ người dùng chọn.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.Google.GoogleAdsMapper.ToPlatformEnumName(System.String)">
            <summary>
            Đổi tên enum của SDK C# (PascalCase) về đúng dạng tài liệu Google dùng (SNAKE_CASE hoa):
            <c>ResponsiveSearchAd</c> → <c>RESPONSIVE_SEARCH_AD</c>, <c>ReviewInProgress</c> →
            <c>REVIEW_IN_PROGRESS</c>.
            <para>
            Dùng cho các field LADA <b>cố ý giữ nguyên tên gốc</b> của nền tảng (loại quảng cáo,
            trạng thái xét duyệt): người dùng phải tra được đúng chuỗi đó trong tài liệu Google.
            Trả về PascalCase của SDK sẽ khiến tra cứu không ra.
            </para>
            <para>
            <c>UNSPECIFIED</c> / <c>UNKNOWN</c> trả <c>null</c> — hai giá trị này không mang thông tin
            nào, hiện lên UI chỉ làm người dùng tưởng nền tảng đã trả về một trạng thái thật.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter">
            <summary>
            Hợp đồng chung cho mọi nền tảng quảng cáo (Google, Facebook, TikTok, Zalo).
            Nguyên tắc: không một kiểu dữ liệu nào của SDK nền tảng được lọt ra ngoài adapter —
            mọi thứ đi vào/đi ra đều là entity canonical hoặc DTO trong <c>AdsAdapterDtos.cs</c>.
            Mọi thông báo lỗi trả về phải là tiếng Việt, kèm mã lỗi gốc của nền tảng để tra cứu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.Platform">
            <summary>Nền tảng mà adapter này phục vụ</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.GetCapabilities">
            <summary>
            Năng lực của nền tảng — UI dùng để render form credential và bật/tắt chức năng.
            Không cần kết nối, gọi được ngay khi chưa cấu hình gì.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.BuildAuthorizationUrl(Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAuthRequest)">
            <summary>
            Tạo URL để người dùng bấm vào cấp quyền (OAuth consent screen).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.ExchangeCodeAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Đổi authorization code (nhận từ callback) thành access token + refresh token.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.RefreshTokenAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.Threading.CancellationToken)">
            <summary>
            Làm mới access token bằng refresh token đang lưu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.TestConnectionAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.Threading.CancellationToken)">
            <summary>
            Kiểm tra kết nối: gọi thử một API nhẹ của nền tảng.
            Trả về thông báo tiếng Việt cụ thể (thiếu field nào, token sai, hay thiếu quyền).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.FetchAccountsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.Threading.CancellationToken)">
            <summary>
            Lấy danh sách tài khoản quảng cáo mà kết nối này truy cập được.
            Trả về cả phần lỗi của từng tài khoản đọc không được — service dùng để ghi sync log,
            nhờ vậy đồng bộ ra 0 tài khoản luôn kèm lý do cụ thể thay vì im lặng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.FetchCampaignsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.Threading.CancellationToken)">
            <summary>
            Lấy danh sách chiến dịch của một tài khoản quảng cáo.
            </summary>
            <param name="externalAccountId">Id tài khoản bên nền tảng</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.FetchAdGroupsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Lấy danh sách nhóm quảng cáo. Truyền <paramref name="externalCampaignId"/> để giới hạn theo một chiến dịch.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.FetchSchedulesAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Lấy lịch chạy quảng cáo (ad schedule) của tài khoản.
            Truyền <paramref name="externalCampaignId"/> để giới hạn theo một chiến dịch.
            <para>
            Ad schedule là criterion cấp chiến dịch. Trả về danh sách rỗng nghĩa là chiến dịch
            **chạy cả tuần 24/7** — không phải "không chạy".
            </para>
            <para>
            Nền tảng chưa hỗ trợ thì trả về danh sách rỗng, không ném exception.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.FetchAdsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Lấy danh sách quảng cáo cụ thể trong các nhóm (cấu trúc, không kèm số liệu).
            Truyền <paramref name="externalCampaignId"/> và/hoặc <paramref name="externalGroupId"/>
            để giới hạn phạm vi.
            <para>
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAdDto.ExternalId"/> trả về là <b>id trần</b>. Việc ghép thành resource name
            dạng <c>{adGroupId}~{adId}</c> nằm hoàn toàn trong adapter.
            </para>
            <para>
            Yêu cầu <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanFetchAds"/> = true. Nền tảng chưa hỗ trợ
            thì trả về danh sách rỗng, không ném exception.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.FetchKeywordsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Lấy danh sách từ khoá — <b>cả từ khoá thường và từ khoá phủ định</b>, phân biệt bằng
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.IsNegative"/> và <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto.Level"/>.
            <para>
            Phạm vi theo tham số:
            <list type="bullet">
            <item>có <paramref name="externalGroupId"/>: chỉ từ khoá <b>cấp nhóm</b> của nhóm đó;</item>
            <item>chỉ có <paramref name="externalCampaignId"/>: từ khoá cấp nhóm của mọi nhóm
            <b>cộng</b> từ khoá phủ định cấp chiến dịch;</item>
            <item>không có gì: toàn bộ tài khoản.</item>
            </list>
            </para>
            <para>
            Danh sách rỗng nghĩa là <b>không có từ khoá nào</b> — với từ khoá phủ định, đó là
            "không loại trừ truy vấn nào", tức mọi truy vấn liên quan đều có thể tiêu tiền.
            </para>
            <para>
            LADA <b>không</b> đọc được từ khoá phủ định nằm trong danh sách dùng chung
            (Google shared set) — chúng vẫn có tác dụng trên nền tảng nhưng không xuất hiện ở đây.
            UI phải nói rõ điều này thay vì để người dùng tưởng danh sách đã đủ.
            </para>
            <para>
            Yêu cầu <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanFetchKeywords"/> = true. Nền tảng chưa
            hỗ trợ thì trả về danh sách rỗng, không ném exception.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.FetchMetricsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.DateOnly,System.DateOnly,Lada.Framework.Data.Enums.AdsMetricLevel,System.Threading.CancellationToken)">
            <summary>
            Lấy số liệu theo ngày trong khoảng [from, to] ở cấp <paramref name="level"/>.
            Chi phí đã được chia micros trong adapter — không bao giờ trả micros ra ngoài.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.PublishCampaignAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest,System.Threading.CancellationToken)">
            <summary>
            Tạo chiến dịch (kèm nhóm, mẫu QC, targeting) trên nền tảng.
            Mặc định tạo ở trạng thái tạm dừng để tránh tiêu tiền ngoài ý muốn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.ValidateCampaignAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignPublishRequest,System.Threading.CancellationToken)">
            <summary>
            Gửi yêu cầu tạo chiến dịch ở chế độ kiểm tra (dry-run): nền tảng validate toàn bộ
            nhưng không tạo gì thật. Chỉ gọi được khi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.SupportsValidateOnly"/> = true.
            Đây là cách duy nhất biết trước Google có nhận dữ liệu hay không mà không tiêu tiền.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.UpdateCampaignAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignUpdateRequest,System.Threading.CancellationToken)">
            <summary>
            Cập nhật chiến dịch đã tồn tại trên nền tảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.ChangeStatusAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,Lada.Framework.Data.Enums.AdsEntityLevel,System.String,Lada.Framework.Data.Enums.AdsEntityStatus,System.String,System.Threading.CancellationToken)">
            <summary>
            Đổi trạng thái (bật/tạm dừng) một đối tượng quảng cáo trên nền tảng.
            </summary>
            <param name="externalId">
            Id đối tượng bên nền tảng, dạng <b>id trần</b> — không phải resource name, cũng không
            phải dạng ghép <c>{parentId}~{id}</c>. Việc ghép là việc của adapter.
            </param>
            <param name="externalParentId">
            Id đối tượng cha bên nền tảng, <b>bắt buộc</b> với <see cref="F:Lada.Framework.Data.Enums.AdsEntityLevel.Ad"/>:
            Google định danh một quảng cáo bằng <c>{adGroupId}~{adId}</c> nên thiếu id nhóm thì
            không dựng được resource name. Các cấp khác không cần.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.ChangeBudgetAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,System.String,System.String,System.Decimal,System.Threading.CancellationToken)">
            <summary>
            Đổi ngân sách của một chiến dịch đã tồn tại trên nền tảng.
            Nhận số tiền theo đơn vị tiền tệ của tài khoản — việc đổi sang micros là việc của adapter.
            </summary>
            <param name="externalBudgetId">Id đối tượng ngân sách bên nền tảng</param>
            <param name="dailyBudget">Ngân sách/ngày theo đơn vị tiền tệ của tài khoản</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.ApplySchedulesAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleApplyRequest,System.Boolean,System.Threading.CancellationToken)">
            <summary>
            Áp lịch chạy quảng cáo lên nền tảng: gửi <b>cả lô</b> thao tác (xoá + thêm + đổi %
            giá thầu) trong một request atomic.
            <para>
            Cố ý là một method cho cả lô, không tách thành ba: đổi được một nửa lịch là trạng thái
            tệ nhất — giá thầu đã thay đổi thật mà LADA lại không biết khung nào đã đi, khung nào chưa.
            </para>
            <para>
            <paramref name="validateOnly"/> = true thì nền tảng chỉ kiểm tra, không ghi gì
            (Google: <c>validate_only</c>). Chỉ gọi được khi
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.SupportsValidateOnly"/> = true.
            </para>
            <para>
            Yêu cầu <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanEditSchedules"/> = true. Nền tảng chưa
            hỗ trợ thì trả về <c>Success = false</c> kèm lý do tiếng Việt, không ném exception.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.ApplyKeywordsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordApplyRequest,System.Boolean,System.Threading.CancellationToken)">
            <summary>
            Áp từ khoá lên nền tảng: gửi <b>cả lô</b> thao tác (xoá + thêm + đổi giá thầu) trong một
            request atomic.
            <para>
            Cố ý là một method cho cả lô: xoá được một nửa rồi lỗi là trạng thái tệ nhất — chiến dịch
            mất từ khoá phủ định mà vẫn đang chạy, tiền chảy ra ngay và LADA không biết dòng nào đã đi.
            </para>
            <para>
            <paramref name="validateOnly"/> = true thì nền tảng chỉ kiểm tra, không ghi gì
            (Google: <c>validate_only</c>). Chỉ gọi được khi
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.SupportsValidateOnly"/> = true — nền tảng không có
            dry-run thì phải <b>trả về lỗi</b>, tuyệt đối không âm thầm ghi thật.
            </para>
            <para>
            Yêu cầu <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanEditKeywords"/> = true. Nền tảng chưa
            hỗ trợ thì trả về <c>Success = false</c> kèm lý do tiếng Việt, không ném exception.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.IAdsPlatformAdapter.UpdateGroupBidsAsync(Lada.Framework.Data.Domains.Ads.AdsConnection,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupBidApplyRequest,System.Boolean,System.Threading.CancellationToken)">
            <summary>
            Đổi giá thầu cho <b>cả lô</b> nhóm quảng cáo của một tài khoản trong một request atomic.
            <para>
            Giá thầu trong <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsGroupBidOperation.CpcBid"/> là đơn vị <b>tiền tệ</b>;
            việc đổi ra micros là của adapter, tầng nghiệp vụ không được biết đến micros.
            </para>
            <para>
            <paramref name="validateOnly"/> = true thì nền tảng chỉ kiểm tra, không ghi gì. Chỉ gọi
            được khi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.SupportsValidateOnly"/> = true — nền tảng
            không có dry-run thì phải <b>trả về lỗi</b>, tuyệt đối không âm thầm ghi thật.
            </para>
            <para>
            Yêu cầu <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CanEditGroupBid"/> = true. Nền tảng chưa
            hỗ trợ thì trả về <c>Success = false</c> kèm lý do tiếng Việt, không ném exception.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsAccountService">
            <summary>
            Quản lý tài khoản quảng cáo đồng bộ từ nền tảng về.
            Tài khoản không được tạo tay trong LADA — luôn kéo từ nền tảng để ExternalId chắc chắn đúng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsAccountService.GetByConnectionAsync(System.Int32)">
            <summary>Danh sách tài khoản đang dùng được của một kết nối (cho dropdown)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsAccountService.SyncFromPlatformAsync(System.Int32,System.Int32,System.String)">
            <summary>
            Kéo danh sách tài khoản từ nền tảng về, upsert theo (AdsConnectionId, ExternalId).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsAccountService.ToggleActiveAsync(System.Int32,System.Int32,System.String)">
            <summary>Bật/tắt việc đưa tài khoản vào các job đồng bộ định kỳ</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsAccountService.GetEntityAsync(System.Int32)">
            <summary>Lấy entity kèm kết nối — dùng nội bộ backend khi cần credential</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsAccountSyncResult">
            <summary>
            Kết quả đồng bộ tài khoản quảng cáo.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsAccountSyncResult.CreatedCount">
            <summary>Số tài khoản mới thêm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsAccountSyncResult.UpdatedCount">
            <summary>Số tài khoản đã cập nhật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsAccountSyncResult.TotalCount">
            <summary>Tổng số tài khoản nền tảng trả về</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsAccountService">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsAccountService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsAccountService.GetByIdAsync(System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsAccountService.GetEntityAsync(System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsAccountService.GetByConnectionAsync(System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsAccountService.SyncFromPlatformAsync(System.Int32,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsAccountService.ToggleActiveAsync(System.Int32,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOperation">
            <summary>
            Phép tính áp lên giá thầu cũ của từng dòng.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOperation.Set">
            <summary>Đặt thẳng một giá thầu mới, không phụ thuộc giá cũ</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOperation.IncreasePercent">
            <summary>Tăng theo phần trăm giá cũ</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOperation.DecreasePercent">
            <summary>Giảm theo phần trăm giá cũ</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOperation.IncreaseAmount">
            <summary>Cộng thêm một số tiền vào giá cũ</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOperation.DecreaseAmount">
            <summary>Trừ bớt một số tiền khỏi giá cũ</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidSkipReason">
            <summary>
            Lý do một dòng không đổi được giá thầu, ở mức <b>phép tính</b> (không phải mức dữ liệu).
            <para>
            Là enum chứ không phải chuỗi để test khẳng định được đúng nhánh mà không phụ thuộc câu chữ
            tiếng Việt; câu hiển thị dựng ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidCalculator.DescribeSkip(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidSkipReason,System.Boolean)"/>.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidSkipReason.None">
            <summary>Tính được bình thường</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidSkipReason.InheritsBid">
            <summary>
            Chưa có giá thầu riêng mà phép tính lại dựa trên giá cũ (±% hoặc ± số tiền).
            Ca thật: 2.711/2.718 từ khoá đang kế thừa giá thầu của nhóm — nhân lên sẽ vô tình sinh
            hàng nghìn giá thầu riêng, đúng thứ người dùng không hề yêu cầu.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidSkipReason.Unchanged">
            <summary>Giá thầu mới bằng đúng giá cũ — gửi lên nền tảng chỉ tốn quota và làm số đếm sai</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidComputeResult">
            <summary>Kết quả tính giá thầu mới cho một dòng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidComputeResult.NewBid">
            <summary>Giá thầu mới đã làm tròn và kẹp. <c>null</c> khi dòng bị bỏ qua.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidComputeResult.SkipReason">
            <summary>Lý do bỏ qua; <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidSkipReason.None"/> nghĩa là tính được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidComputeResult.Changed">
            <summary>Tính được và có thay đổi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidComputeResult.Clamped">
            <summary>
            Giá trị đã bị sàn/trần kéo về — giao diện phải nói rõ, vì "tăng 50 %" mà kết quả không
            tăng 50 % là chuyện người dùng cần biết ngay trên dòng đó.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidCalculator">
            <summary>
            Luật tính giá thầu hàng loạt — <b>thuần</b>, không chạm DB, không chạm SDK nền tảng.
            <para>
            Tách riêng để test được từng luật và từng ca biên: đây là chỗ duy nhất quyết định con số
            sẽ ghi lên nền tảng, mà ghi sai một con số ở đây là tiêu sai tiền thật ngay phiên đấu giá
            kế tiếp. Mọi thứ cần biết đều truyền vào tham số, không đọc trạng thái bên ngoài.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidCalculator.ZeroDecimalCurrencies">
            <summary>
            Các mã tiền tệ <b>không có phần lẻ</b> (ISO 4217 minor unit = 0). Giá thầu VND phải là số
            nguyên đồng; gửi 1234,5 ₫ lên Google là tự chuốc lấy sai số làm tròn ở phía nền tảng.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidCalculator.MaxIncreasePercent">
            <summary>Trần phần trăm tăng một lần — chặn lỗi gõ thừa số 0 biến giá thầu thành gấp trăm lần</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidCalculator.SpikeFactor">
            <summary>
            Bội số so với giá cũ mà vượt qua thì <b>cảnh báo mềm</b> (sổ nợ N-32).
            <para>
            Phép "Đặt giá thầu" không có trần nào: gõ thừa một số 0 (60.000 ₫ thay vì 6.000 ₫) qua được
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidCalculator.Validate(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOperation,System.Decimal,System.Nullable{System.Decimal},System.Nullable{System.Decimal})"/>. Cố ý cảnh báo chứ không chặn — giá thầu hợp lệ khác nhau theo tài
            khoản, một con số cứng sẽ chặn nhầm nhiều hơn chặn đúng (cùng nếp cảnh-báo-không-chặn của plan §3.5).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidCalculator.IsSpike(System.Nullable{System.Decimal},System.Decimal,System.String)">
            <summary>
            Giá mới có vọt lên quá <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidCalculator.SpikeFactor"/> lần giá cũ không.
            <para>
            <b>Giá cũ đúng bằng sàn cứng của tiền tệ thì không tính</b> — và đó không phải ngoại lệ cho
            đẹp: đo trên dữ liệu thật ngày 05/09/2026, <b>146/149 nhóm đang ở 1 ₫</b>, tức mức nhỏ nhất
            gửi được. Với chúng thì mọi giá thầu thật đều vượt 10 lần, nên không lọc ra thì cảnh báo
            bật trên gần như mọi dòng và trở thành cái chuông kêu suốt — đúng thứ làm người ta bỏ qua
            cả những cảnh báo có thật. 1 ₫ là "chưa đặt giá bao giờ", không phải một mốc để so.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidCalculator.DecimalsFor(System.String)">
            <summary>Số chữ số thập phân của một loại tiền (VND = 0, mặc định = 2)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidCalculator.MinimumBidFor(System.String)">
            <summary>
            Giá thầu nhỏ nhất gửi được của một loại tiền — 1 đơn vị nhỏ nhất (VND: 1 ₫; USD: 0,01 $).
            Google từ chối <c>cpc_bid_micros</c> ≤ 0 nên đây là sàn cứng, không phải lựa chọn giao diện.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidCalculator.Validate(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOperation,System.Decimal,System.Nullable{System.Decimal},System.Nullable{System.Decimal})">
            <summary>
            Kiểm tra tham số của <b>cả lô</b> trước khi tính dòng nào. Trả <c>null</c> là hợp lệ.
            <para>
            Tách khỏi <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidCalculator.Compute(System.Nullable{System.Decimal},Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOperation,System.Decimal,System.Nullable{System.Decimal},System.Nullable{System.Decimal},System.String)"/> vì đây là lỗi của yêu cầu, không phải của một dòng:
            sai ở đây thì từ chối cả lô và không gọi ra nền tảng lần nào.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidCalculator.Compute(System.Nullable{System.Decimal},Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOperation,System.Decimal,System.Nullable{System.Decimal},System.Nullable{System.Decimal},System.String)">
            <summary>
            Tính giá thầu mới cho <b>một</b> dòng.
            <para>
            Thứ tự cố ý: tính thô → làm tròn theo tiền tệ → kẹp vào sàn/trần người dùng nhập →
            kéo lên sàn cứng của nền tảng → so với giá cũ. Kẹp trước khi làm tròn sẽ để lọt giá trị
            vượt trần đúng bằng nửa đơn vị làm tròn.
            </para>
            </summary>
            <param name="oldBid">
            Giá thầu hiện tại. <c>null</c> = chưa có giá thầu riêng (từ khoá đang kế thừa của nhóm):
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOperation.Set"/> đặt giá riêng mới, còn ± thì bỏ qua vì không có gốc để tính.
            </param>
            <param name="minBid">Sàn do người dùng nhập (tuỳ chọn) — kẹp sau khi tính</param>
            <param name="maxBid">Trần do người dùng nhập (tuỳ chọn) — kẹp sau khi tính</param>
            <param name="currencyCode">Mã tiền của tài khoản, quyết định cách làm tròn và sàn cứng</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidCalculator.DescribeSkip(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidSkipReason,System.Boolean)">
            <summary>
            Câu tiếng Việt cho lý do bỏ qua, khác nhau theo cấp vì người đọc cần biết phải làm gì tiếp.
            </summary>
            <param name="isKeyword">true = dòng từ khoá, false = dòng nhóm quảng cáo</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOutcome">
            <summary>Kết cục của một dòng trong lô đổi giá thầu.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOutcome.Failed">
            <summary>Nền tảng từ chối hoặc lời gọi lỗi — dòng này chưa đổi gì cả</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOutcome.Changed">
            <summary>Đổi được (xem trước: sẽ đổi được)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOutcome.Skipped">
            <summary>Không đổi vì lý do hợp lệ — không phải lỗi</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOutcome.PlatformOnly">
            <summary>
            Nền tảng <b>đã đổi</b> giá thầu nhưng LADA chưa ghi lại được (DB lỗi ngay sau lời gọi).
            <para>
            Phải là một kết cục RIÊNG, không được gộp vào <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidOutcome.Failed"/>: gộp vào là nói với
            người dùng "chưa đổi gì" trong khi tiền đã đổi thật, và bảng kết quả trở thành lời mời
            chạy lại — chạy lại thì mức tăng cộng chồng lên nhau trên nền tảng.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidRow">
            <summary>Một dòng kết quả đổi giá thầu — mỗi nhóm hoặc mỗi từ khoá một dòng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidRow.EntityId">
            <summary>Id nhóm hoặc Id từ khoá bên LADA</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidRow.Name">
            <summary>Tên nhóm, hoặc nội dung từ khoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidRow.GroupName">
            <summary>Tên nhóm cha — chỉ có ý nghĩa với dòng từ khoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidRow.OldBid">
            <summary>Giá thầu hiện tại. <c>null</c> = đang kế thừa giá thầu nhóm.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidRow.NewBid">
            <summary>Giá thầu sau khi đổi. <c>null</c> khi dòng bị bỏ qua hoặc thất bại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidRow.OutcomeStr">
            <summary>Nhãn kết cục cho giao diện — chỉ một chỗ dựng chữ, tránh mỗi bảng một kiểu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidRow.Reason">
            <summary>Lý do bỏ qua / thất bại, tiếng Việt, nói rõ phải làm gì tiếp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidRow.Clamped">
            <summary>Giá trị đã bị sàn/trần kéo về nên không đúng bằng phép tính đã nhập</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidRow.StrategyWarning">
            <summary>
            Cảnh báo chiến lược đặt giá bỏ qua giá thầu — <b>không</b> chặn, nhưng phải hiện trên
            đúng dòng đó. Google vẫn nhận và đọc lại vẫn thấy giá trị, nên không có cách nào biết
            bằng API là nó vô tác dụng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidRow.SpikeWarning">
            <summary>
            Cảnh báo mềm "giá mới vọt hơn 10 lần giá hiện tại" (sổ nợ N-32) — <b>không</b> chặn,
            hiện ngay trên dòng xem trước để lỗi gõ thừa số 0 lộ ra trước khi bấm ghi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidRow.StaleBid">
            <summary>
            Dòng bị bỏ qua vì giá thầu đã đổi so với lúc xem trước (sổ nợ N-31). Tách khỏi
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidRow.Reason"/> để giao diện làm nổi bật riêng — đây không phải một lý do bỏ qua
            thông thường mà là dấu hiệu bảng xác nhận đã cũ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidResult">
            <summary>
            Kết quả một lô đổi giá thầu.
            <para>
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidResult.Rejected"/> là ca lô bị từ chối <b>trước khi chạy</b> (Id lạ, quá trần, tham số sai):
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidResult.Rows"/> rỗng, <c>Message</c> là lý do — controller trả 400, giao diện dừng lô thay
            vì suy đoán từ số dòng. Giống hệt khuôn của kéo lịch về hàng loạt.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidResult.IsPreview">
            <summary>Bản xem trước (nền tảng chỉ kiểm tra) hay lần ghi thật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidResult.Rejected">
            <summary>Lô bị từ chối trước khi chạy — không dòng nào được xử lý, không gọi nền tảng lần nào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidResult.PlatformAccepted">
            <summary>
            Nền tảng đã nhận toàn bộ phần gửi lên hay chưa. Xem trước mà cờ này false nghĩa là
            bấm ghi thật cũng sẽ hỏng đúng chỗ đó.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidResult.PlatformOnlyCount">
            <summary>
            Số dòng nền tảng đã đổi mà LADA chưa ghi lại được — giao diện phải nói rõ
            <b>đừng chạy lại lô</b>, vì chạy lại là cộng chồng mức tăng trên nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidResult.StaleCount">
            <summary>
            Số dòng bị bỏ qua vì giá thầu đã đổi từ lúc xem trước (N-31). Đếm riêng vì giao diện phải
            mời người dùng <b>xem trước lại</b>, khác hẳn các lý do bỏ qua khác.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidResult.PlatformCallCount">
            <summary>Số lời gọi mutate đã gửi ra nền tảng — để ước lượng quota</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidResult.StrategyWarning">
            <summary>
            Cảnh báo gộp cho cả lô khi có dòng thuộc chiến dịch dùng chiến lược bỏ qua giá thầu.
            Hiện thành băng-rôn trên hộp thoại, ngoài cảnh báo từng dòng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsBulkBidService">
            <summary>
            Đổi giá thầu hàng loạt cho nhóm quảng cáo và từ khoá.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsBulkBidService.PreviewAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Xem trước: tính giá mới cho từng dòng rồi hỏi nền tảng bằng <c>validate_only</c>.
            <b>Không</b> ghi gì vào LADA và không ghi gì lên nền tảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsBulkBidService.ApplyAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Ghi thật: gửi lên nền tảng trước, <b>thành công mới</b> ghi giá thầu mới vào LADA.
            Nền tảng từ chối thì LADA giữ nguyên số cũ, không bao giờ lệch.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService">
            <inheritdoc />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.MaxEntitiesPerRequest">
            <summary>Trần Id một lô — cùng con số với mọi endpoint nhận danh sách Id khác (plan §3.9)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.CpcBidFieldMask">
            <summary>Field mask duy nhất được gửi khi đổi giá thầu — dựng tay, xem bẫy proto3 ở adapter</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.PreviewAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.ApplyAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.RunAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel,System.Int32,System.String,System.Boolean,System.Threading.CancellationToken)">
            <summary>
            Lõi dùng chung của xem trước và ghi thật, khác nhau đúng một cờ <paramref name="validateOnly"/>.
            <para>
            Cố ý dùng chung: bản xem trước không bao giờ được tính khác bản ghi thật — cùng bài học
            đã rút ở luồng áp lịch (<c>ApplyCoreAsync</c>).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.SendBatchAsync(System.Collections.Generic.List{System.ValueTuple{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.BidTarget,Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidRow,System.Decimal}},System.Boolean,System.Boolean,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Gửi một cụm lên nền tảng. Cụm là một chiến dịch (nhóm) hoặc một nhóm (từ khoá) nên
            mọi dòng trong cụm chắc chắn cùng tài khoản, cùng kết nối.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.WriteSyncLogSafelyAsync(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogEntry)">
            <summary>Ghi một dòng nhật ký đồng bộ; lỗi ghi log chỉ được cảnh báo, không được ném ra.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.SaveLocalBidAsync(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.BidTarget,System.Decimal,System.Int32,System.String)">
            <summary>Ghi giá thầu mới vào LADA sau khi nền tảng đã nhận.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.StructuralSkipReason(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.BidTarget,System.Boolean)">
            <summary>
            Các ca bỏ qua vì <b>dữ liệu</b>, kiểm trước khi tính toán gì. Cùng khuôn với
            <c>AdsScheduleService.SkipReasonFor</c>: gọi vào nền tảng ở các ca này là chắc chắn
            thất bại và chỉ tốn quota.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.StrategyWarningFor(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.BidTarget)">
            <summary>
            Cảnh báo chiến lược đặt giá bỏ qua giá thầu. <b>Không</b> chặn: Google vẫn nhận, vẫn lưu
            và đọc lại vẫn thấy giá trị — chặn ở đây sẽ lệch với tính năng lịch chạy đang cho đặt
            % kèm cảnh báo trên đúng các chiến lược này (plan §3.5).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.BuildExpectationMap(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsBulkBidModel,System.Boolean)">
            <summary>
            Bảng "giá cũ người dùng đã nhìn thấy" theo Id (N-31), hoặc <c>null</c> khi không phải kiểm.
            <para>
            Trả <c>null</c> ở bước xem trước và khi client không gửi gì: hàng rào này là <b>ràng buộc
            giữa hai bước</b>, không phải một trường bắt buộc — biến nó thành bắt buộc sẽ làm mọi lời
            gọi cũ hỏng mà không thêm an toàn nào cho luồng giao diện (nút ghi chỉ mở sau xem trước).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.SpikeWarningFor(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.BidTarget,System.Decimal)">
            <summary>
            Cảnh báo mềm giá vọt (N-32) cho một dòng — chỉ dựng câu chữ, luật nằm ở
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidCalculator.IsSpike(System.Nullable{System.Decimal},System.Decimal,System.String)"/> để test được không qua DB.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.FormatBid(System.Nullable{System.Decimal},System.String)">
            <summary>
            Số tiền cho câu tiếng Việt trong lý do / cảnh báo. <c>null</c> là "kế thừa nhóm", khác hẳn 0 ₫
            — cùng quy ước với bảng ở giao diện.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.BuildBatchStrategyWarning(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidRow})">
            <summary>Một câu gộp cho băng-rôn hộp thoại, đếm số dòng bị ảnh hưởng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.BidTarget">
            <summary>
            Một dòng cần đổi giá thầu, đã gom đủ mọi thứ cần biết từ hai cây entity khác nhau
            (nhóm và từ khoá) để phần tính toán bên dưới chỉ viết một lần.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.BidTarget.GroupEntity">
            <summary>Chính nó, khi lô là lô nhóm quảng cáo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.BidTarget.Keyword">
            <summary>Chính nó, khi lô là lô từ khoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.BidTarget.ExternalId">
            <summary>Id nhóm (lô nhóm) hoặc criterion id (lô từ khoá) bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkBidService.BidTarget.ExternalGroupId">
            <summary>Id nhóm cha bên nền tảng — bắt buộc với lô từ khoá</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsCampaignService">
            <summary>
            Đọc và soạn chiến dịch quảng cáo trong LADA.
            Service này chỉ làm việc với bản ghi canonical — mọi thao tác đẩy ra nền tảng
            (tiêu tiền thật) nằm ở <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsPublishService"/> và yêu cầu quyền riêng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsCampaignService.GetDetailAsync(System.Guid,System.Nullable{System.DateOnly},System.Nullable{System.DateOnly})">
            <summary>
            Chi tiết chiến dịch: thông tin chiến dịch, danh sách nhóm và số liệu tổng hợp
            trong khoảng ngày (mặc định 30 ngày gần nhất).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsCampaignService.GetEntityAsync(System.Guid)">
            <summary>Lấy entity kèm tài khoản và kết nối — dùng nội bộ backend</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsCampaignService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCampaignModel,System.Int32,System.String)">
            <summary>
            Lưu cả cây chiến dịch nháp: chiến dịch → nhóm → mẫu quảng cáo → targeting.
            Chiến dịch đã có trên nền tảng chỉ cho sửa những trường đẩy lên được —
            không cho thay cấu trúc nhóm/mẫu vì bản trên nền tảng sẽ lệch ngay.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsCampaignService.DeleteAsync(System.Guid,System.Int32,System.String)">
            <summary>
            Xoá mềm chiến dịch trong LADA. Chiến dịch đã đẩy lên nền tảng thì phải xoá trên
            nền tảng trước — xoá trong LADA không dừng được quảng cáo đang tiêu tiền.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignService">
            <inheritdoc />
            <summary>
            Phần soạn chiến dịch nháp trong LADA (chưa chạm tới nền tảng).
            Tách file để phần đọc ở <c>AdsCampaignService.cs</c> giữ được độ ngắn dễ đọc.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignService.SearchByMetricSortAsync(System.Linq.IQueryable{Lada.Framework.Data.Domains.Ads.AdsCampaign},Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignMetricSortField,System.Boolean,System.DateOnly,System.DateOnly)">
            <summary>
            Đường riêng cho việc sắp theo cột số liệu: sắp chính truy vấn chiến dịch bằng một
            <b>truy vấn con tương quan</b> cộng <c>AdsMetricDaily</c> của khoảng ngày, rồi mới cắt trang.
            <para>
            <b>Không</b> gộp sẵn bằng <c>GroupBy</c> rồi nối trái vào: EF Core không dịch nổi một
            projection của <c>GroupBy</c> nằm ở vế trong của phép nối và ném
            <i>"The LINQ expression … could not be translated"</i> ngay khi chạy thật (bẫy đã cắn — test
            chạy trên repository giả trong bộ nhớ dịch được mọi thứ nên không thấy).
            </para>
            <para>
            Ba điểm đã cân nhắc:
            <list type="bullet">
            <item>Công thức gộp phải khớp <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricAggregator"/> — tỉ lệ tính từ tổng tử số
            chia tổng mẫu số, không phải trung bình cột tỉ lệ của từng ngày. Lệch thì bảng sắp một đằng
            còn cột hiện một nẻo, và người xem tin vào cột.</item>
            <item>Chiến dịch chưa có dòng số liệu nào coi như 0 khi sắp (ô vẫn hiện "—"): sắp giảm dần
            chúng nằm cuối, sắp tăng dần chúng nằm cùng nhóm chi 0 đồng.</item>
            <item>Sau khoá sắp còn hai khoá phụ (mới nhất trước, rồi Id) để thứ tự ổn định. Rất nhiều
            chiến dịch cùng chi phí 0; thứ tự nhập nhằng làm một dòng hiện ở hai trang liền nhau còn
            dòng khác biến mất.</item>
            </list>
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignService.AttachMetricsAsync(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCampaignItem},System.Nullable{System.DateOnly},System.Nullable{System.DateOnly})">
            <summary>
            Gắn số liệu gộp cho các chiến dịch <b>của trang vừa phân trang</b> (plan §3.6): một truy
            vấn <c>AdsMetricDaily</c> cấp chiến dịch cho cả trang rồi gộp trong bộ nhớ bằng đúng
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricAggregator"/> mà <c>report/overview</c> dùng — nên tổng cột của mọi
            trang cộng lại bằng thẻ KPI cùng bộ lọc (test đối chiếu <c>AdsCampaignSearchMetricsTests</c>).
            <para>
            Không truyền khoảng ngày thì không đụng bảng số liệu: các chỗ gọi <c>search</c> chỉ để đếm
            hay lấy danh sách (thanh trạng thái, ô chọn) không phải trả giá cho cột mình không dùng.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignService.ParseFilterDate(System.Object,System.String)">
            <summary>
            Đọc một mốc ngày từ <c>PredicateObject</c>. Chỉ nhận đúng <c>yyyy-MM-dd</c> (giao diện gửi
            từ store ngữ cảnh); giá trị lạ thì báo lỗi rõ thay vì lặng lẽ bỏ qua hay đoán — bảng trống
            số liệu vì một ngày sai định dạng là lỗi rất khó nhìn ra, còn "01/08/2026" mà đoán thành
            ngày 8 tháng 1 thì bảng vẫn có số và không ai nghi ngờ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignService.GetEntityAsync(System.Guid)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignService.GetDetailAsync(System.Guid,System.Nullable{System.DateOnly},System.Nullable{System.DateOnly})">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCampaignModel,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignService.SaveGroupsAsync(Lada.Framework.Data.Domains.Ads.AdsCampaign,Lada.Framework.Data.Domains.Ads.AdsAccount,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsGroupModel},System.Int32,System.String,System.DateTimeOffset)">
            <summary>
            Lưu danh sách nhóm kèm mẫu quảng cáo và targeting.
            Trả về kết quả lỗi khi có vấn đề, null nghĩa là thành công.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignService.SaveGroupCreativesAsync(Lada.Framework.Data.Domains.Ads.AdsCampaign,Lada.Framework.Data.Domains.Ads.AdsAccount,Lada.Framework.Data.Domains.Ads.AdsGroup,System.Collections.Generic.List{System.Guid},System.Int32,System.String,System.DateTimeOffset)">
            <summary>
            Gắn các mẫu quảng cáo vào nhóm dưới dạng bản ghi AdsItem chưa publish.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignService.SaveTargetingAsync(Lada.Framework.Data.Domains.Ads.AdsGroup,Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsTargetingModel,Lada.Framework.Data.Enums.AdsPlatform,System.Int32,System.String,System.DateTimeOffset)">
            <summary>
            Lưu targeting của nhóm. Mỗi nhóm chỉ có một bản ghi targeting.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignService.DeleteAsync(System.Guid,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignMetricSortField">
            <summary>
            Cột số liệu mà lưới chiến dịch sắp xếp được. Số liệu nằm ở <c>AdsMetricDaily</c> chứ không
            phải trên entity, nên sắp theo các cột này phải gộp trước khi phân trang — xem
            <c>AdsCampaignService.SearchByMetricSortAsync</c>.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignMetricSortField.Cost">
            <summary>Chi phí — tổng <c>Cost</c> trong khoảng ngày</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignMetricSortField.Impressions">
            <summary>Lượt hiển thị — tổng <c>Impressions</c></summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignMetricSortField.Clicks">
            <summary>Lượt nhấp — tổng <c>Clicks</c></summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignMetricSortField.Ctr">
            <summary>CTR — <c>tổng Clicks / tổng Impressions</c>, không phải trung bình CTR từng ngày</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignMetricSortField.Cpc">
            <summary>CPC trung bình — <c>tổng Cost / tổng Clicks</c></summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignMetricSortField.Conversions">
            <summary>Chuyển đổi — tổng <c>Conversions</c></summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignSort">
            <summary>
            Đọc yêu cầu sắp xếp của lưới chiến dịch. <b>Thuần logic</b> — không chạm database.
            <para>
            Có hai họ cột và chúng đi hai đường khác nhau: cột của chính chiến dịch (tên, ngân sách,
            trạng thái...) sắp được ngay trên truy vấn entity, còn cột số liệu phải gộp
            <c>AdsMetricDaily</c> theo khoảng ngày rồi mới sắp.
            </para>
            <para>
            <b>Vì sao phải lọc danh sách trắng:</b> khoá sắp xếp đi trên URL của trang danh sách nên người
            dùng sửa tay được. <c>OrderByName</c> ném <see cref="T:System.ArgumentException"/> khi tên trường không
            có thật — nghĩa là một URL gõ nhầm sẽ thành lỗi 500 chứ không phải một bảng sắp theo mặc định.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignSort.DefaultPredicate">
            <summary>Sắp mặc định khi không yêu cầu gì, hoặc khi yêu cầu không hợp lệ: mới nhất trước.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignSort.MetricFields">
            <summary>
            Khoá cột trên lưới → chỉ số cần gộp. Khoá trùng đúng <c>key</c> của cột trong
            <c>campaigns/index.vue</c> để không phải dịch tên ở giữa hai đầu.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignSort.EntityFields">
            <summary>
            Trường của entity <c>AdsCampaign</c> cho phép sắp. So sánh không phân biệt hoa thường
            nhưng luôn trả về <b>tên chuẩn</b> trong tập này: <c>OrderByName</c> tra property phân biệt
            hoa thường, nên trả lại nguyên chuỗi người dùng gửi là mở đường cho đúng lỗi 500 ở trên.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignSort.MetricField(System.String)">
            <summary>
            Cột số liệu tương ứng, hoặc <c>null</c> nếu yêu cầu không phải cột số liệu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignSort.EntitySort(Lada.Framework.DTO.SmartTable.Sort)">
            <summary>
            Yêu cầu sắp xếp trên chính entity, đã chuẩn hoá: tên ngoài danh sách trắng (kể cả tên cột
            số liệu khi bảng không có khoảng ngày để gộp) rơi về sắp mặc định.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignSort.OrderByMetric(System.Linq.IQueryable{Lada.Framework.Data.Domains.Ads.AdsCampaign},System.Linq.IQueryable{Lada.Framework.Data.Domains.Ads.AdsMetricDaily},Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCampaignMetricSortField,System.Boolean)">
            <summary>
            Sắp truy vấn chiến dịch theo một chỉ số gộp từ <paramref name="metricRows"/> bằng
            <b>truy vấn con tương quan</b> — không gộp sẵn rồi nối trái, vì EF Core không dịch nổi một
            projection của <c>GroupBy</c> ở vế trong của phép nối (đã cắn: <i>"The LINQ expression …
            could not be translated"</i>). Ca dịch được kiểm bằng <c>ToQueryString()</c> trong
            <c>AdsCampaignSortSqlTests</c>: repository giả trong bộ nhớ của các test khác chạy được cả
            những truy vấn mà SQL Server không dịch nổi, nên nó KHÔNG chứng minh được điều này.
            <para>
            CTR và CPC tính lại tại chỗ từ tổng, đúng công thức <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricAggregator"/> —
            không đọc cột <c>Ctr</c>/<c>Cpc</c> của từng dòng ngày (chúng là tỉ lệ của riêng ngày đó).
            Mẫu số 0 trả 0 như <c>SafeRatio</c>/<c>SafeDivide</c>. Chỗ này KHÔNG làm tròn như bên đó:
            làm tròn chỉ đổi được thứ tự của hai giá trị vốn đã bằng nhau sau khi làm tròn, mà thứ tự
            của chúng đã do hai khoá phụ quyết định.
            </para>
            <para>
            Hai khoá phụ (mới nhất trước, rồi <c>Id</c>) là bắt buộc: rất nhiều chiến dịch cùng chi phí
            0, thứ tự nhập nhằng làm một dòng hiện ở hai trang liền nhau còn dòng khác biến mất.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsConnectionService">
            <summary>
            Quản lý kết nối tới nền tảng quảng cáo: CRUD, luồng OAuth, kiểm tra kết nối.
            Credentials do người dùng nhập ở trang cấu hình, không đọc từ appsettings.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsConnectionService.GetCapabilities(Lada.Framework.Data.Enums.AdsPlatform)">
            <summary>Năng lực của một nền tảng — UI render form credential từ đây</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsConnectionService.GetAllCapabilities">
            <summary>Năng lực của mọi nền tảng đã khai báo adapter</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsConnectionService.GetAuthorizationUrlAsync(System.Int32)">
            <summary>Tạo URL cấp quyền OAuth cho một kết nối</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsConnectionService.HandleOAuthCallbackAsync(System.String,System.String,System.String)">
            <summary>
            Xử lý callback OAuth: kiểm tra state, đổi code lấy token, lưu vào kết nối.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsConnectionService.TestConnectionAsync(System.Int32,System.Int32,System.String)">
            <summary>Kiểm tra kết nối bằng một lệnh gọi nhẹ tới nền tảng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsConnectionService.GetEntityAsync(System.Int32)">
            <summary>Lấy entity kèm credential gốc — chỉ dùng nội bộ backend, không trả ra API</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsAuthUrlResult">
            <summary>
            Kết quả tạo URL cấp quyền.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsAuthUrlResult.MissingFields">
            <summary>Danh sách field còn thiếu để UI highlight đúng ô nhập</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsConnectionService">
            <inheritdoc />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsConnectionService.StateSecretConfigKey">
            <summary>Chuỗi bí mật dùng ký tham số state của OAuth (chống CSRF)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsConnectionService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsConnectionService.GetByIdAsync(System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsConnectionService.GetEntityAsync(System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsConnectionService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsConnectionModel,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsConnectionService.DeleteAsync(System.Int32,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsConnectionService.GetCapabilities(Lada.Framework.Data.Enums.AdsPlatform)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsConnectionService.GetAllCapabilities">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsConnectionService.GetAuthorizationUrlAsync(System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsConnectionService.HandleOAuthCallbackAsync(System.String,System.String,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsConnectionService.TestConnectionAsync(System.Int32,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsConnectionService.BuildState(System.Int32)">
            <summary>
            Chuỗi state = "{connectionId}.{chữ ký HMAC}". Chỉ callback do LADA khởi tạo mới ký đúng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsConnectionService.ShouldApplySecret(System.String)">
            <summary>
            Giá trị mật gửi lên có chứa *** nghĩa là client trả lại chuỗi đã che → không ghi vào DB.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsCreativeService">
            <summary>
            Quản lý mẫu quảng cáo (creative) và cầu nối từ nội dung website sang quảng cáo.
            Mọi giới hạn ký tự đều đọc từ <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities.CreativeLimits"/> của nền tảng đích —
            tuyệt đối không hard-code 30/90 ở đây, vì Google có thể đổi và mỗi nền tảng một con số.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsCreativeService.Validate(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeModel,Lada.Framework.Data.Enums.AdsPlatform)">
            <summary>
            Kiểm tra mẫu theo giới hạn của nền tảng. Gọi được cả khi chưa lưu (form gọi realtime).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsCreativeService.GetLimits(Lada.Framework.Data.Enums.AdsPlatform)">
            <summary>Giới hạn mẫu quảng cáo của một nền tảng — form đếm ký tự theo object này</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsCreativeService.CreateFromMarketingContentAsync(System.Guid,Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeFromContentModel,System.Int32,System.String)">
            <summary>
            Gợi ý mẫu quảng cáo từ nội dung AI Marketing.
            Chỉ nhận nội dung đã duyệt (Approved / Published) — không quảng cáo bản nháp chưa ai đọc.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsCreativeService.CreateFromPostAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeFromContentModel,System.Int32,System.String)">
            <summary>
            Gợi ý mẫu quảng cáo từ bài viết CMS. Final URL dựng từ slug của bài nếu không truyền vào.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsCreativeService.SuggestText(System.String,System.Int32)">
            <summary>
            Rút gọn một đoạn text cho vừa giới hạn ký tự, cắt theo ranh giới từ.
            Không bao giờ cắt âm thầm — kết quả luôn kèm cờ <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsTextSuggestion.IsTruncated"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsCreativeService.GetEntityAsync(System.Guid)">
            <summary>Lấy entity kèm quan hệ — dùng nội bộ backend khi publish</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeSuggestionResult">
            <summary>
            Kết quả tạo gợi ý mẫu quảng cáo từ nội dung nguồn.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeSuggestionResult.Suggestion">
            <summary>Gợi ý để wizard hiển thị (luôn có khi thành công)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeSuggestionResult.CreativeId">
            <summary>Id mẫu đã lưu — chỉ có khi <c>SaveAsCreative = true</c></summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService">
            <inheritdoc />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.SiteBaseUrlConfigKey">
            <summary>Khoá cấu hình domain website — dùng dựng Final URL cho bài viết CMS</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.DefaultSiteBaseUrl">
            <summary>Domain mặc định khi cấu hình chưa khai</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.GetByIdAsync(System.Guid)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.GetEntityAsync(System.Guid)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeModel,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.DeleteAsync(System.Guid,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.GetLimits(Lada.Framework.Data.Enums.AdsPlatform)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.Validate(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeModel,Lada.Framework.Data.Enums.AdsPlatform)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.CreateFromMarketingContentAsync(System.Guid,Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeFromContentModel,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.CreateFromPostAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeFromContentModel,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.FinalizeSuggestionAsync(Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeSuggestionItem,Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeFromContentModel,System.Int32,System.String)">
            <summary>
            Lưu gợi ý thành mẫu nếu người dùng yêu cầu, đồng thời trả gợi ý cho wizard hiển thị.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.AddSuggestionNotes(Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsCreativeSuggestionItem,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativeLimits,System.Collections.Generic.List{System.String})">
            <summary>
            Bổ sung ghi chú khi số lượng gợi ý chưa đủ mức tối thiểu của nền tảng,
            hoặc có đoạn text phải rút gọn — để người dùng biết chỗ cần sửa tay.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.BuildHeadlineSources(System.String,System.String)">
            <summary>
            Tiêu đề nguồn: tiêu đề nội dung + các câu ngắn tách ra từ phần mô tả ngắn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.BuildDescriptionSources(System.String,System.String,System.String)">
            <summary>
            Mô tả nguồn: meta description, mô tả ngắn, rồi các câu đầu của nội dung chính.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.SuggestText(System.String,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.TruncateAtWordBoundary(System.String,System.Int32)">
            <summary>
            Cắt text tại ranh giới từ gần nhất trước giới hạn.
            Cắt giữa từ tiếng Việt ra chuỗi vô nghĩa nên thà bỏ cả từ cuối;
            nếu từ đầu tiên đã dài quá giới hạn thì mới cắt cứng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.SplitSentences(System.String)">
            <summary>
            Tách một đoạn văn thành các câu, bỏ câu quá ngắn (không dùng làm tiêu đề được).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.StripHtml(System.String)">
            <summary>
            Bỏ thẻ HTML để lấy text thuần từ nội dung bài viết.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.BuildPostUrl(System.String)">
            <summary>
            Dựng URL bài viết từ slug và domain trong cấu hình.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsCreativeService.TrimName(System.String)">
            <summary>Tên mẫu bị giới hạn 500 ký tự trong DB</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsGroupService">
            <summary>
            Đọc nhóm quảng cáo và các quảng cáo bên trong nó.
            <para>
            Service này <b>chỉ đọc</b>. Bật/tắt một quảng cáo hay một nhóm là thao tác tiêu tiền và đã
            có sẵn ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsPublishService.SetStatusAsync(Lada.Framework.Data.Enums.AdsEntityLevel,System.Guid,Lada.Framework.Data.Enums.AdsEntityStatus,System.Int32,System.String)"/> (endpoint
            <c>api/ads/campaign/ad/{adId}/status</c> và <c>api/ads/campaign/group/{groupId}/status</c>,
            quyền <c>Ads.Publish</c>) — cố ý không làm lại ở đây để chỉ có một đường ghi.
            </para>
            <para>
            Quảng cáo có <see cref="P:Lada.Framework.Data.Domains.Ads.AdsItem.AdsCreativeId"/> = <c>null</c> là quảng cáo <b>đồng bộ về từ
            nền tảng</b>, LADA không quản mẫu của nó. Đó là dữ liệu chỉ đọc hợp lệ, không phải bản ghi
            thiếu dữ liệu — UI phải hiển thị khác đi chứ không báo lỗi.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsGroupService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Threading.CancellationToken)">
            <summary>Tìm kiếm nhóm quảng cáo có phân trang.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsGroupService.GetDetailAsync(System.Guid,System.Threading.CancellationToken)">
            <summary>
            Chi tiết một nhóm: thông tin nhóm (kèm 3 số đếm con), bối cảnh chiến dịch / tài khoản,
            và năng lực nền tảng để UI biết ẩn tab nào.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsGroupService.GetAdsAsync(System.Guid,System.Nullable{System.DateOnly},System.Nullable{System.DateOnly},System.Threading.CancellationToken)">
            <summary>
            Danh sách quảng cáo trong một nhóm, kèm số liệu gộp trong khoảng ngày
            (mặc định 30 ngày gần nhất).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsGroupService.GetSummaryAsync(System.Guid,System.Nullable{System.DateOnly},System.Nullable{System.DateOnly},System.Threading.CancellationToken)">
            <summary>Số liệu tổng hợp của nhóm trong khoảng ngày.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsGroupService.FillChildCountsAsync(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem},System.Threading.CancellationToken)">
            <summary>
            Điền 3 số đếm con (<c>AdCount</c>, <c>KeywordCount</c>, <c>NegativeKeywordCount</c>) cho
            một danh sách nhóm bằng <b>hai</b> truy vấn gộp, không phải mỗi nhóm một truy vấn.
            <para>
            AutoMapper không map được các số này (entity không mang sẵn) nên chúng mặc định là 0.
            Mọi chỗ trả <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem"/> ra UI phải gọi hàm này, nếu không bảng sẽ hiện
            "0 quảng cáo" cho nhóm thật ra có quảng cáo — sai theo hướng người dùng tin luôn.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsGroupService">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsGroupService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsGroupService.FillParentNamesAsync(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem},System.Threading.CancellationToken)">
            <summary>
            Điền tên chiến dịch / tài khoản / chiến lược thầu cho <b>trang hiện tại</b>.
            <para>
            Chạy SAU khi đã cắt trang (cùng nếp với số liệu chiến dịch ở plan §3.6): join trước phân
            trang thì trần 149 nhóm hôm nay không sao, nhưng luật sẽ sai ngay khi số nhóm lớn lên.
            Một truy vấn cho cả trang, không phải mỗi dòng một lượt.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsGroupService.GetDetailAsync(System.Guid,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsGroupService.GetAdsAsync(System.Guid,System.Nullable{System.DateOnly},System.Nullable{System.DateOnly},System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsGroupService.GetSummaryAsync(System.Guid,System.Nullable{System.DateOnly},System.Nullable{System.DateOnly},System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsGroupService.FillChildCountsAsync(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsGroupItem},System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueCandidate">
            <summary>
            Một việc cần xử lý <b>trước</b> khi trừ bỏ qua — đơn vị nhỏ nhất, gắn với đúng một bản ghi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueCandidate.Fingerprint">
            <summary>Băm nội dung việc — so với <c>AdsIssueDismissal.Fingerprint</c> để biết bỏ qua còn đúng không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueCandidate.KindCounts">
            <summary>Riêng lệch lịch: số khung theo <c>Kind</c>, để đặt tiêu đề nhóm cho đúng nghĩa</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueSource">
            <summary>Dữ liệu đầu vào đã tải sẵn — classifier là hàm thuần, không chạm repository</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueSource.Accounts">
            <summary>Mọi tài khoản chưa xoá — dùng cả để tra tên cho chiến dịch, nên KHÔNG lọc trước</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueSource.Campaigns">
            <summary>
            Chiến dịch đang <c>Failed</c> hoặc <c>OutOfSync</c>, <b>đã lọc ở SQL</b> theo nền tảng / tài khoản
            (rẻ hơn tải hết) — classifier không lọc lại danh sách này.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueSource.LatestMetricDate">
            <summary><c>max(AdsMetricDaily.Date)</c> cấp chiến dịch trong phạm vi lọc; null = chưa có dòng nào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueSource.HasPublishedCampaign">
            <summary>Có chiến dịch nào đã đẩy lên nền tảng trong phạm vi lọc — chưa có thì "chưa có số liệu" là đương nhiên, không phải việc</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueSource.Platform">
            <summary>Bộ lọc áp cho kết nối / tài khoản / số liệu (chiến dịch đã lọc ở SQL)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueClassifier">
            <summary>
            Phân loại "việc cần xử lý" của phân hệ quảng cáo thành 6 loại (plan §3.4) và gộp theo loại.
            <para>
            <b>Hàm thuần</b>, tách khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueService"/> để test bằng dữ liệu giả không cần
            repository — cùng lý do với <c>AdsScheduleDiff</c>.
            </para>
            <para>
            Cột <c>AdsCampaign.OutOfSyncDetailJson</c> không có schema cố định: reconcile lịch ghi mảng
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftItem"/>, còn đồng bộ chiến dịch / sửa tay ghi mảng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsOutOfSyncField"/>
            — hai luồng ghi đè nhau. Vì vậy lệch lịch bắt theo <b>có <c>Window</c></b>, lệch trường theo
            <b>có <c>Field</c></b>; không so tên <c>Kind</c> — Việc 0 GĐ C đo được cả 3 giá trị của
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftKind"/> trong dữ liệu thật, mà plan ban đầu chỉ ghi một.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueClassifier.AccountStaleDays">
            <summary>Tài khoản đang bật mà quá ngần này ngày chưa kéo lại từ nền tảng</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueClassifier.MetricsStaleDays">
            <summary>Số liệu mới nhất cũ hơn hôm nay − ngần này ngày thì báo (cùng ngưỡng với thanh ngữ cảnh)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueClassifier.MetricsEntityId">
            <summary><c>EntityId</c> cố định của việc mức hệ thống "số liệu cũ"</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueClassifier.Classify(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueSource)">
            <summary>Liệt kê mọi việc trong phạm vi lọc, chưa trừ bỏ qua</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueClassifier.BuildGroup(Lada.Framework.Data.Enums.AdsIssueType,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueCandidate},System.Int32)">
            <summary>Gộp các mục đang hiện của một loại thành một dòng panel</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueClassifier.SortKey(Ladaer.BackEnd.Infrastructures.DTO.Items.Ads.AdsIssueGroupItem)">
            <summary>Thứ tự hiện: lỗi trước cảnh báo, trong cùng mức thì theo số của loại</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueClassifier.Fingerprint(System.String)">
            <summary>SHA-256 rút gọn còn 32 ký tự hex — đủ để phát hiện nội dung đổi, ngắn để làm cột index</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueClassifier.CampaignEntityId(System.Guid)">
            <summary>Guid chiến dịch ở dạng chuỗi chuẩn (chữ thường, có gạch) để so khớp ổn định</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueClassifier.NormalizeEntityId(System.String)">
            <summary>Chuẩn hoá Id client gửi lên về đúng dạng classifier sinh ra</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueClassifier.NormalizeMessage(System.String)">
            <summary>
            Thông điệp lỗi nền tảng thường kèm request-id / thời điểm / số lần thử khác nhau mỗi lần gọi; băm nguyên
            văn thì bỏ qua vô hiệu ngay lần probe kế tiếp dù lỗi không đổi. Xoá các cụm số / hex dài trước khi băm.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueClassifier.ConnectionStatusLabel(Lada.Framework.Data.Enums.AdsConnectionStatus)">
            <summary>Nhãn [Description] của trạng thái kết nối, kèm việc phải làm khi token hết hạn</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueClassifier.PlatformLabel(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueCandidate})">
            <summary>Tên nền tảng ([Description]) khi cả nhóm cùng một nền tảng; lẫn lộn hoặc chưa rõ thì nói chung "nền tảng"</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueClassifier.ParseDrift(System.String)">
            <summary>
            Đọc <c>OutOfSyncDetailJson</c> bao dung: mảng gốc, phần tử có <c>Window</c> là <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftItem"/>
            (reconcile lịch ghi), có <c>Field</c> là <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsOutOfSyncField"/> (đồng bộ chiến dịch ghi);
            JSON hỏng thì <c>Readable = false</c> chứ không ném.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsIssueService">
            <summary>
            "Việc cần xử lý" của phân hệ quảng cáo: liệt kê đã gộp theo loại, bỏ qua có thời hạn, hiện lại.
            <para>
            Phân loại nằm ở <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueClassifier"/> (hàm thuần); lớp này chỉ tải dữ liệu, trừ các
            mục đã bỏ qua còn hạn <b>và</b> khớp fingerprint, rồi gộp. Bỏ qua <b>không</b> chạm
            <c>AdsCampaign</c> hay dữ liệu đồng bộ nào (plan §1.3) — chỉ ghi <c>AdsIssueDismissal</c>.
            </para>
            <para>
            Một mục = <b>một</b> dòng <c>AdsIssueDismissal</c> suốt đời: bỏ qua lại thì cập nhật dòng cũ, hiện
            lại thì đặt <c>ExpiresAt = now</c> (không xoá mềm — hết hạn đã là cơ chế tắt, chồng thêm xoá mềm
            chỉ làm bảng mọc theo số lần bấm và làm mất lịch sử ai bỏ qua / ai hiện lại trên cùng dòng).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsIssueService.ListAsync(System.Nullable{Lada.Framework.Data.Enums.AdsPlatform},System.Nullable{System.Int32},System.Threading.CancellationToken)">
            <summary>
            Mọi loại việc còn mục (đang hiện hoặc đang bị bỏ qua), sắp lỗi trước cảnh báo.
            Lọc theo nền tảng / tài khoản là tuỳ chọn; bỏ trống = toàn hệ thống.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsIssueService.DismissAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsIssueDismissModel,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Bỏ qua một lô mục cùng loại trong N ngày. Hàng rào plan §3.9: từng Id phải là một việc đang
            tồn tại đúng loại — có Id lạ là từ chối cả lô, không âm thầm bỏ phần lạ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsIssueService.UndismissAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsIssueUndismissModel,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>Hiện lại các mục đã bỏ qua của một loại — bỏ trống Id = hiện lại tất cả</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueDismissResult.AffectedCount">
            <summary>Số mục đã bỏ qua / hiện lại</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueService">
            <inheritdoc />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueService.MaxIdsPerRequest">
            <summary>Trần Id mỗi lời gọi bỏ qua / hiện lại — cùng con số với các endpoint nhận danh sách Id khác (§3.9)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueService.DefaultDismissDays">
            <summary>Hạn bỏ qua mặc định (Q1)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Ads.AdsConnection},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Ads.AdsAccount},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Ads.AdsCampaign},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Ads.AdsMetricDaily},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Ads.AdsIssueDismissal},Microsoft.Extensions.Logging.ILogger{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueService},System.TimeProvider)">
            <param name="timeProvider">
            Bỏ trống = giờ hệ thống. Test truyền giờ cố định để các ngưỡng "quá 7 ngày" / "quá 3 ngày"
            không phụ thuộc lúc chạy.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueService.ListAsync(System.Nullable{Lada.Framework.Data.Enums.AdsPlatform},System.Nullable{System.Int32},System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueService.DismissAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsIssueDismissModel,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueService.UndismissAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsIssueUndismissModel,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueService.LoadSourceAsync(System.Nullable{Lada.Framework.Data.Enums.AdsPlatform},System.Nullable{System.Int32},System.DateTimeOffset,System.Threading.CancellationToken)">
            <summary>Nguồn dữ liệu cho liệt kê: kết nối + tài khoản (tải hết, vài chục dòng), chiến dịch có việc lọc ở SQL, mốc số liệu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueService.LoadSourceForDismissAsync(Lada.Framework.Data.Enums.AdsIssueEntityType,System.Collections.Generic.IReadOnlyList{System.String},System.DateTimeOffset,System.Threading.CancellationToken)">
            <summary>
            Nguồn dữ liệu cho bỏ qua: toàn hệ thống nhưng chỉ phần loại này cần — bỏ qua một kết nối
            không cần tải 80 chiến dịch kèm JSON, bỏ qua chiến dịch chỉ cần đúng các Id gửi lên.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueService.HasPublishedCampaignAsync(System.Linq.IQueryable{Lada.Framework.Data.Domains.Ads.AdsCampaign},System.Threading.CancellationToken)">
            <summary>Có chiến dịch nào đã đẩy lên nền tảng chưa — chưa có thì "chưa có số liệu" là chuyện đương nhiên, không phải việc</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueService.LoadLatestMetricDateAsync(System.Nullable{Lada.Framework.Data.Enums.AdsPlatform},System.Nullable{System.Int32},System.Threading.CancellationToken)">
            <summary>Cùng phạm vi với report/metrics-status: chỉ cấp chiến dịch, cùng bộ lọc nền tảng / tài khoản</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsIssueService.LoadActiveDismissalsAsync(System.DateTimeOffset,System.Threading.CancellationToken)">
            <summary>Bỏ qua còn hạn, khoá bộ ba → fingerprint. Trùng khoá (hai request bỏ qua đồng thời) thì lấy bản gần nhất.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry">
            <summary>
            Một từ khoá ở dạng thuần dữ liệu, không phụ thuộc EF hay SDK Google.
            <para>
            Dùng cho cả hai phía của phép so sánh: bên LADA (trạng thái mong muốn) và bên nền tảng
            (trạng thái đang có, đọc về từ <c>FetchKeywordsAsync</c>). Tách khỏi entity để logic diff
            test được mà không cần DB lẫn Google.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry.LocalId">
            <summary>Id dòng bên LADA. <c>null</c> với từ khoá chỉ tồn tại trên nền tảng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry.ExternalId">
            <summary>
            Criterion id bên nền tảng, dạng <b>id trần</b>. <c>null</c> = bản nháp chưa đẩy lên.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry.Level">
            <summary>Cấp của từ khoá — chỉ nhận Campaign hoặc Group</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry.IsNegative">
            <summary>Là từ khoá phủ định (loại trừ) hay từ khoá thường (nhắm chọn)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry.Text">
            <summary>Nội dung từ khoá, <b>không</b> kèm dấu ngoặc biểu thị kiểu khớp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry.MatchType">
            <summary>Kiểu khớp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry.CpcBid">
            <summary>
            Giá thầu CPC riêng của từ khoá. <c>null</c> = dùng giá thầu của nhóm.
            <b>Khác hẳn</b> 0 — 0 là một con số có nghĩa và Google từ chối nó.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry.NormalizedText">
            <summary>
            Nội dung đã chuẩn hoá để so sánh: bỏ khoảng trắng đầu/cuối, gộp khoảng trắng liên tiếp,
            hạ chữ thường.
            <para>
            Google <b>không</b> phân biệt chữ hoa/thường trong từ khoá: thêm "Giày Nam" khi đã có
            "giày nam" sẽ bị nền tảng từ chối vì trùng. So sánh không chuẩn hoá thì LADA tưởng là
            từ khoá mới và cả lô mutate bị Google trả lỗi.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry.WordCount">
            <summary>Số từ trong từ khoá (Google giới hạn 10 từ)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry.IdentityKey">
            <summary>
            Danh tính của từ khoá trên nền tảng.
            <para>
            Google <b>không cho sửa</b> <c>text</c> lẫn <c>match_type</c> của một criterion đã tạo —
            hai thứ đó chính là danh tính của nó: đổi chữ hoặc đổi kiểu khớp = criterion khác, phải
            xoá cái cũ rồi tạo cái mới. Cùng một tính chất bất biến như khung giờ của lịch chạy.
            </para>
            <para>
            Cố ý <b>không</b> đưa nhóm/chiến dịch vào khoá: mỗi lần diff chỉ xử lý <b>một</b> phạm vi
            (một nhóm, hoặc phủ định cấp chiến dịch của một chiến dịch). Đưa vào sẽ làm mọi phép so
            hỏng, vì phía LADA biết id nhóm nội bộ còn phía nền tảng biết id nhóm bên đó.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry.Label">
            <summary>Nhãn tiếng Việt, hiển thị nguyên văn trên hộp xác nhận và thông báo lỗi</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperationKind">
            <summary>Loại thao tác cần thực hiện trên nền tảng</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperationKind.Create">
            <summary>Tạo criterion mới</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperationKind.Update">
            <summary>Cập nhật giá thầu của criterion đã có (text/kiểu khớp không sửa được)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperationKind.Remove">
            <summary>Xoá criterion</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperation">
            <summary>
            Một thao tác trong bản diff từ khoá. Có mô tả tiếng Việt sẵn để hộp xác nhận trên UI
            không phải tự dựng câu — nói sai việc sắp làm là nguyên nhân tiêu tiền oan.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperation.Kind">
            <summary>Loại thao tác</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperation.KindStr">
            <summary>Nhãn loại thao tác cho UI</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperation.LocalId">
            <summary>Id dòng bên LADA (nếu có)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperation.ExternalId">
            <summary>Criterion id bên nền tảng — bắt buộc với Update/Remove</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperation.Keyword">
            <summary>Từ khoá liên quan</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperation.IdentityKey">
            <summary>
            Khoá danh tính, dùng để gắn criterion id nền tảng trả về vào đúng dòng LADA.
            Gắn lệch một dòng thì lần đẩy sau sẽ sửa/xoá sai từ khoá.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperation.CpcBid">
            <summary>Giá thầu sẽ ghi. <c>null</c> nghĩa là <b>xoá giá thầu riêng</b>, quay về giá thầu nhóm.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperation.SetCpcBid">
            <summary>
            Có gán giá trị <c>cpc_bid_micros</c> lên object gửi đi hay không.
            <c>false</c> + mask có <c>cpc_bid_micros</c> = yêu cầu Google xoá giá thầu riêng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperation.FieldMaskPaths">
            <summary>
            Các đường dẫn field mask cần gửi kèm khi Update.
            <para>
            Dựng tay, <b>không</b> dùng <c>FieldMasks.AllSetFieldsOf()</c>: proto3 coi field chưa set
            và 0 là như nhau nên helper đó sẽ bỏ <c>cpc_bid_micros</c> khỏi mask, khiến "xoá giá thầu
            riêng" biến thành không làm gì. Cùng cái bẫy đã ghi ở <c>AdsScheduleOperation</c>.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperation.PreviousCpcBid">
            <summary>Giá thầu hiện có trên nền tảng — chỉ có nghĩa với Update</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordOperation.Description">
            <summary>Mô tả tiếng Việt của thao tác, hiển thị nguyên văn trên hộp xác nhận</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiffResult">
            <summary>
            Kết quả so sánh từ khoá LADA với từ khoá trên nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiffResult.Errors">
            <summary>Các lỗi dữ liệu phát hiện trước khi gọi nền tảng (tiếng Việt)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiffResult.IsValid">
            <summary>Không có lỗi nào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiffResult.Creates">
            <summary>Từ khoá cần tạo mới trên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiffResult.Updates">
            <summary>Từ khoá chỉ đổi giá thầu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiffResult.Removes">
            <summary>Từ khoá cần xoá khỏi nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiffResult.Unchanged">
            <summary>Từ khoá hai bên đã giống nhau — không sinh thao tác nào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiffResult.OperationCount">
            <summary>Tổng số thao tác sẽ gửi lên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiffResult.HasChanges">
            <summary>Có việc phải làm hay không. Không có thì tuyệt đối đừng gọi ra nền tảng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiffResult.NegativeRemoveCount">
            <summary>
            Số từ khoá <b>phủ định</b> sắp bị xoá. UI dùng con số này để nâng mức ma sát:
            xoá từ khoá phủ định là mở cửa cho truy vấn rác, tiền chảy ra ngay mà không có gì báo.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiffResult.AllOperations">
            <summary>Toàn bộ thao tác theo thứ tự gửi: xoá trước, rồi tạo, rồi cập nhật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiffResult.Descriptions">
            <summary>Mô tả tiếng Việt từng thao tác, đúng thứ tự gửi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiffResult.Summary">
            <summary>Câu tóm tắt cho tiêu đề hộp xác nhận</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiff">
            <summary>
            So sánh từ khoá giữa LADA và nền tảng, sinh danh sách thao tác cần ghi.
            <para>
            Toàn bộ lớp này là logic thuần: không chạm DB, không chạm SDK Google. Nhờ vậy phần dễ sai
            nhất của luồng ghi được test đầy đủ trước khi có bất kỳ lệnh gọi ra ngoài.
            </para>
            <para>
            Quy tắc ánh xạ: <c>text</c> và <c>match_type</c> của criterion là <b>bất biến</b> — đổi một
            trong hai phải xoá rồi tạo lại; chỉ <c>cpc_bid_micros</c> là sửa được tại chỗ. Xem
            https://developers.google.com/google-ads/api/fields/v21/ad_group_criterion
            </para>
            <para>
            <b>Mỗi lần gọi chỉ xử lý một phạm vi</b>: từ khoá của một nhóm, hoặc từ khoá phủ định cấp
            chiến dịch của một chiến dịch. Trộn nhiều nhóm vào cùng một lần diff sẽ khiến từ khoá trùng
            tên ở hai nhóm bị coi là một.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiff.MaxTextLength">
            <summary>
            Độ dài tối đa của một từ khoá (ký tự). Nguồn: giới hạn Google Ads cho keyword text.
            Cột <c>AdsKeyword.Text</c> để 200 ký tự để còn chỗ cho nền tảng khác nới rộng hơn.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiff.MaxWordCount">
            <summary>Số từ tối đa trong một từ khoá. Nguồn: giới hạn Google Ads cho keyword text.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiff.CpcBidFieldPath">
            <summary>Tên field <c>cpc_bid_micros</c> trong field mask của Google</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiff.MatchTypeMarkers">
            <summary>
            Các ký tự dùng để <b>viết</b> kiểu khớp, không phải phần nội dung từ khoá:
            <c>[từ khoá]</c> = khớp chính xác, <c>"từ khoá"</c> = khớp cụm từ.
            Người dùng gõ kèm dấu này vào ô nội dung thì kiểu khớp bị nói hai lần và lệch nhau —
            bắt lỗi ngay thay vì đẩy lên rồi mới biết.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiff.DescribeMatchType(Lada.Framework.Data.Enums.AdsKeywordMatchType)">
            <summary>Nhãn tiếng Việt của kiểu khớp — dùng trong nhãn và mô tả thao tác</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiff.Validate(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry},System.Int32)">
            <summary>
            Kiểm tra tính hợp lệ của danh sách từ khoá mong muốn trước khi so sánh.
            </summary>
            <param name="desired">Từ khoá mong muốn — các dòng trong LADA</param>
            <param name="maxKeywords">
            Giới hạn số từ khoá của nền tảng (<c>CreativeLimits.MaxKeywordsPerGroup</c>).
            0 = không áp dụng. Đọc từ Capabilities, không hard-code vào đây.
            </param>
            <returns>Danh sách lỗi tiếng Việt; rỗng nghĩa là hợp lệ.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiff.FindDuplicates(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry})">
            <summary>
            Tìm từ khoá trùng nhau (cùng nội dung + cùng kiểu khớp + cùng cấp + cùng loại).
            Nền tảng từ chối cả lô mutate khi có trùng, nên phải bắt trước và nói rõ trùng ở đâu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiff.Compare(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry},System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry})">
            <summary>
            So sánh hai phía và sinh thao tác, <b>không</b> kiểm tra hợp lệ.
            Dùng khi cần biết diff thuần (ví dụ test phân biệt giá thầu null với 0).
            </summary>
            <param name="desired">Từ khoá mong muốn — các dòng trong LADA</param>
            <param name="remote">Từ khoá đang có trên nền tảng, vừa đọc về</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiff.Build(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry},System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry},System.Int32)">
            <summary>
            Kiểm tra hợp lệ rồi so sánh. Có lỗi thì trả về bản diff <b>rỗng</b> kèm lỗi —
            không bao giờ trả thao tác dựa trên dữ liệu đã biết là sai.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiff.DescribeScope(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry)">
            <summary>
            Phần đuôi nói rõ phạm vi ảnh hưởng. Chỉ ghi với cấp chiến dịch, vì đó là chỗ dễ hiểu
            nhầm nhất: một dòng ở đây áp cho <b>mọi nhóm</b> trong chiến dịch.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiff.DescribeBid(System.Nullable{System.Decimal})">
            <summary>Phần đuôi mô tả giá thầu, bỏ hẳn khi dùng giá thầu của nhóm</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiff.FormatBid(System.Nullable{System.Decimal})">
            <summary>Hiển thị giá thầu; không có giá thầu riêng thì nói rõ là theo nhóm, không in "0"</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService">
            <summary>
            Từ khoá và từ khoá phủ định của chiến dịch / nhóm quảng cáo.
            <para>
            Một dòng <see cref="T:Lada.Framework.Data.Domains.Ads.AdsKeyword"/> ánh xạ 1-1 với một criterion kiểu KEYWORD bên nền tảng,
            khớp theo <c>ExternalId</c> (criterion id <b>trần</b>).
            </para>
            <para>
            Luồng ghi cố ý chia làm <b>ba bước tách biệt</b>, vì đổi từ khoá là đổi cấu hình đang tiêu tiền:
            (1) sửa bản nháp trong LADA (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordModel,System.Int32,System.String,System.Threading.CancellationToken)"/>, <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.CreateBulkAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordBulkModel,System.Int32,System.String,System.Threading.CancellationToken)"/>,
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.DeleteAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)"/>) — không gọi ra nền tảng;
            (2) xem trước (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.PreviewApplyAsync(System.Guid,System.Nullable{System.Guid},System.Int32,System.String,System.Threading.CancellationToken)"/>) — tính diff rồi nhờ nền tảng kiểm tra bằng
            <c>validate_only</c>, không ghi gì;
            (3) đẩy thật (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.ApplyToPlatformAsync(System.Guid,System.Nullable{System.Guid},System.Int32,System.String,System.Threading.CancellationToken)"/>) — ghi rồi <b>đọc lại</b> để xác nhận.
            </para>
            <para>
            <b>Mỗi lần đẩy chỉ xử lý một phạm vi</b>: từ khoá của một nhóm, hoặc từ khoá phủ định cấp
            chiến dịch của một chiến dịch. Trộn hai phạm vi vào một lô sẽ khiến từ khoá trùng nội dung ở
            hai nhóm bị coi là một, và làm mô tả trên hộp xác nhận nói sai phạm vi ảnh hưởng.
            </para>
            <para>
            Từ khoá phủ định nằm trong danh sách dùng chung của nền tảng (Google shared set) <b>không</b>
            được LADA đọc về. Chúng vẫn có tác dụng thật, nên UI phải hiện
            <see cref="!:AdsKeywordViewResult.SharedSetNote"/> thay vì để người dùng tưởng danh sách đã đủ.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Threading.CancellationToken)">
            <summary>
            Tìm kiếm từ khoá có phân trang cho bảng danh sách.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.GetContextAsync(System.Guid,System.Nullable{System.Guid},System.Threading.CancellationToken)">
            <summary>
            Bối cảnh của một phạm vi (nhóm nếu có <paramref name="groupId"/>, ngược lại là chiến
            dịch) — năng lực nền tảng, trạng thái publish, số đếm — <b>không kèm danh sách</b>.
            <para>
            Đây là thứ màn hình danh sách phải gọi, cặp với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Threading.CancellationToken)"/> phân trang.
            Mọi con số tính bằng câu đếm gộp dưới DB, không đọc dòng nào lên bộ nhớ.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.GetByCampaignAsync(System.Guid,System.Threading.CancellationToken)">
            <summary>
            Từ khoá trong phạm vi <b>một chiến dịch</b>: phần phủ định là phủ định cấp chiến dịch,
            phần thường là tổng hợp từ khoá của mọi nhóm bên trong (chỉ đọc).
            <para>
            <b>Trả về toàn bộ dòng, không phân trang</b> — chỉ dùng cho luồng cần đủ dữ liệu để tính
            diff. Màn hình danh sách phải dùng <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Threading.CancellationToken)"/> + <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.GetContextAsync(System.Guid,System.Nullable{System.Guid},System.Threading.CancellationToken)"/>.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.GetByGroupAsync(System.Guid,System.Threading.CancellationToken)">
            <summary>
            Từ khoá trong phạm vi <b>một nhóm</b>. Phần phủ định chỉ gồm phủ định của riêng nhóm —
            phủ định cấp chiến dịch nằm ở trang chiến dịch, không trộn vào đây để không ai tưởng
            xoá ở nhóm này là hết ảnh hưởng.
            <para>
            <b>Trả về toàn bộ dòng, không phân trang</b> — xem ghi chú ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.GetByCampaignAsync(System.Guid,System.Threading.CancellationToken)"/>.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.SyncFromPlatformAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Kéo từ khoá từ nền tảng về cho <b>một chiến dịch</b> (cả phủ định cấp chiến dịch và
            từ khoá của mọi nhóm đã đồng bộ): upsert theo <c>ExternalId</c>, soft-delete các dòng
            nền tảng không còn trả về.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordModel,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Tạo / sửa một từ khoá <b>trong LADA</b>. Không gọi ra nền tảng.
            <para>
            Validate qua <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiff.Validate(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordEntry},System.Int32)"/> trên <b>toàn bộ</b> phạm vi sau khi áp
            thay đổi, nên từ khoá trùng bị chặn ngay lúc lưu nháp chứ không đợi nền tảng từ chối cả lô.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.CreateBulkAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordBulkModel,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Thêm nhiều từ khoá một lần bằng danh sách dán vào <b>trong LADA</b>. Không gọi ra nền tảng.
            Dòng trắng bị bỏ, dòng trùng nhau bị gộp và <b>báo rõ số lượng đã gộp</b>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.DeleteAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Xoá một từ khoá <b>trong LADA</b> (soft-delete). Không gọi ra nền tảng.
            <para>
            Dòng đã có <c>ExternalId</c> thì bên nền tảng vẫn còn từ khoá đó cho tới khi đẩy lên —
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.PreviewApplyAsync(System.Guid,System.Nullable{System.Guid},System.Int32,System.String,System.Threading.CancellationToken)"/> sẽ liệt kê nó ở nhóm "Xoá". Với từ khoá phủ định, đây
            chính là chỗ dễ hiểu nhầm nhất: xoá trong LADA <b>chưa</b> mở cửa cho traffic rác,
            bấm đẩy mới mở.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.PreviewApplyAsync(System.Guid,System.Nullable{System.Guid},System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Xem trước những gì sẽ ghi lên nền tảng cho một phạm vi: đọc từ khoá hiện tại từ nền tảng,
            so với LADA, rồi gửi cả lô ở chế độ <c>validate_only</c>.
            <b>Không ghi bất cứ thứ gì</b> lên tài khoản quảng cáo.
            </summary>
            <param name="campaignId">Chiến dịch chứa phạm vi</param>
            <param name="groupId">
            Nhóm cần áp. <c>null</c> = áp <b>từ khoá phủ định cấp chiến dịch</b>.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.ApplyToPlatformAsync(System.Guid,System.Nullable{System.Guid},System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Đẩy từ khoá lên nền tảng thật. <b>Việc này tiêu tiền</b>: thêm từ khoá là mở thêm đường
            hiển thị, xoá từ khoá phủ định là mở cửa cho truy vấn rác — cả hai đều có hiệu lực ngay.
            <para>
            Sau khi ghi xong luôn gọi lại <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsKeywordService.SyncFromPlatformAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)"/> để đọc lại — request
            thành công không đồng nghĩa dữ liệu đúng, chỉ đọc lại mới chắc.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordSyncResult">
            <summary>
            Kết quả một lần đồng bộ từ khoá từ nền tảng về.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordSyncResult.CreatedCount">
            <summary>Số từ khoá mới thêm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordSyncResult.UpdatedCount">
            <summary>Số từ khoá đã cập nhật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordSyncResult.RemovedCount">
            <summary>Số từ khoá bị bỏ (nền tảng không còn trả về)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordSyncResult.SkippedCount">
            <summary>
            Số từ khoá nền tảng trả về nhưng nhóm cha chưa có trong LADA nên bị bỏ qua.
            Đếm riêng và nói rõ trong thông báo — im lặng thì người dùng tưởng danh sách đã đủ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordSyncResult.TotalCount">
            <summary>Tổng số dòng nền tảng trả về</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordApplyResult">
            <summary>
            Kết quả một lần xem trước / đẩy từ khoá lên nền tảng.
            <para>
            Luôn trả kèm <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordApplyResult.Operations"/> để hộp xác nhận trên UI nói đúng <b>sẽ đổi gì</b> —
            nói sai việc sắp làm là nguyên nhân tiêu tiền oan.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordApplyResult.IsPreview">
            <summary>Đây là lần chạy thử (validate_only) chứ không phải ghi thật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordApplyResult.HasChanges">
            <summary>Có thay đổi nào cần đẩy lên hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordApplyResult.Summary">
            <summary>Câu tóm tắt: sẽ thêm mấy, đổi giá thầu mấy, xoá mấy từ khoá</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordApplyResult.Operations">
            <summary>Mô tả tiếng Việt từng thao tác, đúng thứ tự sẽ gửi lên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordApplyResult.ValidationErrors">
            <summary>Lỗi dữ liệu phát hiện trước khi gọi nền tảng (trùng, quá dài, quá nhiều từ…)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordApplyResult.PlatformAccepted">
            <summary>Nền tảng đã kiểm tra và chấp nhận lô thay đổi này</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordApplyResult.PlatformErrorCode">
            <summary>Mã lỗi gốc của nền tảng — giữ nguyên để tra tài liệu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordApplyResult.NegativeRemoveCount">
            <summary>
            Số từ khoá <b>phủ định</b> trong lô sắp xoá. UI dùng để nâng mức ma sát của hộp xác nhận:
            xoá phủ định là mở cửa cho truy vấn rác, tiền chảy ra ngay mà không có gì báo.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordApplyResult.ScopeStr">
            <summary>
            Phạm vi của lô: tên nhóm, hoặc "cấp chiến dịch". Hiện nguyên văn trên hộp xác nhận để
            người bấm biết chắc mình đang đổi chỗ nào.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordApplyResult.Items">
            <summary>
            Từ khoá <b>đọc lại từ nền tảng</b> sau khi ghi. Đây là sự thật, không phải payload đã gửi.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService">
            <inheritdoc />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.SharedSetNote">
            <summary>
            Ghi chú cố định về danh sách phủ định dùng chung. Hiện <b>luôn</b> trên tab từ khoá phủ
            định: LADA không đọc shared set nên danh sách ở đây có thể chưa đủ, và người dùng không
            được tưởng ngược lại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.GetContextAsync(System.Guid,System.Nullable{System.Guid},System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.GetByCampaignAsync(System.Guid,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.GetByGroupAsync(System.Guid,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.BuildContext``1(Lada.Framework.Data.Domains.Ads.AdsCampaign,Lada.Framework.Data.Domains.Ads.AdsGroup)">
            <summary>
            Phần bối cảnh dùng chung: định danh phạm vi, năng lực nền tảng, trạng thái publish.
            Năng lực đọc từ Capabilities chứ không để frontend tự đoán — nền tảng không có khái niệm
            từ khoá thì UI ẩn hẳn tab, không hiện tab rỗng.
            <para>
            Cố ý <b>không</b> đụng tới số đếm: nơi gọi tự tính, hoặc bằng câu đếm gộp
            (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.GetContextAsync(System.Guid,System.Nullable{System.Guid},System.Threading.CancellationToken)"/>), hoặc từ danh sách đã có sẵn (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.BuildView(Lada.Framework.Data.Domains.Ads.AdsCampaign,Lada.Framework.Data.Domains.Ads.AdsGroup,System.Collections.Generic.List{Lada.Framework.Data.Domains.Ads.AdsKeyword})"/>).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.BuildContext(Lada.Framework.Data.Domains.Ads.AdsCampaign,Lada.Framework.Data.Domains.Ads.AdsGroup)">
            <inheritdoc cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.BuildContext``1(Lada.Framework.Data.Domains.Ads.AdsCampaign,Lada.Framework.Data.Domains.Ads.AdsGroup)"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.BuildView(Lada.Framework.Data.Domains.Ads.AdsCampaign,Lada.Framework.Data.Domains.Ads.AdsGroup,System.Collections.Generic.List{Lada.Framework.Data.Domains.Ads.AdsKeyword})">
            <summary>
            Dựng bọc dữ liệu đầy đủ cho luồng cần cả danh sách: bối cảnh + mọi dòng của phạm vi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.EscapeLikePattern(System.String)">
            <summary>
            Vô hiệu hoá ký tự đại diện của LIKE trong chuỗi người dùng gõ, để tìm "50%" ra đúng
            "50%" chứ không thành khớp mọi thứ bắt đầu bằng "50".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.SyncFromPlatformAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.ApplyRemote(Lada.Framework.Data.Domains.Ads.AdsKeyword,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto,Lada.Framework.Data.Domains.Ads.AdsGroup,System.Boolean,System.DateTimeOffset,System.Int32,System.String)">
            <summary>
            Chép dữ liệu nền tảng vào entity.
            <para>
            <paramref name="keepLocalEdit"/> = true thì chỉ nhận về các field do <b>nền tảng</b> quyết
            định (trạng thái duyệt, điểm chất lượng, id) và ghi chỗ lệch vào
            <c>OutOfSyncDetailJson</c>; nội dung người dùng đang soạn được giữ nguyên.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.BuildOutOfSyncDetail(Lada.Framework.Data.Domains.Ads.AdsKeyword,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordDto)">
            <summary>
            Ghi lại chỗ lệch giữa LADA và nền tảng để UI chỉ đúng field nào khác nhau.
            JSON hỏng thì trả null — một bản ghi lỗi không được làm sập cả lần đồng bộ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordModel,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.CreateBulkAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsKeywordBulkModel,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.DeleteAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.PreviewApplyAsync(System.Guid,System.Nullable{System.Guid},System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.ApplyToPlatformAsync(System.Guid,System.Nullable{System.Guid},System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.ApplyCoreAsync(System.Guid,System.Nullable{System.Guid},System.Int32,System.String,System.Boolean,System.Threading.CancellationToken)">
            <summary>
            Một đường code duy nhất cho cả xem trước và ghi thật — hai đường song song sẽ lệch nhau,
            và chỗ lệch nằm đúng trên đường tiêu tiền.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.LoadCampaignAsync(System.Guid,System.Threading.CancellationToken)">
            <summary>
            Chiến dịch kèm tài khoản và kết nối — cần cả ba để gọi ra nền tảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.LoadScopeAsync(System.Guid,System.Nullable{System.Guid},System.Threading.CancellationToken)">
            <summary>
            Toàn bộ từ khoá của <b>một phạm vi</b>: cả nhắm mục tiêu và phủ định của một nhóm, hoặc
            từ khoá phủ định cấp chiến dịch. Hai loại nằm cùng một resource bên nền tảng nên phải
            cùng một lô — tách ra sẽ khiến diff của lô này coi dòng của lô kia là "cần xoá".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.LoadScopeItemsAsync(System.Guid,System.Nullable{System.Guid},System.Threading.CancellationToken)">
            <summary>
            Danh sách từ khoá của phạm vi để trả về UI sau khi ghi — đọc lại từ DB chứ không dựng
            từ payload đã gửi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.CheckScopeAsync(Lada.Framework.Data.Domains.Ads.AdsCampaign,System.Nullable{System.Guid},System.Boolean,System.Threading.CancellationToken)">
            <summary>
            Kiểm tra phạm vi hợp lệ: nhóm có tồn tại, thuộc đúng chiến dịch, và cấp chiến dịch chỉ
            nhận từ khoá phủ định.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.CheckCapability(Lada.Framework.Data.Domains.Ads.AdsCampaign,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities,System.Boolean,Lada.Framework.Data.Enums.AdsEntityLevel)">
            <summary>
            Nền tảng có khái niệm từ khoá / phủ định / phủ định cấp chiến dịch hay không.
            Thiếu năng lực thì báo lý do tiếng Việt, không im lặng lưu một dòng vô nghĩa.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.MaxKeywords(Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities,System.Nullable{System.Guid})">
            <summary>
            Giới hạn số từ khoá để đưa vào validate. Chỉ áp cho phạm vi <b>nhóm</b>: giới hạn của
            nền tảng là giới hạn mỗi nhóm, đem áp cho danh sách phủ định cấp chiến dịch sẽ báo lỗi
            sai chỗ. Trả 0 = không kiểm số lượng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.ToEntry(Lada.Framework.Data.Domains.Ads.AdsKeyword)">
            <summary>Entity sang một dòng để so sánh — nơi duy nhất quyết định cách chuẩn hoá.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.NewEntry(Lada.Framework.Data.Enums.AdsEntityLevel,System.Boolean,System.String,Lada.Framework.Data.Enums.AdsKeywordMatchType,System.Nullable{System.Decimal})">
            <summary>Dòng so sánh cho một từ khoá chưa có trong DB.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.NewEntity(Lada.Framework.Data.Domains.Ads.AdsCampaign,System.Nullable{System.Guid},Lada.Framework.Data.Enums.AdsEntityLevel,System.Boolean,System.String,Lada.Framework.Data.Enums.AdsKeywordMatchType,System.Nullable{System.Decimal},System.DateTimeOffset,System.Int32,System.String)">
            <summary>
            Dựng entity mới cho một từ khoá nháp.
            <para>
            <see cref="P:Lada.Framework.Data.Domains.Ads.AdsKeyword.MatchType"/> và <see cref="P:Lada.Framework.Data.Domains.Ads.AdsKeyword.Status"/> được gán
            <b>tường minh</b>: mặc định của entity là "Rộng" còn mặc định của model là "Cụm từ",
            để trống ở đây sẽ lưu kiểu khớp khác cái người dùng chọn.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.MarkOutOfSync(Lada.Framework.Data.Domains.Ads.AdsKeyword,System.DateTimeOffset,System.Int32,System.String)">
            <summary>
            Đánh dấu dòng đã lệch với nền tảng sau khi sửa trong LADA. Dòng chưa từng lên nền tảng
            vẫn là nháp (<see cref="F:Lada.Framework.Data.Enums.AdsSyncStatus.Local"/>) — gọi nó là "lệch" sẽ khiến người dùng
            tưởng nền tảng đang chạy một giá trị khác.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.MarkSynced(Lada.Framework.Data.Domains.Ads.AdsKeyword,System.DateTimeOffset,System.Int32,System.String)">
            <summary>Đánh dấu dòng đã khớp nền tảng sau khi ghi thành công.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.MarkErrorAsync(System.Collections.Generic.List{Lada.Framework.Data.Domains.Ads.AdsKeyword},System.String,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Ghi lý do lỗi vào từng dòng trong phạm vi để người dùng thấy ngay trên bảng, không phải
            mở log mới biết vì sao lần đẩy vừa rồi không có tác dụng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.BuildRequestLog(Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsKeywordApplyRequest,Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordDiffResult,System.Boolean)">
            <summary>
            Nội dung request để lưu log: đủ để sau này dựng lại chính xác đã gửi gì lên nền tảng.
            Serialize lỗi thì trả bản tối giản chứ không để trống — mất log là mất khả năng truy vết
            một lần ghi đã tiêu tiền.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsKeywordService.LogAsync(Lada.Framework.Data.Domains.Ads.AdsCampaign,Lada.Framework.Data.Domains.Ads.AdsAccount,System.Boolean,System.String,System.String,System.Int64,System.Int32,System.Int32,System.String,System.String,Lada.Framework.Data.Enums.AdsSyncDirection,System.String,System.String,System.String,Lada.Framework.Data.Enums.AdsEntityLevel,System.Nullable{System.Guid})">
            <summary>
            Ghi một dòng log gọi nền tảng. Mọi payload đi qua
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsSyncLogService"/> nên token được che trước khi lưu.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricAggregator">
            <summary>
            Gộp số liệu quảng cáo theo ngày thành một bản tổng hợp. <b>Thuần logic</b> — không chạm
            database, không chạm SDK nền tảng — nên gọi được trực tiếp từ unit test.
            <para>
            Tách ra khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService"/> vì công thức này giờ có <b>ba</b> nơi dùng:
            tổng hợp cấp chiến dịch, số liệu từng quảng cáo trong nhóm, và số liệu từng từ khoá.
            Chép công thức ra ba chỗ là cách chắc chắn để ba chỗ lệch nhau sau vài lần sửa.
            </para>
            <para>
            <b>Nguyên tắc không được phá:</b> mọi chỉ số dạng tỉ lệ (CTR, CPC, CPA, ROAS) đều tính lại
            từ <b>tổng</b> của tử số và tổng của mẫu số. Lấy trung bình cột tỉ lệ của từng ngày cho ra
            số khác hẳn khi lượng hiển thị các ngày lệch nhau — và sai theo hướng khó phát hiện, vì con
            số vẫn "trông hợp lý".
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricAggregator.Summarize(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Ads.AdsMetricDaily},System.DateOnly,System.DateOnly)">
            <summary>
            Gộp danh sách dòng số liệu theo ngày thành một bản tổng hợp cho khoảng [from, to].
            Trả <c>null</c> khi không có dòng nào — "chưa có dữ liệu" khác hẳn "có dữ liệu và bằng 0",
            nên không trả về một bản tổng hợp toàn số 0.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricAggregator.SummarizeByEntity(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Ads.AdsMetricDaily},System.DateOnly,System.DateOnly)">
            <summary>
            Gộp số liệu cho <b>nhiều đối tượng cùng lúc</b>, trả về map theo <c>EntityId</c>.
            <para>
            Dùng cho bảng danh sách (từng quảng cáo, từng từ khoá): một truy vấn cho cả trang rồi
            gộp trong bộ nhớ, thay vì gọi <c>GetSummaryAsync</c> mỗi dòng — 500 từ khoá là 500 lượt
            truy vấn.
            </para>
            <para>
            Đối tượng không có dòng số liệu nào <b>không</b> xuất hiện trong map. Chỗ gọi dùng
            <c>TryGetValue</c> và để <c>Metrics = null</c>, giữ đúng phân biệt "chưa có dữ liệu".
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricAggregator.SafeRatio(System.Int64,System.Int64)">
            <summary>
            Chia an toàn cho tỉ lệ dạng số nguyên / số nguyên. Mẫu số 0 trả 0 chứ không ném lỗi:
            một từ khoá chưa có lượt hiển thị là chuyện bình thường, không phải lỗi dữ liệu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricAggregator.SafeDivide(System.Decimal,System.Int64)">
            <summary>Chia an toàn cho chi phí / số lượt. Mẫu số 0 trả 0.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricAggregator.DistinctCurrencies(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Ads.AdsMetricDaily})">
            <summary>Các mã tiền tệ khác nhau xuất hiện trong tập số liệu (bỏ qua giá trị rỗng).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsMetricService">
            <summary>
            Đồng bộ và tổng hợp số liệu quảng cáo theo ngày.
            Job đồng bộ sẽ chạy lại trên cùng khoảng ngày nên mọi thao tác ghi đều là upsert
            theo khoá (Level, EntityId, Date) — chạy 10 lần vẫn ra đúng một bản ghi mỗi ngày.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsMetricService.SyncMetricsAsync(System.Int32,System.DateOnly,System.DateOnly,Lada.Framework.Data.Enums.AdsMetricLevel,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Kéo số liệu của một tài khoản trong khoảng ngày về LADA ở cấp <paramref name="level"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsMetricService.GetSummaryAsync(Lada.Framework.Data.Enums.AdsMetricLevel,System.Guid,System.DateOnly,System.DateOnly)">
            <summary>
            Số liệu tổng hợp của một đối tượng canonical trong khoảng ngày.
            Trả null khi chưa có dữ liệu nào — UI hiển thị "chưa đồng bộ số liệu" thay vì toàn số 0.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsMetricService.GetAccountSummaryAsync(System.Int32,System.DateOnly,System.DateOnly)">
            <summary>
            Số liệu tổng hợp của cả một tài khoản quảng cáo ở cấp chiến dịch.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsMetricService.GetOverviewAsync(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricFilter)">
            <summary>
            Số liệu tổng quan cho trang chủ phân hệ, kèm kỳ liền trước để so sánh tăng/giảm.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsMetricService.GetMetricsStatusAsync(System.Nullable{Lada.Framework.Data.Enums.AdsPlatform},System.Nullable{System.Int32})">
            <summary>
            Số liệu đã về tới ngày nào và đồng bộ lần cuối lúc nào — cho thanh ngữ cảnh.
            Lọc theo nền tảng / tài khoản như các báo cáo khác nhưng KHÔNG theo khoảng ngày.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsMetricService.GetTimeSeriesAsync(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricFilter,Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricGroupBy)">
            <summary>
            Chuỗi số liệu theo thời gian để vẽ biểu đồ, gộp theo ngày / tuần / tháng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsMetricService.GetByPlatformAsync(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricFilter)">
            <summary>
            Số liệu gộp theo từng nền tảng quảng cáo, sắp giảm dần theo chi phí.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsMetricService.GetTopCampaignsAsync(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricFilter,System.String,System.Int32)">
            <summary>
            Xếp hạng chiến dịch theo một chỉ số trong khoảng ngày.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsMetricService.SyncAllActiveAccountsAsync(System.DateOnly,System.DateOnly,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Đồng bộ số liệu cho mọi tài khoản đang bật đồng bộ định kỳ.
            Một tài khoản lỗi không làm hỏng cả lượt — phần lỗi được gom vào thông báo trả về.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricFilter">
            <summary>
            Bộ lọc dùng chung cho các truy vấn đọc số liệu tổng hợp.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricFilter.Platform">
            <summary>Null nghĩa là lấy tất cả nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricFilter.AdsAccountId">
            <summary>Null nghĩa là lấy tất cả tài khoản</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricFilter.DayCount">
            <summary>Số ngày của kỳ, tính cả hai đầu</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricFilter.EnsureValidRange(System.DateOnly,System.DateOnly)">
            <summary>
            Luật khoảng ngày chung cho mọi nơi đọc số liệu theo kỳ (báo cáo tổng quan, cột số liệu của
            bảng chiến dịch…) — một chỗ, một thông điệp. Ném <see cref="T:System.ArgumentException"/> để controller
            trả 400 kèm lý do người dùng đọc được.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricGroupBy">
            <summary>
            Mức gộp thời gian khi vẽ biểu đồ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricSyncResult">
            <summary>
            Kết quả một lần đồng bộ số liệu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricSyncResult.CreatedCount">
            <summary>Số dòng số liệu mới thêm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricSyncResult.UpdatedCount">
            <summary>Số dòng số liệu đã cập nhật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricSyncResult.SkippedCount">
            <summary>
            Số dòng nền tảng trả về nhưng không khớp đối tượng nào trong LADA
            (thường do chưa đồng bộ chiến dịch / nhóm trước).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricSyncResult.TotalCount">
            <summary>Tổng số dòng nền tảng trả về</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService.SyncMetricsAsync(System.Int32,System.DateOnly,System.DateOnly,Lada.Framework.Data.Enums.AdsMetricLevel,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService.SyncAllActiveAccountsAsync(System.DateOnly,System.DateOnly,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService.BuildCanonicalMapAsync(System.Int32,Lada.Framework.Data.Enums.AdsMetricLevel,System.Threading.CancellationToken)">
            <summary>
            Bảng tra ExternalId → Id canonical theo cấp số liệu.
            <para>
            Cấp lạ thì <b>ném lỗi</b> chứ không trả bảng rỗng: bảng rỗng làm mọi dòng nền tảng
            trả về rơi vào <c>SkippedCount</c> và báo "đồng bộ thành công 0 bản ghi" — đúng kiểu
            lỗi im lặng đã từng giấu bug số liệu cấp quảng cáo.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService.GetSummaryAsync(Lada.Framework.Data.Enums.AdsMetricLevel,System.Guid,System.DateOnly,System.DateOnly)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService.GetAccountSummaryAsync(System.Int32,System.DateOnly,System.DateOnly)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService.GetOverviewAsync(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricFilter)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService.GetMetricsStatusAsync(System.Nullable{Lada.Framework.Data.Enums.AdsPlatform},System.Nullable{System.Int32})">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService.GetTimeSeriesAsync(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricFilter,Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricGroupBy)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService.GetByPlatformAsync(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricFilter)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService.GetTopCampaignsAsync(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricFilter,System.String,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService.QueryByFilter(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricFilter)">
            <summary>
            Truy vấn số liệu theo bộ lọc chung.
            Luôn giới hạn ở cấp chiến dịch: cấp nhóm và cấp quảng cáo là số liệu chi tiết của
            cùng khoản chi đó, gộp lẫn vào sẽ đội chi phí lên nhiều lần.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService.BucketStart(System.DateOnly,Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricGroupBy)">
            <summary>Ngày đầu của mốc gộp chứa <paramref name="date"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService.DistinctCurrencies(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Ads.AdsMetricDaily})">
            <summary>Các mã tiền tệ khác nhau xuất hiện trong tập số liệu (bỏ qua giá trị rỗng).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricService.Summarize(System.Collections.Generic.List{Lada.Framework.Data.Domains.Ads.AdsMetricDaily},System.DateOnly,System.DateOnly)">
            <summary>
            Tính tổng và các chỉ số dẫn xuất.
            <para>
            Công thức nằm ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsMetricAggregator.Summarize(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Ads.AdsMetricDaily},System.DateOnly,System.DateOnly)"/> — thuần logic, không chạm
            database — để trang nhóm quảng cáo, bảng từ khoá và unit test dùng đúng một công thức.
            CTR / CPC / CPA / ROAS tính lại từ tổng, không lấy trung bình cột tỉ lệ.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsEnumDescriptionExtensions">
            <summary>
            Lấy mô tả tiếng Việt của enum, không ném lỗi khi enum chưa khai báo Description.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsNavPermissions">
            <summary>
            Các nút của phân hệ Quảng cáo mà máy chủ gác bằng quyền có được hiện cho một người hay không
            (rule <c>quyen-hien-thi</c>; plan cải tổ giao diện quảng cáo GĐ B, GĐ C).
            </summary>
            <remarks>
            <para>
            <b>Hàm thuần</b> — không chạm database, không đọc <c>HttpContext</c>: nhận danh sách role đã
            phân giải qua <c>IUserRoleResolver</c>, trả các cờ. Cùng khuôn với
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavPermissions"/>, và vì cùng một lý do: luật "ai thấy gì" phải có
            ca test gọi thẳng vào nó, mà controller thì không test được sạch (<c>User.GetCurrentUser()</c>
            nuốt mọi ngoại lệ rồi trả <c>UserId = 0</c>).
            </para>
            <para>
            <b>Cờ đọc đúng bó quyền của thứ nó gác.</b> Nút "Đồng bộ" trên thanh ngữ cảnh gọi
            <c>POST api/ads/report/sync-now</c>, endpoint ấy đòi <c>Ads.Publish</c> (gọi ra nền tảng,
            tốn quota) — không phải <c>Ads.Search</c> của các lời gọi đọc số liệu quanh nó. Lấy bó
            <c>Ads.Search</c> làm cờ là cho người chỉ được xem thấy nút, bấm, và ăn 403.
            </para>
            <para>
            Mỗi cờ một bó quyền, không mượn cờ của bó khác: <c>CanSyncMetrics</c> và <c>CanPublish</c> hiện
            trùng bó <c>Ads.Publish</c> nhưng cố ý tách (một endpoint đổi role thì chỉ một cờ đổi);
            <c>CanDismissIssues</c> gác "bỏ qua việc cần xử lý" (<c>Ads.Update</c> — chỉ ghi trong LADA);
            <c>CanSyncAccounts</c> gác "đồng bộ tài khoản" (<c>Ads.Connection</c> — kéo danh sách tài khoản từ
            kết nối). Ba bó khác nhau cho ba nút cạnh nhau trên cùng một panel.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsNavPermissions.Founder">
            <summary>Vai bỏ qua mọi kiểm tra role của hệ thống — ẩn nút của Founder là dựng hàng rào không có thật.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsNavPermissions.AdsPublish">
            <summary>Role của mọi lời gọi ra nền tảng: <c>report/sync-now</c>, <c>campaign/{id}/publish|pause|resume|budget</c>, <c>schedule/sync-many</c>…</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsNavPermissions.AdsUpdate">
            <summary>Role sửa dữ liệu trong LADA không chạm nền tảng: <c>issue/dismiss</c>, sửa nháp lịch / từ khoá</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsNavPermissions.AdsConnection">
            <summary>Role quản lý kết nối: <c>account/sync/{connectionId}</c>, trang Kết nối</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsNavPermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c>; <c>null</c> = không có role nào</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsNavFlags">
            <summary>Cờ hiển thị của phân hệ quảng cáo — mỗi cờ gác đúng một bó quyền (xem <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsNavPermissions"/>)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsNavFlags.#ctor(System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
            <summary>Cờ hiển thị của phân hệ quảng cáo — mỗi cờ gác đúng một bó quyền (xem <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsNavPermissions"/>)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsPublishService">
            <summary>
            Điều phối việc đẩy chiến dịch từ LADA lên nền tảng quảng cáo.
            Đây là service duy nhất trong module có khả năng làm phát sinh chi phí thật, nên:
            chiến dịch mới luôn tạo ở trạng thái tạm dừng, validate đầy đủ trước khi gọi API,
            và chặn publish lại khi chiến dịch đang đẩy hoặc đã có ExternalId.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsPublishService.GetPublishPreviewAsync(System.Guid)">
            <summary>
            Dựng thông tin cho hộp thoại xác nhận: tài khoản bị trừ tiền, ngân sách,
            thời gian chạy, ước tính chi phí tối đa, kèm danh sách lỗi/cảnh báo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsPublishService.ValidateCampaignAsync(System.Guid,System.Int32,System.String)">
            <summary>
            Gửi chiến dịch sang nền tảng ở chế độ kiểm tra (dry-run): nền tảng validate
            toàn bộ nhưng không tạo gì thật. Không tiêu tiền, không tạo rác.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsPublishService.PublishCampaignAsync(System.Guid,System.Int32,System.String)">
            <summary>
            Đẩy chiến dịch lên nền tảng. Tạo ở trạng thái tạm dừng, người dùng tự bật sau.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsPublishService.UpdateCampaignAsync(System.Guid,System.Int32,System.String)">
            <summary>Đẩy thay đổi (tên, trạng thái, thời gian chạy) của chiến dịch lên nền tảng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsPublishService.SetStatusAsync(Lada.Framework.Data.Enums.AdsEntityLevel,System.Guid,Lada.Framework.Data.Enums.AdsEntityStatus,System.Int32,System.String)">
            <summary>Bật / tạm dừng / xoá một đối tượng ở cấp chiến dịch, nhóm hoặc quảng cáo</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsPublishService.SetStatusManyAsync(System.Collections.Generic.List{System.Guid},Lada.Framework.Data.Enums.AdsEntityStatus,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Bật / tạm dừng <b>nhiều</b> chiến dịch trong một lượt, gọi tuần tự đúng logic của bản lẻ.
            <para>
            Chiến dịch đã ở trạng thái đích → bỏ qua chứ không gọi ra nền tảng: gửi lệnh thừa vừa tốn
            quota vừa làm số "thành công" trông to hơn thật.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsPublishService.SetBudgetAsync(System.Guid,System.Decimal,System.Int32,System.String)">
            <summary>Đổi ngân sách theo ngày của một chiến dịch đã có trên nền tảng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishResult">
            <summary>
            Kết quả một lần đẩy dữ liệu ra nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishResult.ExternalCampaignId">
            <summary>Id chiến dịch bên nền tảng (có sau khi publish thành công)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishResult.ExternalBudgetId">
            <summary>Id ngân sách bên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishResult.PlatformErrorCode">
            <summary>Mã lỗi gốc của nền tảng — giữ nguyên để tra tài liệu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishResult.ValidationErrors">
            <summary>Danh sách lỗi validate trước khi gọi API (tiếng Việt, nói rõ trường nào)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkStatusOutcome">
            <summary>Kết cục của một chiến dịch trong lô đổi trạng thái.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkStatusOutcome.Skipped">
            <summary>Đã ở trạng thái đích, hoặc chưa đẩy lên nền tảng — không phải lỗi</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkStatusItemResult">
            <summary>Kết quả đổi trạng thái của một chiến dịch trong lô.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkStatusResult">
            <summary>
            Kết quả bật / tạm dừng cả lô chiến dịch.
            <para>
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkStatusResult.Rejected"/> là ca lô bị từ chối <b>trước khi chạy</b> (Id lạ, quá trần, rỗng):
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsBulkStatusResult.Items"/> rỗng, controller trả 400. Cùng khuôn với kéo lịch về hàng loạt.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.GetPublishPreviewAsync(System.Guid)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.ValidateCampaignAsync(System.Guid,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.PublishCampaignAsync(System.Guid,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.SaveExternalIdsAsync(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.PublishContext,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMutateResult,System.Int32,System.String)">
            <summary>
            Lưu ExternalId cho cả 4 cấp (ngân sách, chiến dịch, nhóm, quảng cáo).
            Thiếu id ở bất kỳ cấp nào thì lần đồng bộ sau sẽ tạo bản ghi trùng, nên phải lưu đủ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.UpsertAdsItemAsync(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.PublishContext,Lada.Framework.Data.Domains.Ads.AdsGroup,Lada.Framework.Data.Domains.Ads.AdsCreative,System.String,System.DateTimeOffset,System.Int32,System.String)">
            <summary>
            Ghi bản ghi quảng cáo canonical (AdsItem) tương ứng mẫu đã đẩy lên.
            Upsert theo (nhóm, mẫu) để publish lại không sinh bản ghi trùng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.UpdateCampaignAsync(System.Guid,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.SetStatusAsync(Lada.Framework.Data.Enums.AdsEntityLevel,System.Guid,Lada.Framework.Data.Enums.AdsEntityStatus,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.ApplyStatusLocallyAsync(Lada.Framework.Data.Enums.AdsEntityLevel,System.Guid,Lada.Framework.Data.Enums.AdsEntityStatus,System.Int32,System.String)">
            <summary>
            Cập nhật trạng thái canonical sau khi nền tảng đã nhận — chỉ gọi khi nền tảng trả về thành công,
            để trạng thái trong LADA không nói dối về những gì đang chạy thật.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.MaxBulkStatusCampaigns">
            <summary>Trần Id một lô đổi trạng thái — cùng con số với các endpoint nhận danh sách Id khác (plan §3.9)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.SetStatusManyAsync(System.Collections.Generic.List{System.Guid},Lada.Framework.Data.Enums.AdsEntityStatus,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.SetBudgetAsync(System.Guid,System.Decimal,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.LoadContextAsync(System.Guid,System.Boolean)">
            <summary>
            Đọc toàn bộ cây dữ liệu cần cho việc publish: chiến dịch, tài khoản, kết nối,
            nhóm, mẫu quảng cáo, targeting.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.ValidateContext(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.PublishContext,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities)">
            <summary>
            Kiểm tra toàn bộ cây theo <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsPlatformCapabilities"/> của nền tảng đích.
            Mọi con số giới hạn đều lấy từ capabilities — nền tảng khác chỉ cần khai capabilities khác.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.ValidateCreative(Lada.Framework.Data.Domains.Ads.AdsCreative,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCreativeLimits,System.String,System.Collections.Generic.List{System.String})">
            <summary>
            Kiểm tra một mẫu quảng cáo theo giới hạn của nền tảng.
            Trùng logic với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsCreativeService.Validate(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsCreativeModel,Lada.Framework.Data.Enums.AdsPlatform)"/> về mặt luật, nhưng ở đây đọc từ entity
            (đã lưu) chứ không từ model form, và gắn tên nhóm vào thông báo để người dùng biết sửa ở đâu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.BuildPublishRequest(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.PublishContext)">
            <summary>
            Chuyển cây canonical thành yêu cầu publish cho adapter.
            Trạng thái mong muốn luôn là tạm dừng — không có đường nào để tạo chiến dịch đang chạy.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.CalculateRunningDays(System.Nullable{System.DateOnly},System.Nullable{System.DateOnly})">
            <summary>
            Số ngày chạy tính cả ngày đầu và ngày cuối. Null khi chưa có ngày kết thúc.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.ParseJsonList(System.String)">
            <summary>
            Đọc mảng chuỗi lưu dạng JSON. JSON hỏng thì trả rỗng — một bản ghi lỗi
            không nên làm gãy cả luồng publish, và validate sẽ báo thiếu dữ liệu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.LogAsync(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.PublishContext,System.String,System.Object,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsMutateResult,System.Int64,System.Int32,System.String,System.Nullable{Lada.Framework.Data.Enums.AdsEntityLevel},System.Nullable{System.Guid})">
            <summary>
            Ghi log lần gọi ra nền tảng. Hướng Push cho mọi thao tác trong service này.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.SafeSerialize(System.Object)">
            <summary>
            Serialize payload để ghi log. Lỗi serialize không được làm gãy nghiệp vụ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.PublishContext">
            <summary>
            Cây dữ liệu cần cho một lần publish.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsPublishService.PublishGroupNode">
            <summary>
            Một nhóm quảng cáo kèm mẫu và targeting đã parse.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot">
            <summary>
            Một khung giờ quảng cáo ở dạng thuần dữ liệu, không phụ thuộc EF hay SDK Google.
            <para>
            Dùng cho cả hai phía của phép so sánh: bên LADA (trạng thái mong muốn) và
            bên nền tảng (trạng thái đang có, đọc về từ <c>FetchSchedulesAsync</c>).
            Tách khỏi entity để logic diff test được mà không cần DB lẫn Google.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot.LocalId">
            <summary>Id dòng bên LADA. <c>null</c> với khung giờ chỉ tồn tại trên nền tảng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot.ExternalId">
            <summary>Id criterion bên nền tảng. <c>null</c> = bản nháp chưa đẩy lên.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot.DayOfWeek">
            <summary>Thứ trong tuần (theo <see cref="T:System.DayOfWeek"/> của .NET)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot.StartHour">
            <summary>Giờ bắt đầu, 0–23</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot.StartMinute">
            <summary>Phút bắt đầu, chỉ nhận 0/15/30/45</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot.EndHour">
            <summary>Giờ kết thúc, 1–24 (24 = hết ngày)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot.EndMinute">
            <summary>Phút kết thúc, chỉ nhận 0/15/30/45</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot.BidModifier">
            <summary>
            Hệ số điều chỉnh giá thầu theo dạng của Google (1.2 = +20%).
            <c>null</c> = không điều chỉnh — <b>khác hẳn</b> 0.0 (= -100%).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot.StartMinuteOfDay">
            <summary>Mốc phút tính từ đầu ngày của thời điểm bắt đầu — dùng để kiểm tra chồng giờ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot.EndMinuteOfDay">
            <summary>Mốc phút tính từ đầu ngày của thời điểm kết thúc</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot.Label">
            <summary>Nhãn tiếng Việt của khung giờ, dùng trong thông báo lỗi và hộp xác nhận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot.WindowKey">
            <summary>
            Khoá nhận dạng khung thời gian. Google <b>không cho sửa</b> thứ/giờ của một criterion,
            nên khung thời gian chính là danh tính của nó: đổi giờ = criterion khác.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperationKind">
            <summary>Loại thao tác cần thực hiện trên nền tảng</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperationKind.Create">
            <summary>Tạo criterion mới</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperationKind.Update">
            <summary>Cập nhật hệ số giá thầu của criterion đã có</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperationKind.Remove">
            <summary>Xoá criterion</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperation">
            <summary>
            Một thao tác trong bản diff. Có mô tả tiếng Việt sẵn để hộp xác nhận trên UI
            không phải tự dựng câu — nói sai việc sắp làm là nguyên nhân tiêu tiền oan.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperation.Kind">
            <summary>Loại thao tác</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperation.KindStr">
            <summary>Nhãn loại thao tác cho UI</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperation.LocalId">
            <summary>Id dòng bên LADA (nếu có)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperation.ExternalId">
            <summary>Id criterion bên nền tảng — bắt buộc với Update/Remove</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperation.Slot">
            <summary>Khung giờ liên quan</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperation.BidModifier">
            <summary>
            Giá trị hệ số giá thầu sẽ ghi. <c>null</c> nghĩa là <b>xoá điều chỉnh</b>
            (bỏ trống field nhưng vẫn đưa <c>bid_modifier</c> vào field mask).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperation.SetBidModifier">
            <summary>
            Có gán giá trị <c>bid_modifier</c> lên object gửi đi hay không.
            <c>false</c> + mask có <c>bid_modifier</c> = yêu cầu Google xoá điều chỉnh.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperation.FieldMaskPaths">
            <summary>
            Các đường dẫn field mask cần gửi kèm khi Update.
            <para>
            Dựng tay, <b>không</b> dùng <c>FieldMasks.AllSetFieldsOf()</c>: proto3 coi field
            chưa set và 0.0 là như nhau nên helper đó sẽ bỏ <c>bid_modifier</c> khỏi mask,
            khiến cả "xoá điều chỉnh" và "đặt -100%" đều biến thành không làm gì.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperation.PreviousBidModifier">
            <summary>Giá trị hệ số hiện có trên nền tảng — chỉ có nghĩa với Update</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleOperation.Description">
            <summary>Mô tả tiếng Việt của thao tác, hiển thị nguyên văn trên hộp xác nhận</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiffResult">
            <summary>
            Kết quả so sánh lịch LADA với lịch nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiffResult.Errors">
            <summary>Các lỗi dữ liệu phát hiện trước khi gọi nền tảng (tiếng Việt)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiffResult.IsValid">
            <summary>Không có lỗi nào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiffResult.Creates">
            <summary>Khung giờ cần tạo mới trên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiffResult.Updates">
            <summary>Khung giờ chỉ đổi hệ số giá thầu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiffResult.Removes">
            <summary>Khung giờ cần xoá khỏi nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiffResult.Unchanged">
            <summary>Khung giờ hai bên đã giống nhau — không sinh thao tác nào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiffResult.OperationCount">
            <summary>Tổng số thao tác sẽ gửi lên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiffResult.HasChanges">
            <summary>Có việc phải làm hay không. Không có thì tuyệt đối đừng gọi ra Google.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiffResult.AllOperations">
            <summary>Toàn bộ thao tác theo thứ tự gửi: xoá trước, rồi tạo, rồi cập nhật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiffResult.Descriptions">
            <summary>Mô tả tiếng Việt từng thao tác, đúng thứ tự gửi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiffResult.Summary">
            <summary>Câu tóm tắt cho tiêu đề hộp xác nhận</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiff">
            <summary>
            So sánh lịch quảng cáo giữa LADA và nền tảng, sinh danh sách thao tác cần ghi.
            <para>
            Toàn bộ lớp này là logic thuần: không chạm DB, không chạm SDK Google. Nhờ vậy
            phần dễ sai nhất của luồng ghi được test đầy đủ trước khi có bất kỳ lệnh gọi ra ngoài.
            </para>
            <para>
            Quy tắc ánh xạ (quyết định 3 của Phase 6): <c>AdScheduleInfo</c> của Google là bất biến —
            đổi thứ/giờ phải xoá criterion cũ rồi tạo cái mới; chỉ có <c>bid_modifier</c> là sửa được
            tại chỗ. Xem tài liệu:
            https://developers.google.com/google-ads/api/fields/v21/campaign_criterion
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiff.AllowedMinutes">
            <summary>Phút Google cho phép trong lịch quảng cáo — <c>MinuteOfHour</c> chỉ có 4 mốc này</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiff.MinBidModifier">
            <summary>
            Hệ số giá thầu nhỏ nhất Google nhận cho criterion.
            Nguồn: tài liệu field <c>campaign_criterion.bid_modifier</c> — "must be in the range
            0.1 - 10.0", giá trị 0 chỉ dùng để tắt hẳn một loại <b>thiết bị</b> (device), không
            áp dụng cho lịch quảng cáo.
            https://developers.google.com/google-ads/api/fields/v21/campaign_criterion
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiff.MaxBidModifier">
            <summary>Hệ số giá thầu lớn nhất Google nhận (= +900%). Cùng nguồn với <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiff.MinBidModifier"/>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiff.BidModifierFieldPath">
            <summary>Tên field <c>bid_modifier</c> trong field mask của Google</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiff.Validate(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot})">
            <summary>
            Kiểm tra tính hợp lệ của lịch mong muốn trước khi so sánh: mốc phút, giờ kết thúc,
            thứ tự đầu–cuối, khoảng hệ số giá thầu và chồng giờ trong cùng một thứ.
            </summary>
            <returns>Danh sách lỗi tiếng Việt; rỗng nghĩa là hợp lệ.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiff.FindOverlaps(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot})">
            <summary>
            Tìm các cặp khung giờ chồng nhau trong cùng một thứ. Google từ chối cả lô mutate
            khi có chồng giờ, nên phải bắt trước và nói rõ chồng ở đâu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiff.Compare(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot},System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot})">
            <summary>
            So sánh hai phía và sinh thao tác, <b>không</b> kiểm tra hợp lệ.
            Dùng khi cần biết diff thuần (ví dụ test phân biệt 0.0 với null).
            </summary>
            <param name="desired">Lịch mong muốn — các dòng trong LADA</param>
            <param name="remote">Lịch đang có trên nền tảng, vừa đọc về</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiff.Build(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot},System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot})">
            <summary>
            Kiểm tra hợp lệ rồi so sánh. Có lỗi thì trả về bản diff <b>rỗng</b> kèm lỗi —
            không bao giờ trả thao tác dựa trên dữ liệu đã biết là sai.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiff.DescribeBid(System.Nullable{System.Decimal})">
            <summary>Phần đuôi mô tả hệ số giá thầu, bỏ hẳn khi không có điều chỉnh</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService">
            <summary>
            Lịch chạy quảng cáo (ad schedule) của chiến dịch.
            <para>
            Ad schedule là criterion cấp chiến dịch bên Google, khớp theo <c>ExternalId</c> (criterion id).
            </para>
            <para>
            Luồng ghi cố ý chia làm <b>ba bước tách biệt</b>, vì sửa lịch là đổi giá thầu — tiêu tiền thật:
            (1) sửa bản nháp trong LADA (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleModel,System.Int32,System.String,System.Threading.CancellationToken)"/>, <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.DeleteAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)"/>,
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.SetBidModifierAsync(System.Guid,System.Nullable{System.Decimal},System.Int32,System.String,System.Threading.CancellationToken)"/>) — không gọi ra nền tảng;
            (2) xem trước (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.PreviewApplyAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)"/>) — tính diff rồi nhờ Google kiểm tra bằng
            <c>validate_only</c>, không ghi gì;
            (3) đẩy thật (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.ApplyToPlatformAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)"/>) — ghi rồi <b>đọc lại</b> từ nền tảng để xác nhận.
            </para>
            <para>
            Chiến dịch không có dòng nào nghĩa là **chạy cả tuần 24/7**, không phải "không chạy".
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.GetByCampaignAsync(System.Guid,System.Threading.CancellationToken)">
            <summary>
            Lấy lịch của một chiến dịch, sắp xếp theo thứ (Thứ Hai trước) rồi theo giờ bắt đầu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.GetViewByCampaignAsync(System.Guid,System.Threading.CancellationToken)">
            <summary>
            Lấy lịch kèm bối cảnh UI cần: múi giờ của tài khoản, chiến dịch đã publish chưa,
            nền tảng có cho sửa lịch không. Trả cả bọc này để UI không phải gọi thêm API
            và không phải tự đoán múi giờ (giờ lịch chạy theo múi giờ tài khoản, không phải giờ server).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.SyncFromPlatformAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Kéo lịch từ nền tảng về: upsert theo <c>(AdsCampaignId, ExternalId)</c>,
            soft-delete các dòng nền tảng không còn trả về.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.ReconcileCampaignAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Dò lệch lịch của một chiến dịch: đọc lịch nền tảng, so với LADA và <b>chỉ đánh dấu</b>
            khi lệch. Không sửa lịch ở bất kỳ phía nào.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.ReconcileAllAsync(System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Dò lệch lịch toàn bộ chiến dịch đã đẩy lên nền tảng. Dùng cho job chạy định kỳ và
            cho nút chạy tay. Một chiến dịch lỗi không làm chết cả lượt.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleModel,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Tạo / sửa một khung giờ <b>trong LADA</b>. Không gọi ra nền tảng: dòng được đánh
            <c>SyncStatus = OutOfSync</c> rồi chờ người dùng bấm đẩy lên.
            <para>
            Validate qua <c>AdsScheduleDiff.Validate</c> trên toàn bộ lịch sau khi áp thay đổi,
            nên chồng giờ bị chặn ngay lúc lưu nháp chứ không đợi Google từ chối cả lô.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.DeleteAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Xoá một khung giờ <b>trong LADA</b> (soft-delete). Không gọi ra nền tảng.
            <para>
            Dòng đã có <c>ExternalId</c> thì bên nền tảng vẫn còn khung giờ đó cho tới khi
            đẩy lên — <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.PreviewApplyAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)"/> sẽ liệt kê nó ở nhóm "Xoá".
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.SetBidModifierAsync(System.Guid,System.Nullable{System.Decimal},System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Đặt / xoá hệ số điều chỉnh giá thầu của một khung giờ <b>trong LADA</b>.
            </summary>
            <param name="bidModifier">
            Hệ số theo dạng Google (1.2 = +20%). <c>null</c> = <b>xoá điều chỉnh</b>,
            khác hẳn 0 — xem <see cref="P:Lada.Framework.Data.Domains.Ads.AdsSchedule.BidModifier"/>.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.PreviewApplyAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Xem trước những gì sẽ ghi lên nền tảng: đọc lịch hiện tại từ nền tảng, so với lịch
            trong LADA, rồi gửi cả lô ở chế độ <c>validate_only</c> để nền tảng kiểm tra.
            <b>Không ghi bất cứ thứ gì</b> lên tài khoản quảng cáo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.ApplyToPlatformAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Đẩy lịch lên nền tảng thật. <b>Việc này tiêu tiền</b>: giá thầu theo giờ đổi ngay sau khi ghi.
            <para>
            Sau khi ghi xong luôn gọi lại <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.SyncFromPlatformAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)"/> để đọc lại — request
            thành công không đồng nghĩa dữ liệu đúng, chỉ đọc lại mới chắc.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.ApplyTemplateAsync(System.Guid,System.String,System.Nullable{System.Decimal},System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Áp một mẫu lịch (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplates"/>) cho <b>một</b> chiến dịch — chỉ ghi
            nháp trong LADA, không gọi ra nền tảng.
            <para>
            <b>Thay toàn bộ lịch hiện tại</b>: các khung giờ cũ bị xoá (soft-delete) rồi tạo lại theo
            mẫu. Dòng cũ đã có <c>ExternalId</c> vẫn còn trên nền tảng cho tới khi người dùng đẩy lên.
            </para>
            </summary>
            <param name="bidModifier">
            % chung ghi đè cho mọi khung của mẫu. <c>null</c> nghĩa là dùng % của mẫu
            (<c>DefaultBidModifier</c>, hoặc % riêng từng khung nếu mẫu có).
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.ApplyTemplateToManyAsync(System.Collections.Generic.List{System.Guid},System.String,System.Nullable{System.Decimal},System.Boolean,System.Boolean,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Áp một mẫu lịch cho <b>nhiều</b> chiến dịch rồi (tuỳ <paramref name="pushToPlatform"/>)
            đẩy luôn lên nền tảng.
            <para>
            Một chiến dịch lỗi <b>không</b> làm chết cả lô: mỗi chiến dịch được bọc try/catch riêng,
            phần còn lại vẫn chạy, và kết quả trả về nói rõ từng dòng thành công / thất bại / bỏ qua
            kèm lý do. Chiến dịch chưa publish và tài khoản MCC được tính là <b>bỏ qua</b>,
            không phải thất bại.
            </para>
            </summary>
            <param name="pushToPlatform">
            <c>false</c> = chỉ ghi nháp trong LADA. <c>true</c> = ghi nháp rồi đẩy lên nền tảng thật.
            </param>
            <param name="validateOnly">
            <c>true</c> = dry-run cả lô: ghi nháp trong LADA rồi nhờ nền tảng kiểm tra
            (<c>validate_only</c>) mà không ghi thật. Chỉ có nghĩa khi <paramref name="pushToPlatform"/>.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsScheduleService.SyncFromPlatformManyAsync(System.Collections.Generic.List{System.Guid},System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Kéo lịch từ nền tảng về cho <b>nhiều</b> chiến dịch — tuần tự, một chiến dịch lỗi không giết lô,
            kết quả từng dòng; chiến dịch còn khung giờ sửa trong LADA chưa đẩy lên thì bỏ qua (kéo về sẽ ghi đè).
            Mỗi chiến dịch một lượt đọc nền tảng: lõi kéo về tự dò lệch lại bằng danh sách vừa đọc và gỡ cờ.
            Có Id không tồn tại / đã xoá là từ chối cả lô trước khi gọi nền tảng (<c>Rejected</c>). Tối đa 500 Id.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleViewResult">
            <summary>
            Lịch của một chiến dịch kèm bối cảnh hiển thị.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleViewResult.Items">
            <summary>Các khung giờ đã sắp xếp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleViewResult.AccountTimeZone">
            <summary>
            Múi giờ của tài khoản quảng cáo (ví dụ "Asia/Saigon").
            Lịch chạy theo múi giờ này, KHÔNG phải giờ máy chủ — UI phải ghi rõ cạnh lưới giờ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleViewResult.AccountName">
            <summary>Tên tài khoản quảng cáo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleViewResult.IsCampaignPublished">
            <summary>Chiến dịch đã đẩy lên nền tảng chưa — chưa thì không đồng bộ được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleViewResult.IsManagerAccount">
            <summary>Tài khoản là MCC — không chứa criterion nên không đồng bộ được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleViewResult.CanFetchSchedules">
            <summary>Nền tảng đọc được lịch hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleViewResult.CanEditSchedules">
            <summary>
            Nền tảng cho sửa lịch hay không. UI đọc cờ này để ẩn/hiện chức năng sửa
            thay vì hard-code nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleViewResult.SupportsValidateOnly">
            <summary>Nền tảng có kiểm tra trước khi ghi (dry-run) hay không — không có thì UI phải nói rõ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleViewResult.BidModifierSupport">
            <summary>
            Chiến lược đặt giá của chiến dịch có áp dụng % điều chỉnh theo khung giờ hay không.
            <c>Ignored</c> → UI cảnh báo vàng nhưng vẫn cho lưu; <c>Unknown</c> → nói rõ là
            "chưa xác định được", tuyệt đối không đoán.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleViewResult.BidModifierWarning">
            <summary>Câu cảnh báo tiếng Việt về giá thầu theo giờ — null nghĩa là không có gì phải cảnh báo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleViewResult.HasPendingChanges">
            <summary>Có khung giờ nào chưa khớp nền tảng (nháp / OutOfSync) đang chờ đẩy lên</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleViewResult.LastSyncedAt">
            <summary>Thời điểm đồng bộ lịch gần nhất (lấy mốc mới nhất trong các dòng)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleViewResult.BiddingStrategy">
            <summary>Chiến lược đặt giá của chiến dịch — smart bidding thì Google bỏ qua bid modifier</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleApplyResult">
            <summary>
            Kết quả một lần xem trước / đẩy lịch lên nền tảng.
            <para>
            Luôn trả kèm <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleApplyResult.Operations"/> để hộp xác nhận trên UI nói đúng <b>sẽ đổi gì</b> —
            nói sai việc sắp làm là nguyên nhân tiêu tiền oan.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleApplyResult.IsPreview">
            <summary>Đây là lần chạy thử (validate_only) chứ không phải ghi thật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleApplyResult.HasChanges">
            <summary>Có thay đổi nào cần đẩy lên hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleApplyResult.Summary">
            <summary>Câu tóm tắt: sẽ thêm mấy, đổi giá thầu mấy, xoá mấy khung giờ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleApplyResult.Operations">
            <summary>Mô tả tiếng Việt từng thao tác, đúng thứ tự sẽ gửi lên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleApplyResult.ValidationErrors">
            <summary>Lỗi dữ liệu phát hiện trước khi gọi nền tảng (chồng giờ, phút sai mốc…)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleApplyResult.PlatformAccepted">
            <summary>Nền tảng đã kiểm tra và chấp nhận lô thay đổi này (chỉ có nghĩa khi xem trước)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleApplyResult.PlatformErrorCode">
            <summary>Mã lỗi gốc của nền tảng — giữ nguyên để tra tài liệu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleApplyResult.Items">
            <summary>
            Lịch <b>đọc lại từ nền tảng</b> sau khi ghi. Đây là sự thật, không phải payload đã gửi —
            UI phải hiển thị danh sách này chứ không hiển thị thứ mình vừa gửi lên.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleApplyResult.BidModifierWarning">
            <summary>Cảnh báo về chiến lược đặt giá (nếu có) — vẫn ghi được, chỉ là % có thể không có tác dụng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSyncResult">
            <summary>
            Kết quả một lần đồng bộ lịch.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSyncResult.CreatedCount">
            <summary>Số khung giờ mới thêm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSyncResult.UpdatedCount">
            <summary>Số khung giờ đã cập nhật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSyncResult.RemovedCount">
            <summary>Số khung giờ nền tảng không còn trả về nên bị soft-delete</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSyncResult.TotalCount">
            <summary>Tổng số khung giờ nền tảng trả về</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSyncResult.RemainingDriftCount">
            <summary>
            Số khung còn lệch sau khi kéo về và dò lại bằng chính danh sách vừa đọc — 0 nghĩa là chiến dịch đã
            khớp nền tảng (cờ <c>OutOfSync</c> vì lệch lịch đã được gỡ). Null khi chưa dò (kéo về thất bại).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkItemResult">
            <summary>
            Kết quả áp lịch cho <b>một</b> chiến dịch trong lô — một dòng của bảng kết quả.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkItemResult.Outcome">
            <summary>
            Kết cục của dòng này. Cố ý tách <c>Skipped</c> khỏi <c>Failed</c>: chiến dịch chưa publish
            hay tài khoản MCC là chuyện bình thường, đếm chúng là thất bại sẽ làm người dùng đi tìm
            lỗi không tồn tại.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkItemResult.Message">
            <summary>Lý do — bắt buộc có khi bỏ qua hoặc thất bại, để người dùng biết phải làm gì</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkItemResult.OperationCount">
            <summary>Số thao tác đã (hoặc sẽ) gửi lên nền tảng cho chiến dịch này</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkItemResult.PlatformErrorCode">
            <summary>Mã lỗi gốc của nền tảng, giữ nguyên để tra tài liệu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkItemResult.BidModifierWarning">
            <summary>Cảnh báo chiến lược đặt giá bỏ qua % giá thầu (nếu có)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkOutcome">
            <summary>Kết cục của một chiến dịch trong lô</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkOutcome.Skipped">
            <summary>Không áp được vì lý do hợp lệ (chưa publish, tài khoản MCC…) — không phải lỗi</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkResultBase">
            <summary>
            Phần chung của mọi kết quả lô theo chiến dịch (áp mẫu lịch, kéo lịch về): bảng từng dòng + số đếm.
            <para>
            Luôn mang <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkResultBase.Items"/> đầy đủ từng dòng: câu "8/12 chiến dịch" mà không nói 4 cái nào lỗi
            thì vô dụng. <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkResultBase.Rejected"/> là ca lô bị từ chối <b>trước khi chạy</b> (Id lạ, quá trần,
            rỗng): <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkResultBase.Items"/> rỗng, <c>Message</c> là lý do — controller trả 400, giao diện dừng lô
            thay vì suy đoán từ số dòng.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkResultBase.Items">
            <summary>Kết quả từng chiến dịch — thứ tự giữ nguyên theo danh sách gửi lên</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkResultBase.Rejected">
            <summary>Lô bị từ chối trước khi chạy — không chiến dịch nào được xử lý</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkResultBase.TotalOperationCount">
            <summary>Tổng <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkItemResult.OperationCount"/> cả lô — nghĩa tuỳ luồng, xem lớp con</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkResult">
            <summary>
            Kết quả áp lịch cho cả lô chiến dịch. <c>TotalOperationCount</c> là số thao tác gửi lên nền tảng —
            dùng để ước lượng quota.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkResult.IsPreview">
            <summary>Đây là bản dry-run (chưa ghi gì lên nền tảng) hay lần ghi thật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkResult.TemplateKey">
            <summary>Mẫu đã áp</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkSyncResult">
            <summary>
            Kết quả kéo lịch về cả lô. <c>OperationCount</c> / <c>TotalOperationCount</c> ở đây là số khung giờ
            <b>thay đổi trong LADA</b> (thêm + cập nhật + bỏ), không phải thao tác gửi lên nền tảng: kéo về không
            ghi gì lên.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkSyncResult.InSyncCount">
            <summary>Số chiến dịch sau khi kéo về đã khớp với nền tảng (dò lệch lại không thấy gì)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService">
            <inheritdoc />
            <summary>
            Phần dò lệch lịch (schedule drift) của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService"/>.
            <para>
            <b>Chỉ đọc và đánh dấu, tuyệt đối không tự ghi đè.</b> Một job âm thầm ghi đè thay đổi thủ
            công của người dùng — dù theo hướng nào — là hành vi tệ nhất có thể: người ta sửa giá thầu
            trên Google Ads UI lúc 9h, job chạy lúc 2h sáng xoá mất, không ai biết vì sao. Job này chỉ
            đặt <c>SyncStatus = OutOfSync</c> + <c>OutOfSyncDetailJson</c> rồi để người dùng tự quyết:
            đẩy lịch LADA lên, hay kéo lịch nền tảng về.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.ScheduleEndpoint">
            <summary>Nhãn endpoint ghi vào sync log — là bảng GAQL được truy vấn</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.SyncAction">
            <summary>Tên thao tác ghi vào sync log</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.MutateEndpoint">
            <summary>Nhãn endpoint cho luồng ghi — mutate criterion qua GoogleAdsService</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.PreviewAction">
            <summary>Thao tác xem trước (validate_only) — ghi log riêng để phân biệt với lần ghi thật</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.ApplyAction">
            <summary>Thao tác đẩy lịch thật lên nền tảng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.GetByCampaignAsync(System.Guid,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.GetViewByCampaignAsync(System.Guid,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.SyncFromPlatformAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.SyncFromPlatformCoreAsync(Lada.Framework.Data.Domains.Ads.AdsCampaign,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Phần lõi của kéo lịch về, nhận chiến dịch đã tải kèm tài khoản + kết nối (luồng lô tải một lần rồi
            gọi thẳng vào đây). Sau khi ghi xong, dò lệch lại bằng <b>chính danh sách nền tảng vừa đọc</b> để
            gỡ cờ <c>OutOfSync</c> của chiến dịch — không tốn lượt đọc thứ hai, và cả endpoint lẻ lẫn lô đều gỡ
            cờ (trước GĐ C kéo về xong panel "việc cần xử lý" vẫn đỏ tới job đêm).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleModel,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.DeleteAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.SetBidModifierAsync(System.Guid,System.Nullable{System.Decimal},System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.PreviewApplyAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.ApplyToPlatformAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.ApplyCoreAsync(System.Guid,System.Int32,System.String,System.Boolean,System.Threading.CancellationToken)">
            <summary>
            Thân chung của xem trước và đẩy thật. Chỉ khác nhau một cờ <paramref name="validateOnly"/>
            — cố ý dùng chung một đường code để bản xem trước không bao giờ lệch với bản ghi thật.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.MaxBulkCampaigns">
            <summary>
            Giới hạn số chiến dịch một lô. Quota Google Ads Basic Access là 15.000 operations/ngày;
            mỗi chiến dịch có thể sinh vài chục operation (xoá lịch cũ + tạo lịch mới), nên 30 chiến
            dịch là mức vừa đủ dùng mà vẫn còn xa quota — và đủ nhỏ để người dùng còn đọc hết được
            bảng kết quả. Vượt giới hạn thì <b>báo lỗi</b>, tuyệt đối không âm thầm cắt bớt danh sách.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.ApplyTemplateAsync(System.Guid,System.String,System.Nullable{System.Decimal},System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.ApplyTemplateToManyAsync(System.Collections.Generic.List{System.Guid},System.String,System.Nullable{System.Decimal},System.Boolean,System.Boolean,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.ApplyTemplateToOneAsync(System.Guid,Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplate,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot},System.Boolean,System.Boolean,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Áp mẫu cho một chiến dịch trong lô. Không ném lỗi ra ngoài trong các ca đã lường được —
            trả về dòng kết quả có lý do, để lô còn chạy tiếp.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.ReplaceLocalScheduleAsync(Lada.Framework.Data.Domains.Ads.AdsCampaign,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot},System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Thay toàn bộ lịch nháp của chiến dịch bằng danh sách khung giờ của mẫu.
            <para>
            Khớp theo <c>WindowKey</c> (thứ + giờ) chứ <b>không</b> xoá sạch rồi tạo lại. Lý do rất
            cụ thể: xoá sạch làm mất <c>ExternalId</c> của những khung giờ vẫn đang tồn tại trên nền
            tảng, và <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.SyncFromPlatformAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)"/> khớp dòng theo <c>ExternalId</c> — dòng nháp
            <c>ExternalId = null</c> sẽ không khớp được nên bước đọc lại sinh thêm một dòng nữa cho
            cùng khung giờ. Dòng nháp mồ côi đó cũng không bị bước dọn dẹp xoá (bước đó chỉ xét dòng
            <b>có</b> <c>ExternalId</c>), kết quả là hai dòng trùng khung giờ và validate báo chồng
            giờ vĩnh viễn — lịch của chiến dịch coi như hỏng, phải sửa tay trong DB.
            </para>
            <para>
            Giữ lại <c>ExternalId</c> còn lợi về quota: đổi % giá thầu của khung giờ đã có trở thành
            một <c>update</c> thay vì cặp <c>remove</c> + <c>create</c>.
            </para>
            </summary>
            <returns>Số khung giờ cũ bị xoá vì không có trong mẫu</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.BuildTemplateSlots(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplate,System.Nullable{System.Decimal})">
            <summary>
            Dựng danh sách khung giờ của mẫu, áp % giá thầu theo thứ tự ưu tiên:
            % người dùng nhập → % riêng của khung → % mặc định của mẫu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.BuildTemplateMessage(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplate,System.Int32,System.Int32)">
            <summary>Câu thông báo sau khi áp mẫu vào lịch nháp của một chiến dịch</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.BuildBulkMessage(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleBulkResult,Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplate,System.Boolean,System.Boolean)">
            <summary>
            Câu tổng kết cả lô. Luôn nêu số bỏ qua tách riêng số thất bại.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.MaxBulkSyncCampaigns">
            <summary>Trần Id một lần kéo lịch về — cùng con số với các endpoint nhận danh sách Id khác (plan §3.9)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.SyncFromPlatformManyAsync(System.Collections.Generic.List{System.Guid},System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.SyncOneForBulkAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Một chiến dịch trong lô: gác các ca bỏ qua (kể cả kết nối lỗi / tài khoản tắt — gọi vào là chắc chắn
            thất bại), từ chối chiến dịch còn khung giờ sửa trong LADA chưa đẩy lên (kéo về sẽ ghi đè im lặng),
            rồi kéo về bằng lõi dùng chung — lõi đã dò lệch lại và gỡ cờ. Trả thêm cờ "đã khớp" để đếm ở kết quả lô.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.SkipReasonFor(Lada.Framework.Data.Domains.Ads.AdsCampaign,System.String,System.Boolean)">
            <summary>
            Lý do một chiến dịch bị BỎ QUA trong các luồng lô (hợp lệ, không phải lỗi): chưa gắn tài khoản /
            kết nối (kể cả đã xoá mềm — <c>Include</c> không lọc xoá mềm), tài khoản MCC, chưa đẩy lên nền
            tảng. Null = xử lý được. Dùng chung cho áp mẫu lịch và kéo lịch về để cùng một chiến dịch nhận
            cùng một câu dù đi endpoint nào.
            </summary>
            <param name="nextAction">Việc người dùng định làm, để câu gợi ý đúng ngữ cảnh ("áp lịch", "kéo lịch về")</param>
            <param name="requireFetch">
            Luồng phải ĐỌC được từ nền tảng (kéo lịch về): thêm các ca tài khoản đã tắt đồng bộ, kết nối
            đang lỗi, nền tảng chưa hỗ trợ đọc lịch — gọi vào đó là chắc chắn thất bại và chỉ tốn log.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.PendingLocalScheduleReasonAsync(System.Guid,System.Threading.CancellationToken)">
            <summary>
            Chiến dịch còn khung giờ đã sửa trong LADA mà chưa đẩy lên (dòng lịch <c>OutOfSync</c>) thì kéo về
            hàng loạt sẽ ghi đè im lặng thứ người dùng vừa nhập — luồng lẻ cho họ xem hai cột trước khi bấm,
            luồng lô thì không, nên ở lô là bỏ qua kèm lý do (finding review GĐ C).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.LoadCampaignNameAsync(System.Guid,System.Threading.CancellationToken)">
            <summary>Tên chiến dịch cho dòng kết quả khi luồng chính đã ném lỗi</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.LoadLocalAsync(System.Guid,System.Threading.CancellationToken)">
            <summary>Các dòng lịch còn hiệu lực của một chiến dịch trong LADA</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.ToSlot(Lada.Framework.Data.Domains.Ads.AdsSchedule)">
            <summary>
            Entity → slot thuần dữ liệu để đưa vào <c>AdsScheduleDiff</c>.
            Giữ nguyên <c>BidModifier</c> kể cả null — null (không điều chỉnh) khác hẳn 0 (-100%).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.ToSlot(Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleDto)">
            <summary>
            DTO nền tảng → slot. <c>LocalId</c> để null vì đây là phía nền tảng,
            chưa biết ứng với dòng LADA nào.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.ApplyModel(Lada.Framework.Data.Domains.Ads.AdsSchedule,Ladaer.BackEnd.Infrastructures.DTO.Models.Ads.AdsScheduleModel,System.DateTimeOffset,System.Int32,System.String)">
            <summary>Áp dữ liệu model lên entity rồi đánh dấu lệch với nền tảng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.MarkOutOfSync(Lada.Framework.Data.Domains.Ads.AdsSchedule,System.DateTimeOffset,System.Int32,System.String)">
            <summary>
            Đánh dấu dòng đã sửa trong LADA nhưng chưa đẩy lên nền tảng.
            <para>
            Dòng chưa từng lên nền tảng giữ <c>Local</c>; dòng đã có criterion thì thành
            <c>OutOfSync</c> — UI đọc cờ này để hiện chấm "chờ đẩy lên".
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.DescribeSlot(Lada.Framework.Data.Domains.Ads.AdsSchedule)">
            <summary>Nhãn tiếng Việt của một khung giờ, dùng trong thông báo</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.BuildBidModifierWarning(Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleBidModifierSupport,System.String)">
            <summary>
            Câu cảnh báo về việc % điều chỉnh giá thầu có tác dụng hay không với chiến lược đặt giá
            đang dùng. Trả null khi nền tảng thật sự áp dụng — không có gì phải cảnh báo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.BuildRequestLog(Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsScheduleApplyRequest,Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiffResult,System.Boolean)">
            <summary>
            Nội dung định ghi, lưu vào <c>RequestJson</c> của sync log.
            <para>
            Cố ý lưu cả mô tả tiếng Việt từng thao tác chứ không chỉ payload máy đọc: khi cần
            truy "vì sao chi phí tăng", đọc log phải hiểu ngay đã đổi gì mà không cần dịch proto.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.MarkErrorAsync(System.Guid,System.String,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Ghi lỗi lên các dòng lịch hiện có để UI chỉ ra được lần đồng bộ gần nhất đã thất bại,
            thay vì hiển thị dữ liệu cũ như thể vẫn đúng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.LogAsync(Lada.Framework.Data.Domains.Ads.AdsCampaign,Lada.Framework.Data.Domains.Ads.AdsAccount,System.Boolean,System.String,System.String,System.Int64,System.Int32,System.Int32,System.String,System.String,Lada.Framework.Data.Enums.AdsSyncDirection,System.String,System.String,System.String)">
            <summary>
            Ghi một dòng sync log. Mặc định là hướng Pull / thao tác đồng bộ để giữ nguyên
            hành vi phần đọc; luồng ghi truyền <c>AdsSyncDirection.Push</c> kèm nội dung định ghi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.SortableDayOfWeek(System.DayOfWeek)">
            <summary>
            Đổi <see cref="T:System.DayOfWeek"/> của .NET (Sunday = 0) sang số thứ tự để sắp xếp
            theo cách người Việt đọc lịch: Thứ Hai = 1 … Chủ Nhật = 7.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.BulkSyncFailed(System.String)">
            <summary>Lô bị từ chối trước khi chạy — <c>Rejected</c> để controller trả 400 và giao diện dừng lô</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.ReconcileAction">
            <summary>Thao tác ghi vào <c>AdsSyncLog</c> cho lượt dò lệch</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.ReconcileCampaignAsync(System.Guid,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Dò lệch lịch cho một chiến dịch: đọc lịch từ nền tảng, so với LADA, và nếu lệch thì
            đánh dấu chiến dịch <c>OutOfSync</c> kèm chi tiết.
            <para>
            Không ghi bất cứ thứ gì lên nền tảng. Chiến dịch chưa publish / tài khoản MCC / kết nối
            đã tắt được <b>bỏ qua</b>, không tính là lỗi.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.ReconcileAllAsync(System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Dò lệch lịch cho <b>mọi</b> chiến dịch đã publish thuộc các tài khoản đang bật.
            <para>
            Một chiến dịch lỗi <b>không</b> làm chết cả lượt: mỗi chiến dịch bọc try/catch riêng.
            Đây là điều kiện sống của job chạy đêm — một kết nối hết token không được làm 200 chiến
            dịch còn lại không được kiểm tra.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.CompareForDrift(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot},System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleSlot})">
            <summary>
            So lịch LADA với lịch nền tảng, trả về danh sách khung giờ lệch.
            <para>
            Logic thuần, không chạm DB — test được. Khớp theo <c>WindowKey</c> giống
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDiff"/> vì Google không cho sửa thứ/giờ của một criterion: khung
            thời gian chính là danh tính của nó.
            </para>
            <para>
            Chỉ so những dòng LADA <b>đã có</b> <c>ExternalId</c> hoặc khung mà nền tảng có. Bản nháp
            chưa đẩy lên (<c>ExternalId</c> rỗng) <b>không</b> tính là lệch: người dùng đang cố ý sửa
            và chưa đẩy, báo lệch ở đó là báo động giả và sẽ khiến người ta bỏ qua cả badge thật.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.SaveDriftAsync(Lada.Framework.Data.Domains.Ads.AdsCampaign,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftItem})">
            <summary>
            Ghi kết quả dò lệch vào chiến dịch. <b>Chỉ đánh dấu</b> — không sửa một dòng lịch nào.
            <para>
            Hết lệch thì xoá cờ, nhưng <b>chỉ khi</b> chiến dịch đang <c>OutOfSync</c>: chiến dịch
            đang <c>Local</c>/<c>Publishing</c>/<c>Failed</c> mang nghĩa khác của luồng publish, ghi
            <c>Synced</c> lên là mất thông tin của luồng đó.
            </para>
            </summary>
            <returns><c>true</c> khi vừa gỡ cờ lệch (trước đó <c>OutOfSync</c>, nay đã khớp lại)</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.ExtractFieldEntries(System.String)">
            <summary>
            Các phần tử lệch trường (<c>{Field, LocalValue, RemoteValue}</c>) đang lưu trong chi tiết — phần không
            thuộc luồng lịch, phải giữ nguyên. JSON rỗng / hỏng → rỗng (chi tiết hỏng thì ghi mới).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleService.BuildReconcileSummary(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleReconcileResult,System.Int32)">
            <summary>Câu tóm tắt cho log và cho người bấm chạy tay</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftItem">
            <summary>
            Một khung giờ đang lệch giữa LADA và nền tảng, ở dạng đủ để UI hiện hai cột cạnh nhau.
            <para>
            Cố ý <b>không</b> tái dùng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsOutOfSyncField"/> (Field/LocalValue/RemoteValue) của
            chiến dịch: lệch lịch không phải "một trường đổi giá trị" mà là "khung giờ này có bên kia mà
            không có bên này". Nhồi vào cấu trúc 3 cột kia thì phải nhét nhãn khung giờ vào tên trường,
            UI không tách lại được để tô màu theo loại lệch.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftItem.Kind">
            <summary>
            Loại lệch: <c>MissingOnPlatform</c> (LADA có, nền tảng không),
            <c>MissingInLada</c> (nền tảng có, LADA không), <c>BidModifierDiffers</c> (cùng khung, khác giá thầu).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftItem.KindStr">
            <summary>Nhãn tiếng Việt của loại lệch, để UI không phải tự dịch</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftItem.Window">
            <summary>Nhãn khung giờ, ví dụ "Thứ Hai 08:00–17:30"</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftItem.LocalBid">
            <summary>Giá thầu phía LADA đã định dạng (%), <c>null</c> khi LADA không có khung này</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftItem.RemoteBid">
            <summary>Giá thầu phía nền tảng đã định dạng (%), <c>null</c> khi nền tảng không có khung này</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftItem.ExternalId">
            <summary>Criterion id bên nền tảng (nếu khung đó tồn tại bên nền tảng)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftKind">
            <summary>
            Giá trị của <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftItem.Kind"/> — chuỗi lưu trong <c>OutOfSyncDetailJson</c> và được
            classifier "việc cần xử lý" đọc lại, nên là hằng dùng chung: đổi chữ ở đây là đổi dữ liệu đã lưu.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftKind.MissingOnPlatform">
            <summary>LADA nghĩ khung này đang chạy nhưng bên nền tảng không còn</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftKind.BidModifierDiffers">
            <summary>Cùng khung giờ nhưng % giá thầu hai bên khác nhau</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftKind.MissingInLada">
            <summary>Nền tảng có khung mà LADA không biết</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftResult">
            <summary>
            Kết quả dò lệch lịch của <b>một</b> chiến dịch.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftResult.CampaignId">
            <summary>Chiến dịch được kiểm tra</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftResult.CampaignName">
            <summary>Tên chiến dịch — để log/thông báo không phải join lại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftResult.Checked">
            <summary>Đã kiểm tra được hay không (false = bỏ qua hoặc lỗi kết nối)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftResult.HasDrift">
            <summary>Có lệch hay không. Chỉ có nghĩa khi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftResult.Checked"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftResult.ClearedDrift">
            <summary>
            Trước đó đang lệch, lượt này đã khớp lại nên cờ <c>OutOfSync</c> vừa được gỡ.
            Tách riêng khỏi "không lệch" để log nói được "hết lệch 3" — người vận hành cần biết
            cảnh báo cũ đã tự hết, không phải đi tìm xem ai đã xử lý.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftResult.Items">
            <summary>Danh sách khung giờ lệch</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftResult.SkipReason">
            <summary>Lý do bỏ qua / lỗi. <c>null</c> khi kiểm tra bình thường.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleDriftResult.Error">
            <summary>Lỗi khi gọi nền tảng, nếu có</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleReconcileResult">
            <summary>
            Kết quả một lượt chạy dò lệch trên nhiều chiến dịch.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleReconcileResult.CheckedCount">
            <summary>Số chiến dịch đã gọi ra nền tảng để so</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleReconcileResult.DriftCount">
            <summary>Số chiến dịch phát hiện lệch</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleReconcileResult.ClearedCount">
            <summary>Số chiến dịch vừa hết lệch (trước đó OutOfSync, giờ khớp lại)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleReconcileResult.SkippedCount">
            <summary>Số chiến dịch bỏ qua (chưa publish, MCC, kết nối tắt…) — không phải lỗi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleReconcileResult.FailedCount">
            <summary>Số chiến dịch lỗi khi gọi nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleReconcileResult.Items">
            <summary>Chi tiết từng chiến dịch có lệch hoặc lỗi (chiến dịch khớp không đưa vào cho gọn)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleReconcileResult.Summary">
            <summary>Câu tóm tắt tiếng Việt cho log và cho endpoint kích hoạt tay</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplates">
            <summary>
            Định nghĩa các mẫu lịch áp nhanh.
            <para>
            Cố ý để ở backend (không hard-code trong Vue) vì hai lý do: thêm/sửa mẫu không phải build lại
            frontend, và job tự động (nếu có) dùng chung được đúng một định nghĩa — hai bản định nghĩa
            lệch nhau là cách chắc chắn nhất để áp sai lịch mà không ai biết.
            </para>
            <para>
            <b>Áp mẫu = thay toàn bộ lịch hiện tại</b>, không phải cộng thêm vào lịch đang có.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplates.OfficeHours">
            <summary>Thứ Hai–Thứ Sáu 08:00–17:30</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplates.OutsideOfficeHours">
            <summary>Phần bù của <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplates.OfficeHours"/> — ngoài giờ hành chính và cả cuối tuần</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplates.Weekend">
            <summary>Thứ Bảy + Chủ Nhật cả ngày</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplates.Always">
            <summary>Chạy suốt — tương đương xoá hết khung giờ</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplates.LogisticsPeak">
            <summary>Hai đỉnh đặc thù vận tải: sáng điều xe, chiều chốt lịch lấy hàng hôm sau</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplates.Weekdays">
            <summary>
            Các thứ trong tuần theo cách người Việt đọc lịch: Thứ Hai trước, Chủ Nhật cuối.
            Không dùng thứ tự của <see cref="T:System.DayOfWeek"/> (.NET đánh Sunday = 0).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplates.All">
            <summary>
            Toàn bộ mẫu, theo thứ tự muốn hiện trên UI.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplates.Find(System.String)">
            <summary>
            Tìm mẫu theo khoá. Trả <c>null</c> nếu không có — người gọi phải xử lý,
            không được lặng lẽ áp mẫu khác.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplates.Build(System.Collections.Generic.IEnumerable{System.DayOfWeek},System.Int32,System.Int32,System.Int32,System.Int32)">
            <summary>Cùng một khung giờ áp cho nhiều thứ</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplates.BuildOutsideOfficeHours">
            <summary>
            Phần bù của giờ hành chính. Ngày làm việc tách thành hai khung để không chồng lên
            khoảng 08:00–17:30; cuối tuần lấy cả ngày.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplates.BuildLogisticsPeak">
            <summary>
            Giờ cao điểm vận tải — mỗi khung mang % riêng, không dùng % mặc định chung.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplate">
            <summary>
            Một mẫu lịch áp nhanh.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplate.Key">
            <summary>Khoá bền, dùng trong API và log — đừng đổi sau khi đã phát hành</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplate.Name">
            <summary>Tên hiện trên UI</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplate.Description">
            <summary>Giải thích mẫu làm gì, hiện thẳng trên UI để người dùng không phải đoán</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplate.DefaultBidModifier">
            <summary>
            Hệ số giá thầu mặc định theo dạng Google (1.2 = +20%). <c>null</c> = không điều chỉnh.
            Người dùng ghi đè được khi áp.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplate.HasPerSlotBidModifier">
            <summary>
            Mẫu tự mang % riêng cho từng khung giờ (như giờ cao điểm vận tải). UI nên nói rõ
            rằng nhập % chung sẽ ghi đè các % riêng này.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplate.ClearsAllSlots">
            <summary>
            Mẫu này xoá sạch lịch chứ không tạo khung giờ nào (mẫu 24/7).
            UI phải cảnh báo rõ vì nhìn danh sách khung giờ rỗng dễ tưởng là mẫu lỗi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplate.Slots">
            <summary>Các khung giờ của mẫu. Rỗng là hợp lệ — nghĩa là chạy 24/7.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplate.SlotCount">
            <summary>Số khung giờ mẫu sẽ tạo — UI hiện trước để người dùng ước lượng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplateSlot">
            <summary>
            Một khung giờ trong mẫu. Thuần dữ liệu, không gắn chiến dịch nào.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplateSlot.EndHour">
            <summary>0–24, trong đó 24 nghĩa là hết ngày</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsScheduleTemplateSlot.BidModifier">
            <summary>
            % riêng của khung này theo dạng hệ số Google. <c>null</c> = dùng % chung khi áp.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsSyncLogService">
            <summary>
            Ghi log mọi lần gọi ra nền tảng quảng cáo — công cụ debug chính của module.
            Bắt buộc đi qua service này thay vì ghi trực tiếp, để không có chỗ nào lọt credential vào DB.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsSyncLogService.WriteAsync(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogEntry)">
            <summary>
            Ghi một dòng log. Nội dung request/response được scrub trước khi lưu.
            Lỗi khi ghi log không được làm hỏng nghiệp vụ gọi nó — chỉ nuốt và bỏ qua.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsSyncLogService.Scrub(System.String)">
            <summary>
            Xoá thông tin mật khỏi một chuỗi trước khi lưu hoặc trả ra UI.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsSyncLogService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Danh sách log để tra cứu trên UI. Payload đã được scrub từ lúc ghi,
            nhưng vẫn scrub lại một lần nữa khi trả ra để chắc chắn với dữ liệu cũ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogEntry">
            <summary>
            Dữ liệu một dòng log gọi nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogEntry.Action">
            <summary>Tên hành động, ví dụ FetchAccounts, SyncCampaigns, PublishCampaign</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogService">
            <inheritdoc />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogService.MaxPayloadLength">
            <summary>Giới hạn độ dài payload lưu vào log — response metrics có thể rất lớn</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogService.MaxErrorMessageLength">
            <summary>Độ dài cột ErrorMessage trong AdsSyncLogMap</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogService.MaxPlatformErrorCodeLength">
            <summary>Độ dài cột PlatformErrorCode trong AdsSyncLogMap</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogService.MaxEndpointLength">
            <summary>Độ dài cột Endpoint trong AdsSyncLogMap</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogService.MaxActionLength">
            <summary>Độ dài cột Action trong AdsSyncLogMap</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogService.SecretPatterns">
            <summary>
            Các mẫu credential cần xoá. Bao gồm cả dạng header thô và dạng JSON,
            vì payload log đến từ nhiều nguồn (HttpClient, SDK, chuỗi tự ghép).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogService.Scrub(System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogService.Truncate(System.String,System.Int32)">
            <summary>
            Cắt chuỗi cho vừa độ dài cột trong DB.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogService.WriteAsync(Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogEntry)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncLogService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsSyncService">
            <summary>
            Kéo chiến dịch / nhóm / quảng cáo từ nền tảng về bản ghi canonical của LADA.
            Quy tắc đối chiếu: khớp theo <c>ExternalId</c>; bản ghi LADA đang có ExternalId mà số liệu
            khác nền tảng thì đánh <see cref="F:Lada.Framework.Data.Enums.AdsSyncStatus.OutOfSync"/> kèm danh sách trường lệch —
            không tự ghi đè, vì có thể người dùng vừa sửa trong LADA và chưa đẩy lên.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsSyncService.SyncCampaignsAsync(System.Int32,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>Đồng bộ chiến dịch của một tài khoản quảng cáo</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsSyncService.SyncAdGroupsAsync(System.Int32,System.Nullable{System.Guid},System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Đồng bộ nhóm quảng cáo. Truyền <paramref name="adsCampaignId"/> để chỉ đồng bộ một chiến dịch.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsSyncService.SyncAdsAsync(System.Int32,System.Nullable{System.Guid},System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Đồng bộ <b>quảng cáo</b> (Google: AdGroupAd) từ nền tảng về. Truyền
            <paramref name="adsCampaignId"/> để chỉ đồng bộ một chiến dịch.
            <para>
            Quảng cáo tồn tại trên nền tảng nhưng không do LADA soạn sẽ có
            <see cref="P:Lada.Framework.Data.Domains.Ads.AdsItem.AdsCreativeId"/> = <c>null</c> — đó là dữ liệu chỉ đọc, không phải lỗi.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.IAdsSyncService.SyncAccountAsync(System.Int32,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>Đồng bộ cả chiến dịch, nhóm rồi tới quảng cáo của một tài khoản</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncResult">
            <summary>
            Kết quả một lần đồng bộ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncResult.CreatedCount">
            <summary>Số bản ghi mới thêm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncResult.UpdatedCount">
            <summary>Số bản ghi đã cập nhật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncResult.OutOfSyncCount">
            <summary>Số bản ghi bị đánh dấu lệch dữ liệu</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncResult.TotalCount">
            <summary>Tổng số bản ghi nền tảng trả về</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsOutOfSyncField">
            <summary>
            Một trường đang lệch giữa LADA và nền tảng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncService">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncService.SyncCampaignsAsync(System.Int32,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncService.CompareCampaign(Lada.Framework.Data.Domains.Ads.AdsCampaign,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsCampaignDto)">
            <summary>
            So sánh các trường người dùng sửa được. Không so RawResponseJson / LastSyncedAt
            vì chúng luôn khác nhau và không phản ánh sự lệch thật.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncService.SyncAdGroupsAsync(System.Int32,System.Nullable{System.Guid},System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncService.SyncAdsAsync(System.Int32,System.Nullable{System.Guid},System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncService.CompareItem(Lada.Framework.Data.Domains.Ads.AdsItem,Ladaer.BackEnd.Infrastructures.Services.Ads.Adapters.AdsAdDto)">
            <summary>
            So sánh các trường có thể lệch. <b>Không</b> so <c>ApprovalStatus</c>: trạng thái xét
            duyệt do nền tảng quyết, LADA không sửa được nên nó đổi không phải là "lệch dữ liệu"
            mà là tin mới cần nhận về.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncService.SyncAccountAsync(System.Int32,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncService.LogAsync(Lada.Framework.Data.Domains.Ads.AdsAccount,System.String,System.Boolean,System.String,System.Int64,System.Int32,System.Int32,System.String,System.Nullable{Lada.Framework.Data.Enums.AdsEntityLevel},System.Nullable{System.Guid})">
            <summary>
            Ghi log một lần đồng bộ. <paramref name="entityLevel"/> / <paramref name="entityId"/> là
            tuỳ chọn để các hàm đồng bộ cũ không phải đổi; hàm mới nên truyền đủ để bộ lọc log
            theo cấp dùng được.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsSyncService.ManagerAccountMessage(System.String)">
            <summary>
            Tài khoản quản lý (MCC) không chứa chiến dịch / nhóm / số liệu — Google bắt gọi riêng
            vào từng tài khoản con. Chặn ở service thay vì chỉ ở UI để job định kỳ cũng an toàn.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.AI.AiProviderKeyProtection">
            <summary>
            Chuyển các API key còn ở dạng bản rõ trong bảng <c>AiProvider</c> sang bản mã hoá tại chỗ (plan cổng §3.6, đóng CNQ-1).
            Chạy lúc API khởi động (<c>StartupHostedService</c>) vì FluentMigrator chỉ chạy SQL, không gọi được
            <c>ISecretProtector</c>. Tiêu chí chọn dòng là <see cref="M:Lada.Framework.Infrastructures.Services.Ai.AiProviderKeys.NeedsProtection(System.String)"/> — đúng tiêu chí của
            script khảo sát <c>Lada.Migrations/Sql/KhaoSat/TroLyAiCongNhuongQuyen.KhaoSat.sql</c>.
            </summary>
            <remarks>
            Chạy lại vô hại: dòng đã mã hoá không còn khớp tiêu chí. Mỗi dòng ghi bằng <c>ExecuteUpdate</c> có điều kiện
            "key vẫn là giá trị vừa đọc" — người sửa key cùng lúc không bị đè. Máy chủ không mã hoá được (thiếu
            <c>Security:SecretKey</c>) thì dừng và cảnh báo, KHÔNG bao giờ ghi lại bản rõ. Log chỉ có số dòng, không có key.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.AiProviderKeyProtection.ProtectStoredKeysAsync(Lada.Framework.Data.Mappings.DbContexts.LadaDbContext,Lada.Framework.Infrastructures.Services.ISecretProtector,Microsoft.Extensions.Logging.ILogger,System.Threading.CancellationToken)">
            <returns>Số dòng đã chuyển.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.AI.IAiProviderService">
            <summary>
            Interface quản lý nhà cung cấp AI
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IAiProviderService.RevealApiKey(Lada.Framework.Data.Domains.AI.AiProvider)">
            <summary>
            API key bản rõ của một nhà cung cấp để gắn vào lời gọi — key lưu mã hoá trong DB (CNQ-1); rỗng khi không có hoặc
            không giải mã được. KHÔNG gán kết quả lại vào <see cref="P:Lada.Framework.Data.Domains.AI.AiProvider.ApiKey"/>: entity đang được theo dõi, một
            lần <c>UpdateAsync</c> sau đó sẽ ghi bản rõ xuống DB.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IAiProviderService.GenerateImageAsync(System.String,System.String,System.String,Ladaer.BackEnd.Infrastructures.Services.AI.BrandContextForImageGen,System.Boolean)">
            <summary>
            Tạo ảnh bằng OpenAI.
            Nếu có brandContext → dùng Responses API (POST /v1/responses) với tools image_generation + file_search.
            Nếu không có brandContext → fallback Images API (POST /v1/images/generations).
            Nếu enhancePrompt = true → prompt được LLM viết lại thành prompt tiếng Anh chi tiết trước khi tạo ảnh.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.AI.AiImageResult">
            <summary>Kết quả tạo ảnh AI</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.AI.AiImageResult.EnhancedPrompt">
            <summary>Prompt sau khi được LLM enhance (null nếu không enhance hoặc enhance thất bại)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.AI.AiModelInfo">
            <summary>
            Thông tin model AI trả về cho client
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.AI.SyncModelsResult">
            <summary>
            Kết quả sync models
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.AI.AiProviderService.CannotProtectKeyMessage">
            <summary>Thông báo khi máy chủ không mã hoá được key (thiếu <c>Security:SecretKey</c>) — không bao giờ lưu bản rõ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.AiProviderService.ProtectNewKey(System.String)">
            <summary>Key người dùng vừa nhập → bản mã hoá để ghi DB; ném khi key quá dài hoặc máy chủ không mã hoá được.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.AiProviderService.GenerateImageAsync(System.String,System.String,System.String,Ladaer.BackEnd.Infrastructures.Services.AI.BrandContextForImageGen,System.Boolean)">
            <summary>
            Tạo ảnh bằng OpenAI.
            Nếu có brandContext → dùng Responses API (POST /v1/responses) với tools.
            Nếu không có brandContext → fallback Images API cũ.
            Nếu enhancePrompt = true → prompt được LLM viết lại thành prompt tiếng Anh chi tiết trước khi tạo ảnh.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.AI.AiProviderService.EnhancePromptSystemMessage">
            <summary>System prompt cho bước enhance image prompt</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.AiProviderService.TryEnhanceImagePromptAsync(Lada.Framework.Data.Domains.AI.AiProvider,System.String)">
            <summary>
            Viết lại prompt tạo ảnh thành prompt tiếng Anh chi tiết bằng LLM (gpt-4.1-mini).
            Trả về null nếu thất bại — caller sẽ fallback về prompt gốc, không chặn việc tạo ảnh.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.AiProviderService.GenerateImageViaResponsesApiAsync(Lada.Framework.Data.Domains.AI.AiProvider,System.String,System.String,System.String,Ladaer.BackEnd.Infrastructures.Services.AI.BrandContextForImageGen,System.Diagnostics.Stopwatch)">
            <summary>
            Tạo ảnh qua Responses API (POST /v1/responses)
            Model orchestrator (gpt-4.1-mini/gpt-4.1) sẽ:
            1. Đọc developer instructions (luật brand cố định)
            2. Dùng file_search tra cứu brand guidelines từ Vector Store
            3. Xem ảnh tham chiếu (logo, xe tải, đồng phục) qua file_id
            4. Gọi tool image_generation để tạo ảnh phù hợp
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.AiProviderService.GenerateImageViaImagesApiAsync(Lada.Framework.Data.Domains.AI.AiProvider,System.String,System.String,System.String,System.Diagnostics.Stopwatch)">
            <summary>
            Fallback: Tạo ảnh qua Images API cũ (POST /v1/images/generations)
            Dùng khi không có brand context
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.AiProviderService.SyncAnthropicModelsAsync(Lada.Framework.Data.Domains.AI.AiProvider)">
            <summary>
            Gọi OpenAI API GET /v1/models để lấy danh sách models
            https://developers.openai.com/api/reference/resources/models/methods/list
            Thông tin chi tiết về các model xem ở 
            https://developers.openai.com/api/docs/models/compare
            </summary>
            <summary>
            Danh sách model của Anthropic qua SDK chính thức (cổng nhượng quyền GĐ G — màn Cấu hình trợ lý chọn model từ
            đây). Luôn gọi địa chỉ mặc định của SDK, không theo ô BaseUrl (mặc định của form là địa chỉ OpenAI).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.AI.BrandContextForImageGen">
            <summary>
            Kết quả trả về từ Brand Registry cho image generation
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.AI.IBrandRegistryService">
            <summary>
            Interface quản lý Brand Registry + Brand Assets trên OpenAI
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IBrandRegistryService.GetRegistryAsync">
            <summary>Lấy BrandRegistry hiện tại (singleton cho lada_express)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IBrandRegistryService.UpdateDeveloperInstructionsAsync(System.String)">
            <summary>Cập nhật developer instructions</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IBrandRegistryService.UploadAssetAsync(System.IO.Stream,System.String,System.String,System.String,System.String,System.String)">
            <summary>Upload file lên OpenAI Files API và lưu BrandAsset</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IBrandRegistryService.DeleteAssetAsync(System.Int32)">
            <summary>Xóa brand asset (cả trên OpenAI + DB)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IBrandRegistryService.GetActiveAssetsAsync">
            <summary>Lấy tất cả assets đang active</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IBrandRegistryService.GetImageAssetsAsync">
            <summary>Lấy chỉ image assets (cho image generation)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IBrandRegistryService.SyncVectorStoreAsync">
            <summary>Sync knowledge base MD files lên OpenAI Vector Store</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IBrandRegistryService.GetBrandContextForImageGenAsync">
            <summary>Lấy brand context cho image generation (developer instructions + file_ids + vector_store_id)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IBrandRegistryService.RegisterAssetFromOpenAiAsync(System.String,System.String,System.String,System.String,System.String)">
            <summary>Đăng ký file đã có trên OpenAI làm Brand Asset (không upload lại)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IBrandRegistryService.LinkVectorStoreAsync(System.String,System.String)">
            <summary>Gắn Vector Store ID đã có vào BrandRegistry làm Knowledge Base</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.AI.BrandRegistryService.DefaultDeveloperInstructions">
            <summary>Developer instructions mặc định nếu chưa cấu hình</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.BrandRegistryService.UploadToOpenAiFilesApiAsync(Lada.Framework.Data.Domains.AI.AiProvider,System.IO.Stream,System.String)">
            <summary>
            Upload file lên OpenAI Files API, trả về file_id
            POST /v1/files với multipart/form-data
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.BrandRegistryService.DeleteOpenAiFileAsync(Lada.Framework.Data.Domains.AI.AiProvider,System.String)">
            <summary>
            Xóa file trên OpenAI Files API
            DELETE /v1/files/{file_id}
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.AI.IKnowledgeBaseService">
            <summary>
            Service quản lý và truy xuất dữ liệu Knowledge Base cho RAG
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IKnowledgeBaseService.GetKnowledgeContextAsync">
            <summary>
            Lấy toàn bộ ngữ cảnh kiến thức từ các tài liệu trong thư mục knowledge
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.AI.IMarketingAgentService">
            <summary>
            Interface cho Marketing Agent Service
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IMarketingAgentService.GenerateBlogPostAsync(System.String,System.String,System.String)">
            <summary>Tạo bài blog từ brief</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IMarketingAgentService.GenerateSocialPostAsync(System.String,System.String,System.String)">
            <summary>Tạo bài social media từ brief</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IMarketingAgentService.ApproveContentAsync(System.Guid,System.Int32,System.String)">
            <summary>Duyệt nội dung</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IMarketingAgentService.RejectContentAsync(System.Guid,System.Int32,System.String)">
            <summary>Từ chối nội dung</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IMarketingAgentService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Tìm kiếm nội dung với SmartTableParam (search, filter, sort, pagination)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IMarketingAgentService.GetPendingReviewAsync">
            <summary>Lấy danh sách nội dung chờ duyệt</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IMarketingAgentService.GetByIdAsync(System.Guid)">
            <summary>Lấy nội dung theo ID</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.IMarketingAgentService.GetAvailableModels">
            <summary>Lấy danh sách AI models được hỗ trợ</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.AI.MarketingAgentService">
            <summary>
            Marketing Agent Service sử dụng Semantic Kernel để tạo nội dung marketing.
            Giai đoạn MVP: gọi LLM trực tiếp qua SK, chưa có RAG/MCP.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.AI.MarketingAgentService.LlmTimeout">
            <summary>Timeout cho một lần gọi LLM (không retry). Bài blog cần thời gian dài.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.AI.MarketingAgentService.DefaultModel">
            <summary>Model mặc định</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.MarketingAgentService.LoadPromptAsync(System.String)">
            <summary>
            Tải prompt template từ database theo category.
            Ném <see cref="T:System.InvalidOperationException"/> nếu không tìm thấy template active.
            Prompt KHÔNG dùng fallback hardcode — mọi thay đổi prompt phải qua DB.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.MarketingAgentService.CallLlmAsync(System.String,System.String,System.String,System.String,System.String)">
            <summary>
            Gọi LLM qua Semantic Kernel với logging
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.MarketingAgentService.GetAvailableModels">
            <summary>
            Xóa markdown code block nếu LLM bọc JSON trong ```json ... ```
            </summary>
            <summary>Lấy danh sách AI models được hỗ trợ</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.MarketingAgentService.ResolveModel(System.String)">
            <summary>Resolve model name — fallback về DefaultModel nếu không hợp lệ</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AI.MarketingAgentService.ExtractJsonField(System.String,System.String)">
            <summary>
            Trích xuất field từ JSON response
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.AI.OpenAiService">
            <summary>
            Legacy OpenAI service — giờ dùng Semantic Kernel IChatCompletionService.
            Giữ interface cũ để backward compatibility với AiController.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.AI.IPromptTemplateService">
            <summary>
            Interface quản lý các prompt template dùng cho AI
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsCallLogWriter">
            <summary>Ghi <see cref="T:Lada.Framework.Data.Domains.Analytics.AnalyticsCallLog"/> cho MỌI lời gọi tool số liệu (plan §3.10).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCallLogWriter">
            <summary>
            Ghi nhật ký bằng kết nối CHÍNH, mở riêng (không dùng DbContext của request): lời gọi đọc số liệu chạy trên kết nối
            chỉ đọc không ghi được, và một lỗi DbContext của request không được kéo nhật ký chết theo.
            </summary>
            <remarks>
            Chờ ghi xong (vài mili giây) thay vì fire-and-forget như plan ghi: fire-and-forget trong request dễ mất dòng khi
            request kết thúc sớm, và lỗi ghi đã được lớp nền tool nuốt + log nên câu trả lời không bao giờ hỏng vì nhật ký.
            Không dùng CancellationToken của request: trợ lý huỷ giữa chừng vẫn phải có dòng nhật ký.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCallLogWriter.MaxParamsLength">
            <summary>Độ dài tối đa của tham số lưu lại — khớp cột <c>ParamsJson nvarchar(4000)</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCallLogWriter.ToRow(Ladaer.BackEnd.Infrastructures.Mcp.McpToolCompletion,System.DateTimeOffset)">
            <summary>Dựng dòng nhật ký — tách riêng để test không cần DB.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCallLogWriter.SerializeParams(System.Collections.Generic.IDictionary{System.String,System.Text.Json.JsonElement})">
            <summary>Tham số JSON cắt ≤ <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCallLogWriter.MaxParamsLength"/> ký tự (kèm dấu cắt) — không bao giờ lưu nguyên một tham số dài.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFieldStatus">
            <summary>Mức độ có dữ liệu của một chiều / chỉ tiêu.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFieldStatus.Available">
            <summary>Đọc thẳng hoặc tính chắc chắn từ dữ liệu hệ thống.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFieldStatus.Estimated">
            <summary>Ước lượng theo một định nghĩa ghi rõ (ví dụ điểm dừng ĐD-1) — đọc kèm định nghĩa.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFieldStatus.Partial">
            <summary>Chỉ có một phần (ví dụ chỉ đơn từ một ngày trở đi) — phần thiếu trả null kèm cảnh báo.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDateField">
            <summary>Một cột ngày mà tool cho chọn qua tham số <c>date_field</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDateField.Column">
            <summary>Cột ngày trong bảng fact.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsJoin">
            <summary>Bảng danh mục mà biểu thức SQL của một chiều cần join thêm (alias cố định trong engine).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsJoin.SourceAgency">
            <summary><c>LEFT JOIN analytics.DimAgency sa ON sa.AgencyId = f.SourceAgencyId</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsJoin.DestAgency">
            <summary><c>LEFT JOIN analytics.DimAgency da ON da.AgencyId = f.DestAgencyId</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsJoin.Agency">
            <summary><c>LEFT JOIN analytics.DimAgency ag ON ag.AgencyId = f.AgencyId</c> — fact có MỘT cột bưu cục (điểm dừng, đổ dầu).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsJoin.Vehicle">
            <summary><c>LEFT JOIN analytics.DimVehicle vh ON vh.VehicleCode = f.VehicleCode</c> — mẫu xe, tải trọng của lần đổ dầu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension">
            <summary>Một chiều nhóm/lọc (<c>group_by</c>, <c>filters</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension.Code">
            <summary>Mã snake_case — thứ trợ lý truyền vào <c>group_by</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension.Type">
            <summary>Kiểu giá trị: date, week, month, int, string (mã đơn vị hành chính), text (chữ tự do), bool, enum, hashed_code, bin.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension.Column">
            <summary>Nguồn của chiều bằng lời (cột fact → cột nghiệp vụ) — tài liệu cho người đọc code; không trả cho trợ lý.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension.Sql">
            <summary>
            Biểu thức SQL <b>cố định trong code</b> trên bảng fact (alias <c>f</c>) và bảng join (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension.Join"/>) — thứ
            engine ghép vào câu truy vấn. <c>{date}</c> được thay bằng cột ngày của <c>date_field</c> (cũng lấy từ catalog).
            Null = chủ đề chưa mở hoặc chiều do engine tự dựng (<c>bac_can</c> theo <c>weight_bins</c>).
            Không bao giờ ghép chuỗi của người gọi vào đây — người gọi chỉ chọn MÃ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension.Join">
            <summary>Bảng danh mục cần join để tính <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension.Sql"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension.IsPersonCode">
            <summary>
            true = chiều lộ số của TỪNG NGƯỜI: mã băm của người (nhân viên, khách, lái xe) hoặc chiều mà nhóm thường chỉ có một người
            (<c>don_vi_sale</c> — đo GĐ E). Tắt được bằng AppConfig <c>Analytics.ExposePersonCodes</c> (câu hỏi Q3).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension.Lookup">
            <summary>Tên danh mục trong <c>describe_catalog.lists</c> để tra nhãn, nếu có.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension.Values">
            <summary>Giá trị liệt kê được (kiểu enum/bin).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric">
            <summary>Một chỉ tiêu (<c>metrics</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.Unit">
            <summary>
            Đơn vị: van_don, kien, kg, dong, ty_le, khach, diem, lai_xe_ngay, xe, lai_xe, lit, km, lan, lit_moi_100km, dong_moi_lit,
            dong_moi_km, cm3_per_kg, dong_gia, xa, theo_don_vi, vu, gio, luot, ngay.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.Definition">
            <summary>Định nghĩa nghiệp vụ bằng lời.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.Formula">
            <summary>Công thức trên cột nguồn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.Sql">
            <summary>
            Biểu thức gộp SQL <b>cố định trong code</b> trên các cột của bảng fact (không alias, vì engine gộp trên CTE chứa
            <c>f.*</c>). Null khi là phân vị (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.Percentile"/>) hoặc chủ đề chưa mở.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.Percentile">
            <summary>Phân vị (0–1) tính bằng <c>PERCENTILE_CONT … OVER (PARTITION BY nhóm)</c> trên <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.PercentileColumn"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.PercentileColumn">
            <summary>Cột fact của phân vị.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.PerPair">
            <summary>
            Chỉ tiêu HAI TẦNG (ví dụ "điểm dừng bình quân / lái xe / ngày"): engine gộp trước theo (nhóm, khoá cặp của chủ đề —
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.PairKeyColumns"/>) rồi mới bình quân / phân vị trên các cặp. <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.Sql"/> và
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.PercentileColumn"/> viết trên cột <c>[pv]</c> = giá trị của cặp, chỉ có ở MỘT dòng mỗi cặp (các dòng khác
            NULL — hàm gộp và <c>PERCENTILE_CONT</c> đều bỏ NULL).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.RanksPairs">
            <summary>
            Chỉ tiêu hai tầng cần HẠNG của cặp trong nhóm (ví dụ "tỷ trọng doanh thu 10 khách lớn nhất"): engine thêm cột <c>[prk]</c>
            = thứ hạng của cặp theo <c>[pv]</c> giảm dần trong từng nhóm (1 = lớn nhất; chỉ có ở dòng mang <c>[pv]</c>, còn lại NULL).
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.Sql"/> viết trên <c>[pv]</c> và <c>[prk]</c>; bắt buộc <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.PerPair"/>. Cặp bằng giá trị nhau xếp hạng tuỳ ý
            nhưng tổng của N cặp đầu không đổi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.DirectTable">
            <summary>
            Chỉ tiêu KHÔNG chạy trên engine mà thuộc một bảng tool đọc thẳng danh mục (ví dụ <c>doi_xe</c> của query_vehicles — đội xe
            hiện có, không kỳ). Engine từ chối nó kèm câu chỉ đúng bảng; null = chỉ tiêu của engine.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHistogramBin">
            <summary>Một nhóm của phân bố <c>histogram_of</c>: nhãn + cận trên (gồm); cận trên null = nhóm cuối "trên …".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHistogram">
            <summary>
            Một phân bố mà tool trả thay cho bảng chỉ tiêu khi có tham số <c>histogram_of</c> (yêu cầu §5 T2): đếm số lần một
            cặp (khoá, ngày) có bao nhiêu vận đơn, rồi xếp vào nhóm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHistogram.Code">
            <summary>Giá trị của tham số <c>histogram_of</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHistogram.BinCode">
            <summary>Mã cột nhóm trong <c>rows[]</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHistogram.PairCountCode">
            <summary>Mã cột "số lần" (số cặp khoá–ngày) trong <c>rows[]</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHistogram.ItemCountCode">
            <summary>Mã cột "số vận đơn" trong <c>rows[]</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHistogram.KeySql">
            <summary>Biểu thức SQL cố định của khoá cặp — mỗi dòng thiếu khoá thành một khoá riêng để tổng không hụt.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsUnavailableField">
            <summary>Chiều / chỉ tiêu / tham số yêu cầu có nêu nhưng hệ thống không có dữ liệu — ghi rõ vì sao.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsUnavailableField.Kind">
            <summary>chieu | chi_tieu | tham_so | bang.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsUnavailableField.Debt">
            <summary>Mã sổ nợ (AN-n) nếu có.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic">
            <summary>Một chủ đề số liệu = một tool truy vấn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.Tool">
            <summary>Tool phục vụ chủ đề.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.Stage">
            <summary>Giai đoạn mở tool (plan §4).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.Available">
            <summary>true khi tool đã chạy ở hợp đồng hiện tại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.Source">
            <summary>Bảng nguồn trong schema analytics.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.FactTable">
            <summary>Bảng fact SQL (tên đầy đủ, hằng trong code) mà engine truy vấn; null khi chủ đề chưa có engine.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.RowFilterSql">
            <summary>
            Điều kiện cố định (hằng trong code, alias <c>f</c>) áp lên MỌI câu của chủ đề cùng với kỳ và bộ lọc — ví dụ doanh thu bỏ đơn
            huỷ trên cùng bảng fact vận đơn. Null = không có.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.DefaultMetrics">
            <summary>Chỉ tiêu trả khi người gọi bỏ trống <c>metrics</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.Histograms">
            <summary>Phân bố nhận ở tham số <c>histogram_of</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.Diagnostics">
            <summary>
            Bộ đếm chẩn đoán (mã → biểu thức gộp SQL cố định) engine tính kèm mỗi lời gọi trên đúng tập dòng đã lọc — tool
            dùng để sinh <c>warnings[]</c> (ví dụ số đơn còn địa chỉ bộ 3 cấp). Không trả cho trợ lý.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.DiagnosticJoins">
            <summary>Bảng danh mục câu chẩn đoán cần join (biểu thức chẩn đoán viết trên alias <c>f</c>, <c>sa</c>, <c>da</c>, <c>ag</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.PairKeyColumns">
            <summary>
            Khoá cặp của chỉ tiêu hai tầng (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.PerPair"/>) — tên cột fact, ví dụ (<c>DriverCode</c>,
            <c>StopDate</c>) = một cặp lái xe – ngày. Rỗng = chủ đề không có chỉ tiêu hai tầng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.PairValueSql">
            <summary>Biểu thức SQL cố định (trên cột fact, không alias) mà mỗi dòng góp vào giá trị của cặp: giá trị cặp = SUM của nó.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.DirectRead">
            <summary>
            true = tool đọc thẳng các bảng danh mục (không kỳ, không nhóm) chứ không qua <c>AnalyticsQueryEngine</c> — ví dụ bảng
            giá. Khi đó <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.FactTable"/> null là đúng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog">
            <summary>
            <b>Từ điển số liệu cố định trong code</b> (docs/plan-mcp-tra-cuu-so-lieu.md §3.4) — nguồn sự thật duy nhất của
            chiều và chỉ tiêu: <c>describe_catalog</c> sinh từ đây, engine truy vấn (GĐ B) tra mã ở đây, nên mô tả và code
            không bao giờ lệch pha. Không tool nào nhận tên cột hay biểu thức từ người gọi — chỉ nhận MÃ trong lớp này.
            </summary>
            <remarks>
            <para>
            Định nghĩa bám plan §2.10 (đổi/bỏ so với yêu cầu), §3.5 (tiền, khối lượng, ngày) và §3.6 (điểm dừng ĐD-1).
            Đổi tên hay định nghĩa một mã thì nâng <c>AnalyticsMcpContract.Version</c> và sửa trong cùng commit.
            </para>
            <para>
            Lớp thuần, không DB — test <c>AnalyticsCatalogTests</c> canh: mã duy nhất trong chủ đề, snake_case, mọi chiều có
            cột, mọi chỉ tiêu có định nghĩa và công thức.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.TopicAliases">
            <summary>Mã chủ đề cũ của yêu cầu → mã thay thế (T4 query_trips → query_vehicles, plan §2.10).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.MaxRangeDays">
            <summary>Khoảng ngày tối đa một lời gọi (plan §1).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.MaxGroupBy">
            <summary>Số chiều tối đa trong <c>group_by</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.DefaultWeightBinsKg">
            <summary>Mốc mức cân mặc định (kg): ≤ 5; 5–10; 10–25; 25–50; 50–100; 100–300; 300–1.000; &gt; 1.000.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.DefaultWeightBinLabels">
            <summary>Nhãn các mức cân theo mốc mặc định — cũng là giá trị của chiều <c>bac_can</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.SaleAgencyPersonNote">
            <summary>
            Vì sao <c>don_vi_sale</c> theo công tắc mã người dù không phải mã băm — đo Việc 0 GĐ E (2026-09-26, dev): 22/58 cặp (đơn vị sale,
            tháng) chỉ có ĐÚNG một nhân viên kinh doanh, riêng đơn vị 29 có một sale suốt 13/13 tháng → doanh số theo đơn vị × tháng là
            doanh số (đầu vào hoa hồng) của một người mà ai trong công ty cũng biết là ai.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.FindTopic(System.String)">
            <summary>Tìm chủ đề theo mã (đã đổi alias). Null khi không có.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.AcceptedTopicCodes">
            <summary>Mọi mã chủ đề nhận được ở tham số <c>topic</c>, kể cả alias.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.AllCodes">
            <summary>Mọi mã chiều + chỉ tiêu (mọi chủ đề) — test hợp đồng dùng để kiểm mô tả tool không nhắc mã không tồn tại.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.ShipmentFactTable">
            <summary>Bảng fact vận đơn (GĐ B).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.HistogramOrdersPerCustomerDay">
            <summary>Mã phân bố "số vận đơn một khách gửi trong một ngày" của tham số histogram_of.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.ShipmentDiagnostics">
            <summary>Mã bộ đếm chẩn đoán của query_shipments (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.Diagnostics"/>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.StatusSql">
            <summary>
            <c>CASE f.Status WHEN 55 THEN 'delivered' …</c> sinh từ enum <see cref="T:Lada.Framework.Data.Enums.OrderStatus"/> — hằng trong code, cùng một
            luật snake_case với danh sách giá trị của chiều <c>trang_thai</c>.
            </summary>
            <remarks>
            Thuộc tính chứ KHÔNG phải trường <c>static readonly</c>: <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.Topics"/> khởi tạo trước mọi trường khai phía dưới
            nó trong lớp (thứ tự khởi tạo static theo vị trí), nên trường ở đây còn null lúc dựng catalog — đã cắn ở GĐ B.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.IsoWeekSql">
            <summary>Tuần ISO dạng <c>2026-W33</c>: năm ISO = năm của ngày (26 − số tuần ISO) ngày sau.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.TopCustomers">
            <summary>Số khách lớn nhất của chỉ tiêu <c>ty_trong_doanh_thu_10_khach_lon_nhat</c> — hằng trong SQL của chỉ tiêu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.RevenueDiagnostics">
            <summary>Mã bộ đếm chẩn đoán của query_revenue (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.Diagnostics"/>).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.ComplaintFactTable">
            <summary>Bảng fact khiếu nại (GĐ E).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.ClaimDiagnostics">
            <summary>Mã bộ đếm chẩn đoán của query_claims (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.Diagnostics"/>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.ComplaintTypeCodes">
            <summary>
            Loại sự cố của catalog theo enum <see cref="T:Lada.Framework.Data.Enums.ComplaintType"/> — yêu cầu §5 T7 nêu hu_hong | mat | cham | khac; hệ thống có thêm thái
            độ phục vụ và cước phí nên tách riêng (không gộp mất thông tin). Thuộc tính (không phải trường static readonly) vì khai sau
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.Topics"/>; test canh mọi giá trị enum có mã.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.ComplaintStatusCodes">
            <summary>Trạng thái khiếu nại của catalog theo enum <see cref="T:Lada.Framework.Data.Enums.ComplaintStatus"/> — test canh mọi giá trị có mã.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.EnumCaseSql``1(System.String,System.Collections.Generic.IReadOnlyDictionary{``0,System.String},System.String)">
            <summary><c>CASE f.&lt;cột&gt; WHEN 10 THEN 'hu_hong' … ELSE 'khac' END</c> sinh từ bảng mã — hằng trong code; null = ELSE NULL.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.HubEventFactTable">
            <summary>Bảng fact lượt qua trung tâm khai thác (GĐ E).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.HubDiagnostics">
            <summary>Mã bộ đếm chẩn đoán của query_hub_throughput (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.Diagnostics"/>).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.HubPairMetric(System.String,System.String,System.String,System.String,System.String,System.String,System.Nullable{System.Decimal})">
            <summary>Chỉ tiêu hai tầng trên cặp (nhóm, ngày) của trung tâm: biểu thức gộp trên <c>[pv]</c> hoặc phân vị của <c>pv</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.StopFactTable">
            <summary>Bảng fact điểm dừng ước lượng (GĐ C).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.DefaultStopGapMinutes">
            <summary>Ngưỡng phút mặc định của ĐD-1 khi AppConfig <c>Analytics.StopGapMinutes</c> thiếu hoặc sai.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.StopDiagnostics">
            <summary>Mã bộ đếm chẩn đoán của query_stops (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.Diagnostics"/>).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.StopCountBinSql">
            <summary>Nhóm số vận đơn tại điểm — nhãn cố định 1, 2, 3-5, 5+ (trên 5); không theo weight_bins.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.PairMetric(System.String,System.String,System.String,System.String,System.String,System.String,System.Nullable{System.Decimal})">
            <summary>Chỉ tiêu hai tầng trên cặp lái xe – ngày: biểu thức gộp trên <c>[pv]</c> hoặc phân vị của <c>pv</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.FuelFactTable">
            <summary>Bảng fact lần đổ dầu (GĐ D).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.VehicleTables">
            <summary>Giá trị tham số <c>table</c> của query_vehicles.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.VehicleTables.Fuel">
            <summary>Lần đổ dầu theo kỳ — engine trên <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.FuelFactTable"/> (mặc định).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.VehicleTables.Fleet">
            <summary>Đội xe hiện có — đọc thẳng <c>analytics.DimVehicle</c>, không kỳ.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.VehicleTables.FleetDimensions">
            <summary>Chiều nhóm được ở bảng <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.VehicleTables.Fleet"/> (thuộc tính của xe; không có chiều thời gian, trạng thái phiếu).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.FuelDiagnostics">
            <summary>Mã bộ đếm chẩn đoán của query_vehicles bảng nhien_lieu (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.Diagnostics"/>).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.FuelDiagnostics.MinDay">
            <summary>Ngày đổ sớm nhất của tập đã lọc, dạng số ngày kể từ 2000-01-01 (0 khi không dòng nào).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.FuelMinDayEpoch">
            <summary>Mốc của bộ đếm <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.FuelDiagnostics.MinDay"/>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.HeavyPayloadKg">
            <summary>Tải trọng khai trên mức này (kg) là bất thường với đội xe tải nhẹ — chỉ cảnh báo, không sửa số (ví dụ gõ 19 thay 1,9 tấn).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.HeavyPayloadKgSql">
            <summary><see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.HeavyPayloadKg"/> dạng số SQL — hằng chuỗi cạnh hằng số, test <c>AnalyticsVehiclesTests</c> canh hai giá trị khớp.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.FleetMetric(System.String,System.String,System.String,System.String,System.String)">
            <summary>Chỉ tiêu của bảng đội xe (đọc thẳng DimVehicle) — engine từ chối nó ở bảng nhien_lieu.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.PricesIncludeVat">
            <summary>
            Bảng giá công khai lưu giá <b>ĐÃ GỒM VAT</b> — đo Việc 0 GĐ C (2026-09-24) bằng code tính cước: mọi khoản phí của hệ thống
            là giá gồm VAT, VAT được bóc ngược ra thành dòng giải trình (<c>VatFeeCalculator</c>: "Mọi khoản phí trong hệ thống đang
            là giá đã gồm VAT"), và cước tuyến trên đơn (<c>OrderFin.Fee</c>, vốn gồm VAT) gán thẳng từ <c>Price.Value</c>
            (<c>FeeService.GetFeeByWeightAxis</c>). Trang tra cước công khai /bang-gia gọi đúng <c>FeeService.GetFee</c> đó.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.PriceTables">
            <summary>Giá trị tham số <c>table</c> của get_price_tables.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.ListedPriceRule">
            <summary>
            Cách ra cước từ bảng <c>niem_yet</c> — đúng luật <c>FeeService.GetFeeByWeightAxis</c> (test đối chiếu
            <c>GetPriceTablesDbTests</c> tính lại bằng chính FeeService). Trả trong <c>data.cach_tinh</c> và mô tả tool.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopicFreshness">
            <summary>Lượt nạp gần nhất của một chủ đề + lượt thành công gần nhất.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopicFreshness.LastLoadedAt">
            <summary>Lúc xong của lượt THÀNH CÔNG gần nhất — thứ trả ra <c>freshness.last_loaded_at</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopicFreshness.LastStatus">
            <summary>Trạng thái lượt gần nhất (kể cả lỗi).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopicFreshness.CoverFrom">
            <summary>Mốc đầu vùng phủ của lượt nạp lại cả cửa sổ THÀNH CÔNG gần nhất; null = chưa có lượt nào (fact thiếu lịch sử).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsVehicleRow.AgencyId">
            <summary>Đơn vị quản lý xe (<c>Truck.AgencyId</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsVehicleRow.BranchId">
            <summary>Chi nhánh của đơn vị đó; null = đơn vị không thuộc chi nhánh nào (0.3 trả nhầm AgencyId ở khoá này).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsVehicleRow.MaxPayloadKg">
            <summary>Null = chưa khai (0.3 trả 0 và trả nguyên số khai nhầm theo kg × 1.000).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsVehicleRow.PayloadBasis">
            <summary><see cref="T:Lada.Framework.Data.Domains.Analytics.AnalyticsPayloadBasis"/>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPriceSummaryRow">
            <summary>Tóm tắt bảng giá công khai theo (dải cự ly, loại hàng) — chi tiết là việc của get_price_tables.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalogLists">
            <summary>Mọi danh mục describe_catalog trả khi include_lists = true.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalogLists.Wards">
            <summary>Xã/phường của một tỉnh; null khi không xin tỉnh nào.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsCatalogReader">
            <summary>Đọc schema <c>analytics</c> cho describe_catalog.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsCatalogReader.ReadListsAsync(System.String,System.Threading.CancellationToken)">
            <param name="provinceCode">Mã tỉnh bộ 2 cấp để kèm danh sách xã/phường; null = không kèm.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalogReader">
            <summary>
            Đọc bằng Dapper qua <see cref="P:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.ReadConnectionString"/> — login chỉ đọc thành viên
            <c>db_analytics_reader</c> trên production, nên câu SQL nào lỡ chạm <c>dbo</c> sẽ lỗi quyền thay vì đọc được.
            SQL cố định, không ghép chuỗi từ người gọi; giá trị lọc duy nhất (mã tỉnh) đi qua tham số.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalogReader.CommandTimeoutSeconds">
            <summary>Trần thời gian một câu truy vấn (plan §1).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalogReader.ListsSql">
            <summary>Bảy danh mục, đúng thứ tự đọc ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalogReader.ReadListsAsync(System.String,System.Threading.CancellationToken)"/>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCodeKind">
            <summary>Loại đối tượng được băm — mỗi loại một tiền tố mã.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCodeKind.Customer">
            <summary>Khách hàng — <c>KH-</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCodeKind.Staff">
            <summary>Nhân viên (kinh doanh) — <c>NV-</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCodeKind.Driver">
            <summary>Lái xe / người bấm lấy–giao — <c>LX-</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCodeKind.Vehicle">
            <summary>Xe — <c>XE-</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsCodeHasher">
            <summary>
            Mã băm ổn định cho khách, nhân viên, lái xe, xe trong schema <c>analytics</c> (docs/plan-mcp-tra-cuu-so-lieu.md §3.2):
            <c>HMAC-SHA256(Analytics:CodeHashKey, "&lt;tiền tố&gt;:&lt;Id&gt;")</c> → 5 byte đầu → 8 ký tự base32, kèm tiền tố
            <c>KH-</c> / <c>NV-</c> / <c>LX-</c> / <c>XE-</c>.
            </summary>
            <remarks>
            <para>
            Có khoá bí mật nên người ngoài không băm thử Id 1..N để suy ngược được (SHA thuần thì được). Cùng Id + cùng loại →
            cùng mã qua mọi lần nạp; khác loại → khác mã dù cùng Id (một người vừa là sale vừa là lái xe mang hai mã).
            </para>
            <para>
            40 bit: với 10.000 khách xác suất trùng ~5·10⁻⁵ — đủ cho quy mô hiện tại. Đổi khoá = đổi toàn bộ mã (ghi trong catalog).
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCodeHasher.CodePattern">
            <summary>Hình dạng mọi mã băm — <c>PiiOutputGuard</c> dùng để không che nhầm chính mã của mình.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCodeHasher.Base32(System.Byte[],System.Int32)">
            <summary>Base32 RFC 4648 (không đệm) của <paramref name="byteCount"/> byte đầu — 5 byte = đúng 8 ký tự.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsClaimLoadResult">
            <summary>Kết quả một lượt nạp khiếu nại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsClaimLoadResult.OrderNotInFact">
            <summary>Khiếu nại gắn đơn nhưng đơn không có trong fact vận đơn (đơn đã xoá / ngoài cửa sổ) → không có bưu cục, kg.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsClaimLoadResult.Summary">
            <summary>Tóm tắt ghi vào <c>LoadRun.Message</c> (≤ 200 ký tự).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsComplaintFactBuilder">
            <summary>Nạp <c>analytics.ComplaintFact</c> (khiếu nại của khách).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsComplaintFactBuilder.BuildAsync(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadMode,System.Threading.CancellationToken)">
            <param name="mode">Chỉ để ghi nhật ký — MỌI lượt đều dựng lại cả cửa sổ 400 ngày.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsComplaintFactBuilder">
            <summary>
            Dựng <c>analytics.ComplaintFact</c> (docs/plan-mcp-tra-cuu-so-lieu.md §3.2, GĐ E) từ <c>dbo.CustomerComplaint</c> chưa xoá, gửi trong
            cửa sổ 400 ngày — nguồn của <c>query_claims</c> (chỉ số vụ: hệ thống không lưu tiền bồi thường, bên lỗi — AN-3).
            </summary>
            <remarks>
            <para>
            <b>Không đọc <c>Content</c>, <c>StaffResponse</c></b> (chữ tự do của khách / nhân viên), không mã khiếu nại, không khách. Khiếu nại
            không có cột đơn vị: bưu cục gửi / nhận + kg lấy từ fact vận đơn theo <c>OrderId</c> (chạy trước trong cùng job).
            </para>
            <para>
            Đo Việc 0 GĐ E (2026-09-26): bảng 0 dòng trên dev (phân hệ khiếu nại mở cho app khách, dev chưa có dữ liệu) → dựng lại cả cửa sổ
            mỗi lượt như <c>FuelFact</c>; số liệu thật chỉ có trên production.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsComplaintFactBuilder.ComplaintRow">
            <summary>Một khiếu nại đã chọn cột — đầu vào hàm thuần <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsComplaintFactBuilder.BuildRows(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsComplaintFactBuilder.ComplaintRow},System.Collections.Generic.IReadOnlyDictionary{System.Int32,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsOrderSnapshot},System.DateOnly,System.DateOnly,System.DateTimeOffset)"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsComplaintFactBuilder.ComplaintRow.#ctor(System.Int32,System.DateTimeOffset,System.Nullable{System.DateTimeOffset},Lada.Framework.Data.Enums.ComplaintType,Lada.Framework.Data.Enums.ComplaintStatus,System.Nullable{System.Int32})">
            <summary>Một khiếu nại đã chọn cột — đầu vào hàm thuần <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsComplaintFactBuilder.BuildRows(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsComplaintFactBuilder.ComplaintRow},System.Collections.Generic.IReadOnlyDictionary{System.Int32,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsOrderSnapshot},System.DateOnly,System.DateOnly,System.DateTimeOffset)"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsComplaintFactBuilder.BuildRows(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsComplaintFactBuilder.ComplaintRow},System.Collections.Generic.IReadOnlyDictionary{System.Int32,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsOrderSnapshot},System.DateOnly,System.DateOnly,System.DateTimeOffset)">
            <summary>Khiếu nại → dòng fact của cửa sổ: ngày giờ Việt Nam, giờ giải quyết, bưu cục + kg theo vận đơn. Hàm thuần (test không DB).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsDeployCheckService">
            <summary>
            Ảnh chụp trạng thái triển khai của MCP số liệu, đọc được <b>từ trình duyệt</b> (<c>GET api/Analytics/DeployCheck</c>, gác
            Founder) — thay cho mọi câu SQL tay trên <c>Ladaer2</c> production (ràng buộc 2026-08-27, như <c>ContentDeployCheckService</c>).
            </summary>
            <remarks>
            <para>
            <b>Mật thử login chỉ đọc chạy NGAY TRONG endpoint</b> (plan §3.9 "GĐ D"): mở <c>ConnectionStrings:AnalyticsConnection</c> —
            đúng kết nối mà tool dùng — rồi đọc <c>analytics.LoadRun</c> (phải được) và <c>dbo.Customer</c> (phải lỗi 229). Người triển
            khai đọc hai cờ thay vì tự đăng nhập bằng login đó vào SQL client.
            </para>
            <para>
            <b>Số đo Việc 0 production</b> (plan §4.2, AN-18) đọc qua CHÍNH kết nối chỉ đọc trên schema <c>analytics</c>: kênh bán 12 tháng,
            số xã có phụ phí khu vực xa, dòng tham số cước, đội xe, số lần đổ dầu — nên có số mà không ai phải mở <c>dbo</c>.
            </para>
            <para>
            <b>Không lộ gì nhạy cảm</b>: chỉ số đếm, cờ, tên login SQL, URL công khai. Không trả chuỗi kết nối, không trả khoá băm, không
            danh sách người. Test <c>AnalyticsDeployCheckTests</c> canh.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsDeployCheckService.CheckAsync(System.Threading.CancellationToken)">
            <summary>Đọc trạng thái triển khai. Không ghi một dòng nào.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCheckService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsDeployCheckService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCheckService.AnalyticsTables">
            <summary>Bảng của schema analytics mà migration GĐ A–E tạo — liệt kê tường minh để bảng THIẾU vẫn hiện ra (-1).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCheckService.LoadTopics">
            <summary>Chủ đề nạp mà tool đọc độ tươi — mỗi chủ đề một dòng trạng thái.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCheckService.ConfigKeys">
            <summary>Khoá AppConfig ảnh hưởng hành vi MCP số liệu (giá trị không nhạy cảm).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCheckService.PermissionDeniedError">
            <summary>Lỗi SQL Server "The SELECT permission was denied" — thứ login chỉ đọc PHẢI nhận khi đọc dbo.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCheckService.DescribeSettings(Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings,Ladaer.BackEnd.Infrastructures.Mcp.McpSurface)">
            <summary>Cấu hình đang chạy, dạng an toàn để in: cờ, không chuỗi kết nối, không khoá.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCheckService.CheckReadLoginAsync(System.Threading.CancellationToken)">
            <summary>
            Mọi thứ đọc qua kết nối CHỈ ĐỌC: danh tính login, quyền (analytics được, dbo bị 229), số dòng từng bảng, lượt nạp, số đo
            Việc 0. Kết nối hỏng thì trả lỗi trong <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployReadLogin.Error"/>, không ném.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCheckService.ReadSurveyAsync(Microsoft.Data.SqlClient.SqlConnection,System.Threading.CancellationToken)">
            <summary>Số đo Việc 0 trên production (plan §4.2 GĐ D mục 4) — chỉ đọc schema analytics, chỉ số tổng hợp.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCheckService.CountRoleAsync(System.Threading.CancellationToken)">
            <summary>Role <c>Analytics.Read</c> đã seed chưa và bao nhiêu người đang có (gán thẳng hoặc qua nhóm quyền) — không trả tên.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCheckService.CountOAuthClientsAsync(System.Threading.CancellationToken)">
            <summary>Client OAuth (DCR + khai tay) và bao nhiêu client đã có quyền scope <c>analytics:read</c> — backfill migration 1705.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCheck.Enabled">
            <summary><c>Analytics:Enabled</c> — tắt thì tool trả UNAVAILABLE và job nạp bỏ qua.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCheck.Tables">
            <summary>Số dòng từng bảng analytics; -1 = bảng chưa có (migration chưa chạy) hoặc login chỉ đọc không đọc được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCheck.Survey">
            <summary>Số đo Việc 0 production; null khi chưa đọc được (bảng chưa có / login lỗi).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployReadLogin">
            <param name="Login">SUSER_SNAME() của kết nối chỉ đọc — production phải là <c>lada_analytics_ro</c>.</param>
            <param name="DatabaseUser">USER_NAME() trong Ladaer2.</param>
            <param name="IsReaderMember">Thành viên <c>db_analytics_reader</c>.</param>
            <param name="CanReadAnalytics">Đọc được <c>analytics.LoadRun</c>.</param>
            <param name="DboDenied">Đọc <c>dbo.Customer</c> bị lỗi 229 — hàng rào lớp 4 (plan §1).</param>
            <param name="DboErrorNumber">Số lỗi SQL khi đọc dbo (229 là đúng); null khi đọc được.</param>
            <param name="Error">Không mở được kết nối chỉ đọc (loại lỗi + số lỗi, không chuỗi kết nối).</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployReadLogin.#ctor(System.String,System.String,System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Boolean},System.Nullable{System.Int32},System.String)">
            <param name="Login">SUSER_SNAME() của kết nối chỉ đọc — production phải là <c>lada_analytics_ro</c>.</param>
            <param name="DatabaseUser">USER_NAME() trong Ladaer2.</param>
            <param name="IsReaderMember">Thành viên <c>db_analytics_reader</c>.</param>
            <param name="CanReadAnalytics">Đọc được <c>analytics.LoadRun</c>.</param>
            <param name="DboDenied">Đọc <c>dbo.Customer</c> bị lỗi 229 — hàng rào lớp 4 (plan §1).</param>
            <param name="DboErrorNumber">Số lỗi SQL khi đọc dbo (229 là đúng); null khi đọc được.</param>
            <param name="Error">Không mở được kết nối chỉ đọc (loại lỗi + số lỗi, không chuỗi kết nối).</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployReadLogin.Login">
            <summary>SUSER_SNAME() của kết nối chỉ đọc — production phải là <c>lada_analytics_ro</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployReadLogin.DatabaseUser">
            <summary>USER_NAME() trong Ladaer2.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployReadLogin.IsReaderMember">
            <summary>Thành viên <c>db_analytics_reader</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployReadLogin.CanReadAnalytics">
            <summary>Đọc được <c>analytics.LoadRun</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployReadLogin.DboDenied">
            <summary>Đọc <c>dbo.Customer</c> bị lỗi 229 — hàng rào lớp 4 (plan §1).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployReadLogin.DboErrorNumber">
            <summary>Số lỗi SQL khi đọc dbo (229 là đúng); null khi đọc được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployReadLogin.Error">
            <summary>Không mở được kết nối chỉ đọc (loại lỗi + số lỗi, không chuỗi kết nối).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployLoadRun.CoverFrom">
            <summary>Mốc phủ của lượt nạp lại thành công gần nhất — null với chủ đề fact nghĩa là tool còn trả NO_DATA.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeploySurvey">
            <param name="SalesChannels12Months">Kênh bán của đơn tạo trong 12 tháng (AN-18: dev 100 % buu_cuc).</param>
            <param name="RemoteSurchargeWards">Xã/phường có phụ phí khu vực xa (dev 0).</param>
            <param name="FeeConfigs">Dòng tham số cước (dev chỉ DEFAULT_GOODS_CATEGORY_ID).</param>
            <param name="HubEvents12Months">Lượt qua trung tâm 12 tháng theo "trung tâm:chiều" (GĐ E).</param>
            <param name="HubEventsByActor12Months">Lượt có trung tâm suy từ người thao tác — nhật ký kho không ghi đơn vị (AN-25).</param>
            <param name="Complaints12Months">Khiếu nại 12 tháng theo giá trị số của ComplaintType (dev 0 dòng).</param>
            <param name="SaleAgencyMonths12Months">Số cặp (đơn vị sale, tháng) có đơn gắn sale.</param>
            <param name="SaleAgencyMonthsSingleSale">Trong đó chỉ có MỘT nhân viên kinh doanh — số theo don_vi_sale × tháng là số của một người
            (dev 22/58 — lý do don_vi_sale theo công tắc mã người).</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeploySurvey.#ctor(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCount},System.Int32,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployFeeConfig},System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCount},System.Int32,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeployCount},System.Int32,System.Int32)">
            <param name="SalesChannels12Months">Kênh bán của đơn tạo trong 12 tháng (AN-18: dev 100 % buu_cuc).</param>
            <param name="RemoteSurchargeWards">Xã/phường có phụ phí khu vực xa (dev 0).</param>
            <param name="FeeConfigs">Dòng tham số cước (dev chỉ DEFAULT_GOODS_CATEGORY_ID).</param>
            <param name="HubEvents12Months">Lượt qua trung tâm 12 tháng theo "trung tâm:chiều" (GĐ E).</param>
            <param name="HubEventsByActor12Months">Lượt có trung tâm suy từ người thao tác — nhật ký kho không ghi đơn vị (AN-25).</param>
            <param name="Complaints12Months">Khiếu nại 12 tháng theo giá trị số của ComplaintType (dev 0 dòng).</param>
            <param name="SaleAgencyMonths12Months">Số cặp (đơn vị sale, tháng) có đơn gắn sale.</param>
            <param name="SaleAgencyMonthsSingleSale">Trong đó chỉ có MỘT nhân viên kinh doanh — số theo don_vi_sale × tháng là số của một người
            (dev 22/58 — lý do don_vi_sale theo công tắc mã người).</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeploySurvey.SalesChannels12Months">
            <summary>Kênh bán của đơn tạo trong 12 tháng (AN-18: dev 100 % buu_cuc).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeploySurvey.RemoteSurchargeWards">
            <summary>Xã/phường có phụ phí khu vực xa (dev 0).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeploySurvey.FeeConfigs">
            <summary>Dòng tham số cước (dev chỉ DEFAULT_GOODS_CATEGORY_ID).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeploySurvey.HubEvents12Months">
            <summary>Lượt qua trung tâm 12 tháng theo "trung tâm:chiều" (GĐ E).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeploySurvey.HubEventsByActor12Months">
            <summary>Lượt có trung tâm suy từ người thao tác — nhật ký kho không ghi đơn vị (AN-25).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeploySurvey.Complaints12Months">
            <summary>Khiếu nại 12 tháng theo giá trị số của ComplaintType (dev 0 dòng).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeploySurvey.SaleAgencyMonths12Months">
            <summary>Số cặp (đơn vị sale, tháng) có đơn gắn sale.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDeploySurvey.SaleAgencyMonthsSingleSale">
            <summary>Trong đó chỉ có MỘT nhân viên kinh doanh — số theo don_vi_sale × tháng là số của một người
            (dev 22/58 — lý do don_vi_sale theo công tắc mã người).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimLoadResult">
            <summary>Kết quả một lượt nạp danh mục.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimLoadResult.Summary">
            <summary>Tóm tắt ghi vào <c>LoadRun.Message</c> (≤ 200 ký tự).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsDimBuilder">
            <summary>Nạp bảy bảng <c>analytics.Dim*</c> từ bảng nghiệp vụ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimBuilder">
            <summary>
            Bản sao đêm của danh mục cho MCP số liệu (docs/plan-mcp-tra-cuu-so-lieu.md §3.3): đọc bảng nghiệp vụ bằng kết nối
            CHÍNH (job là ngoại lệ duy nhất được đọc <c>dbo</c>), chỉ chép cột công khai, rồi <b>xoá–chèn cả bảy bảng trong
            một transaction</b> — chạy lại bao nhiêu lần cũng ra một bộ, và người đọc không bao giờ thấy danh mục nửa cũ nửa mới.
            </summary>
            <remarks>
            <para>
            Lọc có chủ đích: <c>DimVehicle</c> không biển số, không Id hệ thống (chỉ mã băm <c>XE-…</c>); <c>DimPrice</c> chỉ
            dòng giá của khách mặc định chưa xoá và duy nhất (luật <c>DefaultCustomerResolver</c> — bảng giá công khai; đo dev
            2026-09-24: 114 dòng chưa xoá thuộc khách Id 4 "LADA Express"); <c>DimAgency</c> không địa chỉ/điện thoại/mã số thuế.
            </para>
            <para>
            Đơn vị: khối lượng bảng giá gram → kg, cự ly <c>Route</c> mét → km, tải trọng xe tấn → kg. Chi nhánh bị xoá mềm và
            xe đã xoá vẫn chép (đánh dấu <c>IsActive = false</c>) vì đơn/lần đổ dầu cũ còn trỏ tới chúng.
            </para>
            <para>
            Mỗi lượt ghi một dòng <see cref="T:Lada.Framework.Data.Domains.Analytics.AnalyticsLoadRun"/> chủ đề <see cref="F:Lada.Framework.Data.Domains.Analytics.AnalyticsLoadTopics.Dimensions"/> TRƯỚC khi mở
            transaction (dòng "running" không bị rollback cuốn mất), cập nhật thành success/failed khi xong
            (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsLoadRunRecorder"/>). Mã đơn vị hành chính chuẩn hoá số 0 đầu (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsAdminCodes"/>).
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimBuilder.PayloadEnteredAsKgFromTonnes">
            <summary>Số ở cột tấn từ mức này trở lên là nhập nhầm theo kg — không xe nào của đội chở 100 tấn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimBuilder.PayloadKg(System.Decimal)">
            <summary>
            <c>Truck.MaxPayload</c> (tấn theo quy ước cột) → kg + căn cứ. Việc 0 GĐ D (2026-09-26, dev): 5/26 xe nhập theo kg (990 Tera
            T100, 2.350 Kia K250, 3.400 JAC N350 ×2, 4.700 Fuso Canter — đúng tải trọng thương mại của các mẫu đó tính bằng kg) nên nhân
            1.000 là ra 4,7 triệu kg; 8/26 xe để 0 (chưa khai) → null chứ không phải xe chở 0 kg.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFleetVehicle">
            <summary>Một xe của đội xe hiện có (bản chụp đêm <c>analytics.DimVehicle</c>) — không biển số.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFleetVehicle.BranchId">
            <summary>Chi nhánh của đơn vị quản lý xe (<c>DimAgency.BranchId</c>); null = đơn vị không thuộc chi nhánh nào.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsFleetReader">
            <summary>Đọc đội xe hiện có cho bảng <c>doi_xe</c> của query_vehicles.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFleetReader">
            <summary>
            Một câu cố định trên <c>analytics.DimVehicle</c> + <c>DimAgency</c> bằng kết nối CHỈ ĐỌC — không nhận gì của người gọi; nhóm
            theo chiều làm ở C# (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFleetSummary"/>) vì đội xe chỉ vài chục dòng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFleetSummary">
            <summary>
            Gộp đội xe theo các chiều của bảng <c>doi_xe</c> (<see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog.VehicleTables.FleetDimensions"/>) — hàm thuần,
            test được không DB. Khoá dòng = mã chiều / chỉ tiêu của catalog.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFleetSummary.DimensionValue(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFleetVehicle,System.String)">
            <summary>Giá trị của một chiều ở một xe (kiểu như engine trả: int, chuỗi, null).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFleetSummary.MetricValue(System.Collections.Generic.IReadOnlyCollection{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFleetVehicle},System.String)">
            <summary>Giá trị một chỉ tiêu trên một nhóm xe.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFleetSummary.Summarize(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFleetVehicle},System.Collections.Generic.IReadOnlyList{System.String},System.Collections.Generic.IReadOnlyList{System.String})">
            <summary>Dòng theo nhóm (sắp tăng dần theo các chiều, null trước) + dòng tổng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFleetSummary.KeyComparer">
            <summary>So từng chiều: null trước, số theo số, chữ theo thứ tự ordinal — tất định.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelLoadResult">
            <summary>Kết quả một lượt nạp lần đổ dầu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelLoadResult.Pending">
            <summary>Phiếu chờ duyệt (vẫn nạp — việc đổ đã xảy ra; số có thể còn được sửa).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelLoadResult.Rejected">
            <summary>Phiếu bị từ chối — không nạp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelLoadResult.Duplicates">
            <summary>Phiếu nghi gửi trùng đã bỏ (trong cửa sổ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelLoadResult.Summary">
            <summary>Tóm tắt ghi vào <c>LoadRun.Message</c> (≤ 200 ký tự).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsFuelFactBuilder">
            <summary>Nạp <c>analytics.FuelFact</c> (lần đổ dầu của đội xe).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsFuelFactBuilder.BuildAsync(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadMode,System.Threading.CancellationToken)">
            <param name="mode">Chỉ để ghi nhật ký — MỌI lượt đều dựng lại cả cửa sổ 400 ngày (bảng nhỏ, xem remarks của lớp).</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelFactBuilder">
            <summary>
            Dựng <c>analytics.FuelFact</c> (docs/plan-mcp-tra-cuu-so-lieu.md §3.2, GĐ D) từ <c>dbo.FuelRefills</c> chưa xoá, trừ phiếu bị từ
            chối — nguồn bảng <c>nhien_lieu</c> của <c>query_vehicles</c>.
            </summary>
            <remarks>
            <para>
            <b>Mỗi lượt dựng lại CẢ cửa sổ 400 ngày</b> (xoá–chèn trong một transaction), kể cả job đêm: đo Việc 0 GĐ D (2026-09-26, dev)
            cả bảng nghiệp vụ chỉ 1.447 phiếu (01/2026 → 08/2026, ~200 phiếu/tháng) nên dựng lại toàn bộ rẻ hơn theo dõi phiếu nào vừa
            sửa (mọi phiếu đều có <c>UpdatedTime</c>; duyệt / tính lại chuỗi ODO sửa phiếu cũ). Hệ quả: lượt thành công nào cũng phủ đủ
            cửa sổ nên cũng ghi mốc phủ (<c>CoverFrom</c>) — khác fact vận đơn / điểm dừng chỉ lượt nạp lại mới ghi.
            </para>
            <para>
            <b>Phiếu gửi trùng</b> (cùng xe, cùng ODO, cùng số tiền — lái xe bấm gửi hai lần; review GĐ D đo dev 4 nhóm, có nhóm chờ duyệt
            8 tháng không ai dọn, có nhóm cả hai bản đã duyệt) chỉ giữ MỘT phiếu (ưu tiên đã duyệt, rồi Id nhỏ), ghi số bản đã bỏ vào
            <see cref="P:Lada.Framework.Data.Domains.Analytics.AnalyticsFuelFact.DroppedDuplicates"/> để tool cảnh báo.
            </para>
            <para>
            <b>Km theo ODO dựng từ chuỗi <c>CurrentOdo</c></b> của xe theo thời gian (sau khi bỏ trùng): km = ODO nay − ODO phiếu liền trước;
            phiếu đầu của xe dùng ODO lúc nhận xe (<c>PreviousOdo</c> &gt; 0) nếu có. KHÔNG dùng <c>FuelRefill.DistanceKm</c>: trường đó bị khoá
            theo kỳ lương (<c>IsPayrollLocked</c>) nên phiếu chèn muộn làm hai phiếu cùng tính một quãng — review GĐ D đo dev: Σ DistanceKm
            vượt khoảng ODO thật ở 4 xe, tổng lệch 1.255 km. Bỏ km (null + <see cref="T:Lada.Framework.Data.Domains.Analytics.AnalyticsOdoIssues"/>) khi không có ODO trước, km ≤ 0,
            hoặc km &gt; <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelFactBuilder.MaxDistanceKm"/> (thiếu phiếu ở giữa / ODO gõ nhầm). KHÔNG loại theo lít/100 km của từng phiếu: đổ không
            đầy bình làm từng phiếu lệch nhưng tổng lít ÷ tổng km trên chuỗi phiếu vẫn đúng — loại một phía là thiên lệch.
            </para>
            <para>
            <b>Tiền giữ nguyên số trên phiếu (ĐÃ GỒM THUẾ)</b>: phiếu nhập số tiền + đơn giá tại cây xăng, không lưu thuế suất hay hoá đơn
            tách VAT, và thuế suất VAT nhiên liệu đổi theo kỳ trong 2025–2026 — bóc bằng một hằng tự đặt là bịa số (plan §7 GĐ D, AN-22).
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelFactBuilder.MaxDistanceKm">
            <summary>Km giữa hai lần đổ vượt mức này thì không dùng (≈ 3 bình dầu của xe tải nhẹ).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelFactBuilder.FuelRefillRow">
            <summary>Một phiếu đổ dầu đã chọn cột — đầu vào hàm thuần <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelFactBuilder.BuildRows(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelFactBuilder.FuelRefillRow},System.Collections.Generic.IReadOnlyDictionary{System.Int32,System.Int32},System.DateOnly,System.DateOnly,System.DateTimeOffset)"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelFactBuilder.FuelRefillRow.#ctor(System.Int32,System.Int32,System.Int32,System.DateTimeOffset,System.Decimal,System.Decimal,System.Int32,System.Int32,Lada.Framework.Data.Enums.FuelRefillStatus)">
            <summary>Một phiếu đổ dầu đã chọn cột — đầu vào hàm thuần <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelFactBuilder.BuildRows(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelFactBuilder.FuelRefillRow},System.Collections.Generic.IReadOnlyDictionary{System.Int32,System.Int32},System.DateOnly,System.DateOnly,System.DateTimeOffset)"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelFactBuilder.BuildRows(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelFactBuilder.FuelRefillRow},System.Collections.Generic.IReadOnlyDictionary{System.Int32,System.Int32},System.DateOnly,System.DateOnly,System.DateTimeOffset)">
            <summary>
            Phiếu (mọi thời điểm, chưa xoá) → dòng fact của cửa sổ [<paramref name="from"/>, <paramref name="to"/>]: bỏ phiếu từ chối, gộp
            phiếu gửi trùng, dựng km từ chuỗi ODO từng xe, băm mã, ngày giờ Việt Nam. Hàm thuần theo dữ liệu đầu vào (test không DB).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFuelFactBuilder.OdoIssueOf(System.Nullable{System.Int32},System.Int32)">
            <summary>Luật dùng km của một phiếu theo ODO trước (null = không có) — xem remarks của lớp.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubLoadResult">
            <summary>Kết quả một lượt nạp lượt qua trung tâm khai thác.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubLoadResult.Hubs">
            <summary>Trung tâm khai ở AppConfig lúc nạp (rỗng = chưa khai → bảng rỗng).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubLoadResult.ByActor">
            <summary>Dòng có trung tâm suy từ đơn vị người thao tác (nhật ký không ghi đơn vị).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubLoadResult.LeftForDelivery">
            <summary>Lượt đến kết thúc vì hàng được gán giao (trung tâm phát thẳng).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubLoadResult.Summary">
            <summary>Tóm tắt ghi vào <c>LoadRun.Message</c> (≤ 200 ký tự) — khoá <c>hubs=</c> được tool đọc lại để so với AppConfig hiện tại.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsHubEventFactBuilder">
            <summary>Nạp <c>analytics.HubEventFact</c> (lượt hàng đến / rời trung tâm khai thác).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsHubEventFactBuilder.BuildAsync(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadMode,System.Threading.CancellationToken)">
            <param name="mode">Chỉ để ghi nhật ký — MỌI lượt đều dựng lại cả cửa sổ 400 ngày (xem remarks của lớp).</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder">
            <summary>
            Dựng <c>analytics.HubEventFact</c> (docs/plan-mcp-tra-cuu-so-lieu.md §3.2, GĐ E) từ nhật ký đơn <c>OrderTrack</c> loại Nhận hàng
            vào kho (7) và Chuyển hàng tới bưu cục kế tiếp (8) tại các trung tâm khai ở AppConfig <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder.HubAgencyIdsConfigKey"/> — nguồn
            của <c>query_hub_throughput</c>.
            </summary>
            <remarks>
            <para>
            <b>Đơn vị của lượt</b>: <c>OrderTrack.AgencyId</c> khi có; không có thì đơn vị HIỆN TẠI của người thao tác (<c>CreatedBy</c> →
            <c>User.AgencyId</c>). Đo Việc 0 GĐ E (2026-09-26, dev): mọi lượt 7/8 từ 23/05/2026 có <c>AgencyId</c> NULL (<c>WarehouseService</c>,
            <c>DeployService</c> hiện không ghi — AN-25); trên dữ liệu còn ghi, đơn vị người thao tác trùng 98,9 % lượt nhập / 99,5 % lượt xuất
            (lệch duy nhất: một người chuyển 29 → 27). Đơn vị của nhật ký 8 là nơi ĐANG xuất hàng đi (đo cả code lẫn chuỗi nhật ký).
            </para>
            <para>
            <b>Máy trạng thái trên chuỗi của mỗi (vận đơn, trung tâm)</b>, sắp theo (thời điểm, loại — nhập, rồi xuất, rồi gán giao khi trùng
            giờ); trạng thái chỉ phụ thuộc loại của sự kiện liền trước (câu <c>LAG</c> độc lập kiểm được): nhập khi hàng chưa ở kho → dòng
            <c>den</c> mở lượt lưu kho; nhập khi đã ở kho → quét lặp; xuất khi hàng ở kho → dòng <c>di</c>, ghi <c>DwellHours</c> vào dòng
            <c>den</c>; <b>gán giao hàng (205) khi hàng ở kho → đóng lượt</b>, dòng <c>den</c> mang <c>LeftForDelivery</c>, không giờ lưu kho;
            xuất khi không ở kho → quét xuất lặp nếu sự kiện trước là xuất, ngược lại "đi thẳng" (dòng <c>di</c> không có nhập — đo dev 2,1 %
            lượt xuất tại 29). Mốc gán giao là của VẬN ĐƠN (không theo đơn vị) nên chèn vào mọi chuỗi trung tâm của đơn đó. Review GĐ E: thiếu mốc
            này thì hàng giao lỗi quay về trung tâm bị nuốt thành quét lặp (đo dev: 881/1.155 cặp nhập–nhập cách ≤ 12 giờ và gần như mọi cặp cách
            &gt; 24 giờ có lượt gán giao ở giữa) và lượt xuất sau đó đóng lượt lưu kho CŨ — giờ lưu kho bị thổi lên hàng trăm giờ. Đọc lùi thêm
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder.LookbackDays"/> ngày trước cửa sổ để lượt đầu cửa sổ biết hàng đã nhập từ trước.
            </para>
            <para>
            <b>Dựng lại CẢ cửa sổ mỗi lượt</b> (như <c>FuelFact</c>): ~70.000 lượt / năm, và danh sách trung tâm đổi trên AppConfig chỉ cần một
            lượt nạp là đúng lại toàn bộ. Bưu cục gửi / nhận, kg lấy từ fact vận đơn (chạy trước trong cùng job) — một nguồn luật với
            <c>query_shipments</c>.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder.HubAgencyIdsConfigKey">
            <summary>Khoá AppConfig liệt kê Id đơn vị là trung tâm khai thác (quyết định Q7).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder.LookbackDays">
            <summary>Số ngày đọc lùi trước cửa sổ để biết hàng đã ở kho từ trước (đo dev: p99 lưu kho 25 giờ, max 20 ngày).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder.ParseHubIds(System.String)">
            <summary>Danh sách Id trung tâm từ giá trị AppConfig ("29,25" — phẩy, chấm phẩy hoặc khoảng trắng); bỏ giá trị không phải số dương.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder.HubTrackRow">
            <summary>Một dòng nhật ký nhập / xuất kho / gán giao đã chọn cột — đầu vào hàm thuần <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder.BuildRows(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder.HubTrackRow},System.Collections.Generic.IReadOnlyDictionary{System.Int32,System.Int32},System.Collections.Generic.IReadOnlySet{System.Int32},System.Collections.Generic.IReadOnlyDictionary{System.Int32,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsOrderSnapshot},System.DateOnly,System.DateOnly,System.DateTimeOffset)"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder.HubTrackRow.#ctor(System.Int32,Lada.Framework.Data.Enums.TrackActionType,System.DateTimeOffset,System.Nullable{System.Int32},System.Int32)">
            <summary>Một dòng nhật ký nhập / xuất kho / gán giao đã chọn cột — đầu vào hàm thuần <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder.BuildRows(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder.HubTrackRow},System.Collections.Generic.IReadOnlyDictionary{System.Int32,System.Int32},System.Collections.Generic.IReadOnlySet{System.Int32},System.Collections.Generic.IReadOnlyDictionary{System.Int32,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsOrderSnapshot},System.DateOnly,System.DateOnly,System.DateTimeOffset)"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder.EventOrder(Lada.Framework.Data.Enums.TrackActionType)">
            <summary>Thứ tự khi trùng thời điểm: nhập, rồi xuất, rồi gán giao (hàng vào kho rồi mới rời được).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder.BuildRows(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder.HubTrackRow},System.Collections.Generic.IReadOnlyDictionary{System.Int32,System.Int32},System.Collections.Generic.IReadOnlySet{System.Int32},System.Collections.Generic.IReadOnlyDictionary{System.Int32,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsOrderSnapshot},System.DateOnly,System.DateOnly,System.DateTimeOffset)">
            <summary>
            Nhật ký (từ trước cửa sổ <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHubEventFactBuilder.LookbackDays"/> ngày) → dòng fact của cửa sổ [<paramref name="from"/>, <paramref name="to"/>] tại
            các trung tâm <paramref name="hubs"/>: đơn vị của lượt, máy trạng thái lưu kho, giờ lưu kho, bưu cục gửi/nhận + kg từ fact vận
            đơn. Hàm thuần theo dữ liệu đầu vào (test không DB).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsOrderSnapshot">
            <summary>Phần của fact vận đơn mà fact trung tâm / khiếu nại cần: bưu cục gửi, nhận, kg tính cước.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsOrderSnapshot.#ctor(System.Int32,System.Int32,System.Int32,System.Decimal)">
            <summary>Phần của fact vận đơn mà fact trung tâm / khiếu nại cần: bưu cục gửi, nhận, kg tính cước.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsOrderSnapshot.ReadAllAsync(Lada.Framework.Data.Mappings.DbContexts.LadaDbContext,System.Threading.CancellationToken)">
            <summary>
            Cả bảng fact vận đơn (4 cột; ~32.000 dòng trên dev 2026-09-26) — một câu, thay vì lọc theo danh sách Id. Đọc SAU khi fact vận đơn
            của cùng job đã nạp xong nên bưu cục / kg theo đúng luật của <c>query_shipments</c> tại lượt này.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsLoadRunRecorder">
            <summary>
            Khung ghi <c>analytics.LoadRun</c> chung của mọi builder (danh mục, fact vận đơn…): mở dòng "running" TRƯỚC khi mở
            transaction (để rollback không cuốn mất dòng đó), đóng thành success/failed khi xong.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsLoadRunRecorder.FinishAsync(Lada.Framework.Data.Mappings.DbContexts.LadaDbContext,System.Int64,System.String,System.Int32,System.String,System.Nullable{System.DateOnly})">
            <remarks>Không nhận CancellationToken: lượt đã huỷ giữa chừng vẫn phải đóng dòng LoadRun.</remarks>
            <param name="coverFrom">Mốc đầu vùng phủ — chỉ lượt nạp lại cả cửa sổ truyền (xem <see cref="P:Lada.Framework.Data.Domains.Analytics.AnalyticsLoadRun.CoverFrom"/>).</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsAdminCodes">
            <summary>
            Mã đơn vị hành chính chuẩn hoá: tỉnh 2 chữ số, quận/huyện 3, xã/phường 5. Đo Việc 0 GĐ B (2026-09-24): <c>dbo.Location</c>
            lưu thiếu số 0 đầu ở 126 xã bộ 2 cấp (toàn bộ tỉnh 08, hai xã tỉnh 04 — "1006" thay vì "01006"), nên so khớp theo mã
            mà không chuẩn hoá là lạc hẳn một tỉnh.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPiiRules">
            <summary>
            Danh sách cấm dữ liệu cá nhân của MCP số liệu (docs/plan-mcp-tra-cuu-so-lieu.md §3.9) — MỘT nguồn cho cả test quét
            schema (<c>AnalyticsPiiSchemaTests</c>, lớp 2) lẫn bộ lọc kết quả (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.PiiOutputGuard"/>, lớp 3).
            </summary>
            <remarks>
            Tên đơn vị hành chính, tên chi nhánh/bưu cục, tên loại hàng, tên dải cự ly là dữ liệu CÔNG KHAI — được phép qua
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPiiRules.AllowedPublicColumns"/>, không phải bằng cách nới luật "Name". Thêm một cột <c>Name</c> vào bảng khác
            (ví dụ tên khách) là test đỏ ngay.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPiiRules.MaxStringLength">
            <summary>Cột chuỗi dài hơn mức này (hoặc nvarchar(max)) trong schema analytics là cấm — chữ tự do dài là nơi PII trốn.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPiiRules.ForbiddenColumnNames">
            <summary>Tên cột cấm (so khớp nguyên tên, không phân biệt hoa thường).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPiiRules.ForbiddenColumnFragments">
            <summary>Mảnh tên cột cấm (chứa là cấm): PhoneNumber2, SenderAddress, ReceiverEmail…</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPiiRules.AllowedPublicColumns">
            <summary>Ngoại lệ có chủ đích: cột <c>Name</c> của bảng danh mục CÔNG KHAI (bảng, cột).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPiiRules.ColumnViolation(System.String,System.String,System.Type,System.Nullable{System.Int32})">
            <summary>Lý do một cột schema analytics vi phạm; null khi hợp lệ.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPiiRules.ForbiddenOutputKeys">
            <summary>Khoá JSON cấm trong kết quả tool (so khớp nguyên khoá snake_case).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPiiRules.ForbiddenOutputKeyFragments">
            <summary>Mảnh khoá JSON cấm (chứa là cấm).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPiiRules.PhoneRegex">
            <summary>
            Số điện thoại Việt Nam: 0 hoặc +84 rồi 9–10 chữ số, cho phép dấu cách / chấm / gạch giữa các số
            (0912345678, 0912.345.678, +84 912 345 678, 024 3826 1234).
            </summary>
            <remarks>
            Không bắt đầu ngay sau "chữ số + dấu : . ,": phần giây lẻ 7 chữ số của mốc giờ ISO (<c>20:00.1234567</c>) có đúng
            hình "0 + 8 chữ số" và từng bị che nhầm thành số điện thoại khi viết thử.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPiiRules.IsoDateRegex">
            <summary>Giá trị là ngày / ngày giờ ISO-8601 — không bao giờ là dữ liệu cá nhân, bỏ qua khi quét.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPiiRules.WeightBinLabelRegex">
            <summary>
            Nhãn mức cân do CHÍNH engine sinh từ weight_bins ("0.125-12.125", "1000+"): phần nguyên ≤ 6 chữ số (mốc ≤ 100.000 kg),
            ≤ 3 số lẻ — không bao giờ đủ 10 chữ số liền của một số điện thoại, nhưng "0.125-12.125" vẫn trúng regex điện thoại
            (đo GĐ B: bị che nhầm). Giá trị khớp nguyên mẫu này được bộ che bỏ qua.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPiiRules.WeightBinLabelKeys">
            <summary>
            Khoá JSON được phép mang nhãn mức cân. Bỏ qua bộ che CHỈ ở các khoá này: mẫu nhãn cũng khớp số điện thoại viết có gạch
            nối ("0912-345678"), nên bỏ qua theo mọi chuỗi sẽ mở lối cho giá trị tự do trong danh mục (security review GĐ B).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPiiRules.IsWeightBinLabelPath(System.String)">
            <summary>true khi đường dẫn JSON (<c>data.rows[3].bac_can</c>, <c>data.weight_bin_labels[1]</c>) trỏ vào khoá nhãn mức cân.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPiiRules.PlateRegex">
            <summary>Biển số xe Việt Nam: 29A-123.45, 51F12345, 29LD-123.45, 30E1-123.45 (không phân biệt hoa thường).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPriceLineRow">
            <summary>Một dòng bảng giá công khai (<c>analytics.DimPrice</c>) — khối lượng kg, giá gồm VAT.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsFeeConfigLineRow">
            <summary>Một dòng tham số cước (<c>analytics.DimFeeConfig</c>) kèm Id để chọn dòng hiệu lực đúng luật <c>FeeConfigProvider</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsRemoteWardRow">
            <summary>Xã/phường bộ 2 cấp có phụ phí khu vực xa.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPriceTables">
            <summary>Mọi thứ <c>get_price_tables</c> cần — bảng danh mục nhỏ (vài trăm dòng), đọc một lần mỗi lời gọi.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsPriceTableReader">
            <summary>Đọc bảng giá công khai + tham số cước từ schema <c>analytics</c> cho <c>get_price_tables</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPriceTableReader">
            <summary>
            Dapper trên <see cref="P:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.ReadConnectionString"/> (login chỉ đọc <c>db_analytics_reader</c> trên production —
            câu nào lỡ chạm <c>dbo</c> sẽ lỗi quyền), như <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalogReader"/>. Không qua <c>AnalyticsQueryEngine</c>: bảng
            giá không có kỳ, không nhóm (plan GĐ C). SQL cố định, không tham số nào của người gọi.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPriceTableReader.Sql">
            <summary>Năm câu, đúng thứ tự đọc ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsPriceTableReader.ReadAsync(System.Threading.CancellationToken)"/> (public để test chạy lại dưới login chỉ đọc).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryRequest">
            <summary>Tham số một lời gọi truy vấn một chủ đề — đã đọc từ tool, CHƯA kiểm.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryRequest.Filters">
            <summary>Mã chiều → một giá trị hoặc mảng giá trị (JToken, CLR primitive hoặc IEnumerable).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryRequest.ExposePersonCodes">
            <summary>
            AppConfig <c>Analytics.ExposePersonCodes</c>: false thì mọi chiều mã người bị chặn (FORBIDDEN). Mặc định FALSE — tool
            nào quên truyền thì mã người đóng chứ không mở.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryIssue">
            <summary>Một lỗi tham số: mã lỗi hợp đồng + trường (tên tham số snake_case) + câu tiếng Việt.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsSqlParameter">
            <summary>Một tham số Dapper của câu truy vấn — tên do engine đặt, giá trị đã kiểu hoá.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsOutputColumn">
            <summary>Một cột kết quả: alias SQL do engine đặt (<c>d0</c>, <c>m1</c>…) → mã trả cho trợ lý.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsOutputColumn.IsPercentile">
            <summary>Giá trị float của PERCENTILE_CONT — làm tròn 3 số lẻ khi đọc.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan">
            <summary>
            Kế hoạch truy vấn đã kiểm: một batch SQL (tối đa 4 câu, thứ tự cố định: dòng theo trang, số nhóm, tổng, bộ đếm chẩn
            đoán) + tham số + ánh xạ alias → mã. Không có chuỗi nào của người gọi trong <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan.Sql"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan.WeightBinsKg">
            <summary>Mốc mức cân đang dùng (mặc định hoặc weight_bins).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan.UsesWeightBins">
            <summary>true khi chiều bac_can có mặt ở group_by hoặc filters.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan.FilterCodes">
            <summary>Mã chiều đã dùng ở filters (đã kiểm).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan.HasGroups">
            <summary>true = câu 1–2 (dòng theo trang + đếm nhóm) có mặt; false = không nhóm, rows là một dòng tổng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan.DiagnosticColumns">
            <summary>alias → mã bộ đếm chẩn đoán (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.Diagnostics"/>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan.OrderBy">
            <summary>Thứ tự sắp xếp hiệu lực (mã, giảm dần?) — kể cả khoá phụ engine tự thêm cho phân trang tất định.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryBuildResult">
            <summary>Kết quả dựng: có kế hoạch, hoặc danh sách lỗi (mã lỗi của lời gọi = mã của lỗi đầu tiên).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine">
            <summary>
            <b>Bộ dựng SQL của MCP số liệu</b> (docs/plan-mcp-tra-cuu-so-lieu.md §1, §3.4) — lớp thuần, không DB: kiểm tham số
            theo <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalog"/> rồi sinh câu truy vấn trên bảng fact của chủ đề.
            </summary>
            <remarks>
            <para>
            <b>Không nhận SQL, tên cột hay biểu thức từ người gọi.</b> Người gọi chỉ chọn MÃ; mã tra trong catalog (so khớp
            <see cref="F:System.StringComparison.Ordinal"/>), và mọi mảnh SQL — tên bảng, cột ngày, biểu thức chiều, biểu thức gộp — là
            hằng trong catalog. Mọi GIÁ TRỊ (ngày, giá trị lọc, mốc mức cân, phân trang) đi qua tham số Dapper. Alias trong câu
            (<c>[d0]</c>, <c>[m0]</c>…) do engine đặt theo chỉ số; mã chỉ gắn lại ở C# khi đọc kết quả.
            </para>
            <para>
            Giới hạn §1: khoảng ngày ≤ 400 (<c>RANGE_TOO_LARGE</c>), ≤ 6 chiều (<c>TOO_MANY_GROUPS</c>), trang ≤ 5.000 dòng,
            mỗi bộ lọc ≤ 500 giá trị; thời gian chạy do bộ thực thi đặt <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.CommandTimeoutSeconds"/>.
            </para>
            <para>
            Hình câu: CTE <c>base</c> = <c>f.*</c> + biểu thức chiều, lọc kỳ + bộ lọc → (chỉ tiêu hai tầng) CTE <c>pb</c> thêm giá
            trị của cặp bằng hàm cửa sổ (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.PerPair"/>) → (tuỳ chỉ tiêu) CTE <c>pct</c> thêm
            <c>PERCENTILE_CONT … OVER (PARTITION BY chiều)</c> → <c>GROUP BY</c> chiều, <c>ORDER BY … OFFSET/FETCH</c>. Tổng là
            cùng CTE nhưng không <c>GROUP BY</c> (phân vị <c>OVER ()</c>). SQL Server cho CTE sống trong một câu nên mỗi câu của
            batch dựng lại CTE — ở quy mô ~30.000 dòng/năm việc lặp này không đáng kể.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.MaxTotalFilterValues">
            <summary>Tổng giá trị lọc của mọi chiều — dưới xa trần 2.100 tham số một câu của SQL Server.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.MaxTextFilterLength">
            <summary>Độ dài tối đa một giá trị lọc của chiều chữ tự do (<c>text</c>) — bằng độ dài cột <c>DimVehicle.Model</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.Identifier">
            <summary>Hàng rào thứ hai cho tên cột lấy từ catalog (catalog là hằng, nhưng engine không tin mù).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.DimColumn.GroupAliases">
            <summary>Alias đưa vào GROUP BY (chiều mức cân có thêm cột thứ tự để sắp theo mốc, không theo chữ).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.DimensionSql(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.SqlContext,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension)">
            <summary>Biểu thức SQL của một chiều — từ catalog; mức cân dựng từ tham số @wb/@wl.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.WeightBinSql(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.SqlContext,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension,System.Boolean)">
            <summary>
            <c>CASE WHEN f.X &lt;= @wb0 THEN @wl0 … ELSE @wlN END</c> (labels) hoặc cùng CASE trả chỉ số 0..N (thứ tự). Cận trên
            gồm — khớp nhãn "5-10" nghĩa là 5 &lt; kg ≤ 10.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.FromWhere(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.SqlContext,System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsJoin},System.Collections.Generic.IReadOnlyList{System.ValueTuple{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension,System.Collections.Generic.List{System.String},System.Boolean}})">
            <summary>
            <c> FROM bảng fact f [LEFT JOIN …] WHERE kỳ AND bộ lọc</c> — dùng chung cho CTE <c>base</c> và câu chẩn đoán (câu chẩn
            đoán cần thêm join của <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.DiagnosticJoins"/>, ví dụ để đếm bưu cục không thuộc chi nhánh).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.MetricCtes(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.SqlContext,System.String,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.DimColumn},System.Boolean,System.Boolean,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric},System.String@)">
            <summary>
            Chuỗi CTE cho câu có chỉ tiêu: <c>base</c> → (chỉ tiêu hai tầng) <c>pb</c> → (hạng cặp) <c>pr</c> → (phân vị) <c>pct</c>;
            trả tên CTE cuối để <c>SELECT … FROM</c>. Mọi CTE giữ nguyên số dòng của <c>base</c> nên chỉ tiêu một tầng (COUNT, SUM…)
            không đổi nghĩa.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.PairCte(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.DimColumn})">
            <summary>
            CTE <c>pb</c> của chỉ tiêu hai tầng (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.PerPair"/>): mỗi dòng mang giá trị của cặp nó thuộc về —
            <c>[pn]</c> = SUM(<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic.PairValueSql"/>) trên (nhóm, khoá cặp) — và <c>[pv]</c> = giá trị đó CHỈ ở một
            dòng mỗi cặp (<c>ROW_NUMBER() = 1</c>) khi &gt; 0, còn lại NULL. Nhờ vậy <c>COUNT([pv])</c> = số cặp, <c>AVG([pv])</c> =
            bình quân trên cặp, <c>PERCENTILE_CONT … ORDER BY [pv]</c> = phân vị trên cặp (hàm gộp và PERCENTILE_CONT bỏ NULL) — cùng
            một câu <c>GROUP BY</c> với chỉ tiêu một tầng, không cần join lại theo chiều (chiều có thể NULL). SQL Server không có
            <c>COUNT(DISTINCT a, b)</c>; cặp đếm theo cách này.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.PairRankCte(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.DimColumn})">
            <summary>
            CTE <c>pr</c> của chỉ tiêu cần hạng cặp (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric.RanksPairs"/>): <c>[prk]</c> = thứ hạng của cặp theo
            <c>[pv]</c> giảm dần trong từng nhóm, CHỈ ở dòng mang <c>[pv]</c> (SQL Server xếp NULL cuối khi giảm dần, nên dòng NULL không
            chiếm hạng của cặp nào). Chỉ tiêu "N cặp lớn nhất" viết <c>SUM(CASE WHEN [prk] &lt;= N THEN [pv] END)</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.BuildHistogramCtes(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.SqlContext,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDateField,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHistogram,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.DimColumn})">
            <summary>CTE <c>pairs</c> (một dòng / cặp khoá–ngày trong nhóm) và <c>binned</c> (chỉ số nhóm của phân bố).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.UnknownMessage(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsTopic,System.String,System.String)">
            <summary>Câu báo mã lạ: nói rõ nếu mã nằm ở mục "chưa có dữ liệu" (kèm lý do) hay là chiều/chỉ tiêu nhầm chỗ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.BinLabels(System.Collections.Generic.IReadOnlyList{System.Decimal})">
            <summary>Nhãn mức cân: "0-5", "5-10", …, "1000+" — mốc là cận trên gồm của nhóm.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.FlattenFilterValues(System.Object)">
            <summary>Giá trị lọc → danh sách giá trị đơn (null giữ nguyên = lọc IS NULL); null trả về = kiểu không nhận (object).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.ConvertFilterValue(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension,System.Object,System.String,System.Collections.Generic.IReadOnlyList{System.String},System.String,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryIssue})">
            <summary>Một giá trị lọc → tham số đã kiểu hoá theo kiểu của chiều; null + lỗi khi sai kiểu/giá trị.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.ParseOrderBy(System.String,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimension},System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsMetric},Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsHistogram,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryIssue})">
            <summary>
            <c>order_by</c>: chuỗi "mã [asc|desc], mã [asc|desc]" — mã phải là chiều trong group_by hoặc chỉ tiêu đã chọn (với
            phân bố: mã nhóm, so_lan, so_van_don). Sau đó thêm mọi chiều còn lại (và nhóm phân bố) làm khoá phụ để phân trang
            tất định. Mặc định: theo thứ tự group_by, tăng dần.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryResult">
            <summary>Kết quả chạy một <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan"/>: dòng theo trang, tổng, số nhóm, bộ đếm chẩn đoán — khoá là MÃ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsQueryExecutor">
            <summary>Chạy kế hoạch truy vấn của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine"/> trên schema analytics.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryExecutor">
            <summary>
            Dapper trên <see cref="P:Ladaer.BackEnd.Infrastructures.AppSettings.AnalyticsMcpSettings.ReadConnectionString"/> — login chỉ đọc thành viên <c>db_analytics_reader</c>
            trên production (như <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCatalogReader"/>), nên câu nào lỡ chạm <c>dbo</c> sẽ lỗi quyền. Một lần đi về DB
            (<c>QueryMultiple</c>), trần <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryEngine.CommandTimeoutSeconds"/> giây (plan §1).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryExecutor.Map(System.Collections.Generic.IDictionary{System.String,System.Object},System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsOutputColumn},Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsQueryPlan)">
            <summary>alias SQL → mã; float của phân vị làm tròn 3 số lẻ; nhóm phân bố đổi chỉ số → nhãn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadMode">
            <summary>Cách chọn đơn của một lượt nạp fact vận đơn.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadMode.Nightly">
            <summary>Job đêm: đơn tạo trong <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentFactBuilder.RecentCreatedDays"/> ngày + đơn có thay đổi / lấy / giao trong <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentFactBuilder.ChangeWindowDays"/> ngày.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadMode.Rebuild">
            <summary>Nạp lại cả cửa sổ <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentFactBuilder.RebuildDays"/> ngày và dọn dòng không còn trong cửa sổ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadResult">
            <summary>Kết quả một lượt nạp fact vận đơn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadResult.Loaded">
            <summary>Số đơn đã nạp (chèn lại) vào fact.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadResult.Removed">
            <summary>Số dòng fact đã gỡ (đơn bị xoá, hoặc — khi nạp lại — ra ngoài cửa sổ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadResult.SkippedNoCreatedTime">
            <summary>Đơn không có ngày tạo — bỏ qua.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadResult.VatFallback">
            <summary>Đơn có VAT không hợp lệ trên đơn, bóc VAT bằng thuế suất cấu hình.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadResult.SourceFromActor">
            <summary>Đơn có bưu cục gửi / nhận suy từ bưu cục HIỆN TẠI của người bấm (đơn cũ chưa ghi cột trên đơn).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadResult.UnmappedProvinces">
            <summary>Địa chỉ trỏ tỉnh bộ 3 cấp không quy được về bộ mới (mã cũ không còn và không có trong bảng ánh xạ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadResult.Summary">
            <summary>Tóm tắt ghi vào <c>LoadRun.Message</c> (≤ 200 ký tự).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsShipmentFactBuilder">
            <summary>Nạp <c>analytics.ShipmentFact</c> từ bảng nghiệp vụ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsShipmentFactBuilder.BuildOrdersAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Threading.CancellationToken)">
            <summary>Nạp đúng danh sách đơn (test, nạp tay) — vẫn ghi LoadRun.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentFactBuilder">
            <summary>
            Dựng fact vận đơn cho MCP số liệu (docs/plan-mcp-tra-cuu-so-lieu.md §3.3, §3.5) — khung như
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsDimBuilder"/>: đọc bảng nghiệp vụ bằng kết nối CHÍNH, ghi <c>LoadRun</c> "running" trước, xoá–chèn
            theo <c>OrderId</c> từng lô 1.000 đơn trong một transaction, <c>ChangeTracker.Clear()</c>, đóng <c>LoadRun</c>.
            </summary>
            <remarks>
            <para>
            <b>Tiền tính bằng thuộc tính của entity</b> (<see cref="P:Lada.Framework.Data.Domains.Orders.OrderFin.TotalFeeAfterVat"/>, <see cref="P:Lada.Framework.Data.Domains.Orders.OrderFin.VatFee"/>,
            <see cref="P:Lada.Framework.Data.Domains.Orders.OrderFin.TotalFeeBeforeVat"/>), không chép công thức sang SQL. Thuế suất của đơn = VatFee ÷ TotalFeeBeforeVat
            khi hợp lệ (0 &lt; tỷ lệ ≤ 20 %), ngược lại thuế suất FeeConfig <c>VatRate</c> hiệu lực lúc tạo đơn (mặc định 8 %) — đo
            Việc 0: tháng 08/2025 gần như mọi đơn có VatFee = 0 dù cước đã gồm VAT. Mỗi khoản chưa VAT = khoản ÷ (1 + thuế suất), làm
            tròn đồng; riêng cước thực lấy phần còn lại để cước thực + phí thu hộ + bảo hiểm + hoàn = đúng TotalFeeBeforeVat của đơn.
            </para>
            <para>
            <b>Ngày</b> theo giờ Việt Nam tính trong C# (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentFactBuilder.VietnamDate(System.DateTimeOffset)"/>) — không CAST trong SQL (bẫy +00:00).
            <b>Khối lượng tính cước</b> = Σ <c>OrderPackage.SubTotalWeight</c> (đo Việc 0: SubTotalWeight = max(cân thực, thể tích ÷ 6.000)
            × số lượng ở 99,4 % kiện, phần còn lại lệch do cắt phần lẻ gram). <c>OrderFin.ChargeWeight</c> không dùng: console không ghi,
            app khách ghi cân khai báo.
            </para>
            <para>
            <b>Bưu cục gửi / nhận</b> (<see cref="T:Lada.Framework.Data.Domains.Analytics.AnalyticsAgencyBasis"/>): cột trên đơn <c>OrderOps.AgencyPickedupId /
            AgencyDeliveredId</c> khi có (ghi từ 05/2026; tháng 08/2026 trùng bưu cục người bấm 1.473/1.473 đơn); không có thì bưu
            cục HIỆN TẠI của người bấm lấy / giao (<c>User.AgencyId</c>); chưa lấy / giao thì bưu cục kế hoạch. Không dùng
            <c>Order.SaleAgencyId</c> — đó là bưu cục doanh số (HQ chiếm phần lớn).
            </para>
            <para>
            <b>Tỉnh</b> quy về bộ 34 tỉnh mới: mã tỉnh 3 cấp cũ còn tồn tại thì giữ, 29 mã đã đóng tra
            <c>analytics.ProvinceCodeMap</c> (AN-15). <b>Bộ danh mục của địa chỉ</b> lấy theo <c>Location.LevelType</c> của tỉnh, KHÔNG
            theo <c>OrderAddress.AddressLevelType</c> (đo: cờ này = 0 ở mọi đơn trước 05/2026). Mã xã giữ theo đúng bộ của địa chỉ.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentFactBuilder.RecentCreatedDays">
            <summary>Job đêm nạp lại mọi đơn tạo trong chừng này ngày (trạng thái đơn trẻ còn đổi).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentFactBuilder.ChangeWindowDays">
            <summary>Job đêm nạp lại đơn có thay đổi (UpdatedTime bảng đơn / tài chính / vận hành / mốc thời gian) hoặc lấy / giao trong chừng này ngày.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentFactBuilder.RebuildDays">
            <summary>Cửa sổ nạp lại toàn bộ (giới hạn khoảng ngày của tool).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentFactBuilder.MaxOrderVatRate">
            <summary>Thuế suất hợp lệ tối đa suy từ VatFee của đơn — trên mức này coi là dữ liệu lệch, dùng thuế suất cấu hình.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentFactBuilder.ReferenceData.NewProvinceCodes">
            <summary>Mã tỉnh bộ 2 cấp (đã chuẩn hoá).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentFactBuilder.ReferenceData.ProvinceMap">
            <summary>Mã tỉnh cũ đã đóng → mã mới (AN-15).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentFactBuilder.SalesChannelOf(Lada.Framework.Data.Enums.ActionSource)">
            <summary>ActionSource của track tạo đơn → kênh bán. Nội bộ (app/web) gộp cả tổng đài — không tách được (AN-6).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentFactBuilder.ApplyMoney(Lada.Framework.Data.Domains.Analytics.AnalyticsShipmentFact,Lada.Framework.Data.Domains.Orders.OrderFin,System.Collections.Generic.IReadOnlyList{System.ValueTuple{Lada.Framework.Data.Enums.FeeLineType,System.Decimal,System.Boolean,System.Boolean}},System.Decimal)">
            <summary>
            Bóc VAT (plan §3.5): thuế suất theo đơn khi <c>VatFee</c> hợp lệ, không thì FeeConfig lúc tạo đơn (mặc định 8 %).
            Cước thực lấy phần còn lại để tổng các khoản chưa VAT = đúng <see cref="P:Lada.Framework.Data.Domains.Orders.OrderFin.TotalFeeBeforeVat"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentFactBuilder.ConfiguredVatRate(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentFactBuilder.ReferenceData,System.DateTimeOffset)">
            <summary>FeeConfig <c>VatRate</c> hiệu lực lúc tạo đơn (theo <c>EffectiveFrom/To</c>); không có dòng nào → 8 % mặc định.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopEvent">
            <summary>Một lượt bấm lấy/giao — đầu vào của thuật toán ĐD-1 (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.GroupStops(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopEvent},System.Int32,System.Collections.Generic.IReadOnlySet{System.ValueTuple{System.Int32,System.String}},System.DateTimeOffset)"/>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopEvent.StopType">
            <summary><see cref="F:Lada.Framework.Data.Domains.Analytics.AnalyticsStopTypes.Pickup"/> | <see cref="F:Lada.Framework.Data.Domains.Analytics.AnalyticsStopTypes.Delivery"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopEvent.DriverCode">
            <summary>Mã băm người bấm <c>LX-…</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopEvent.Time">
            <summary>Thời điểm bấm (<c>OrderTimeTrack.PickupTime / DeliveryDate</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopEvent.WardId">
            <summary><c>OrderAddress.WardId</c> của địa chỉ gửi (lấy) / nhận (giao); 0 = không có.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopEvent.Address">
            <summary>Địa chỉ ĐÃ CHUẨN HOÁ (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.NormalizeAddress(System.String)"/>); null = trống. Chỉ sống trong bộ nhớ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopLoadResult">
            <summary>Kết quả một lượt nạp điểm dừng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopLoadResult.Events">
            <summary>Số lượt bấm đã dựng thành điểm.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopLoadResult.Skipped">
            <summary>Lượt có trong fact nhưng không đọc được thời điểm bấm, hoặc ngày bấm lệch khỏi khoảng (fact cũ hơn bảng nghiệp vụ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopLoadResult.NoAddress">
            <summary>Lượt không có địa chỉ chuỗi / không có xã — mỗi lượt thành một điểm riêng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopLoadResult.Summary">
            <summary>Tóm tắt ghi vào <c>LoadRun.Message</c> (≤ 200 ký tự).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsStopFactBuilder">
            <summary>Nạp <c>analytics.StopFact</c> (điểm dừng ước lượng ĐD-1).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsStopFactBuilder.BuildAsync(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsShipmentLoadMode,System.Threading.CancellationToken)">
            <param name="mode">
            Nightly = 35 ngày gần nhất, lùi tới lần nạp thành công trước nếu cũ hơn, và tới ngày lấy/giao sớm nhất của đơn mà lượt fact
            vận đơn gần nhất vừa nạp lại; Rebuild = cả cửa sổ 400 ngày + dọn + mốc phủ.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.IAnalyticsStopFactBuilder.BuildRangeAsync(System.DateOnly,System.DateOnly,System.Threading.CancellationToken)">
            <summary>Dựng lại đúng khoảng ngày (test, nạp tay) — vẫn ghi LoadRun, không ghi mốc phủ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder">
            <summary>
            Dựng điểm dừng ước lượng ĐD-1 (docs/plan-mcp-tra-cuu-so-lieu.md §3.6) từ <c>analytics.ShipmentFact</c> (ngày lấy/giao, mã
            người bấm, kiện, kg, bưu cục, địa bàn — một nguồn luật với <c>query_shipments</c>) cộng bảng nghiệp vụ cho đúng hai thứ fact
            không có: <b>thời điểm bấm</b> và <b>địa chỉ</b> để so trùng.
            </summary>
            <remarks>
            <para>
            <b>Địa chỉ chỉ sống trong bộ nhớ</b>: đọc <c>OrderAddress.Address1</c>, chuẩn hoá (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.NormalizeAddress(System.String)"/>), so trùng,
            rồi bỏ — bảng <c>StopFact</c> không có cột địa chỉ nào (hàng rào dữ liệu cá nhân lớp 1).
            </para>
            <para>
            ĐD-1 (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.GroupStops(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopEvent},System.Int32,System.Collections.Generic.IReadOnlySet{System.ValueTuple{System.Int32,System.String}},System.DateTimeOffset)"/>, hàm thuần): các lượt của một người bấm trong một ngày giờ Việt Nam sắp theo thời điểm; lượt
            nối vào điểm đang mở khi cùng loại lượt, cùng xã (<c>WardId</c>), cùng địa chỉ chuẩn hoá và cách lượt trước ≤ ngưỡng
            AppConfig <c>Analytics.StopGapMinutes</c>. Việc 0 GĐ C (2026-09-24) bỏ điều kiện "toạ độ cách nhau ≤ 50 m" của plan: chỉ
            7,3 % cặp lượt có toạ độ ở cả hai đầu.
            </para>
            <para>
            Ghi theo từng tháng: một transaction xoá–chèn các ngày của tháng đó, nên bảng vẫn đọc được trong lúc chạy và chạy lại
            nhiều lần ra một bộ. Mỗi lượt ghi một dòng <c>LoadRun</c> chủ đề <c>stops</c>; lượt nạp lại cả cửa sổ ghi mốc phủ
            (<c>CoverFrom</c>) như fact vận đơn.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.BurstSeconds">
            <summary>Lượt đầu của điểm cách lượt cuối của điểm trước dưới chừng này giây mà khác xã → cờ bấm dồn.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.RecentDays">
            <summary>Job đêm dựng lại chừng này ngày gần nhất — cùng cửa sổ đơn trẻ của fact vận đơn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.ReadGapMinutesAsync">
            <summary>AppConfig <c>Analytics.StopGapMinutes</c>; thiếu, sai kiểu hoặc ngoài 1–240 → 30 + log cảnh báo.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.ParseGapMinutes(System.String)">
            <summary>Giá trị AppConfig ngưỡng phút → số nguyên trong [<see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.MinGapMinutes"/>, <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.MaxGapMinutes"/>]; sai → null.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.LoadAgencyAddressesAsync(System.Threading.CancellationToken)">
            <summary>(xã, địa chỉ chuẩn hoá) của mọi bưu cục/chi nhánh chưa xoá — để đánh dấu điểm dừng tại bưu cục.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.NormalizeAddress(System.String)">
            <summary>
            Chuẩn hoá chuỗi địa chỉ để so trùng: bỏ dấu tiếng Việt (đ → d), chữ thường, mọi ký tự không phải chữ/số thành khoảng
            trắng, gộp khoảng trắng. "Số 12, Ngõ 34/5 Đường Láng" và "so 12 ngo 34 5 duong lang" là một. Trống → null.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.GroupStops(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopEvent},System.Int32,System.Collections.Generic.IReadOnlySet{System.ValueTuple{System.Int32,System.String}},System.DateTimeOffset)">
            <summary>
            Gom lượt thành điểm dừng theo ĐD-1. Lượt nối vào điểm đang mở khi CÙNG người bấm, CÙNG ngày giờ Việt Nam, CÙNG loại lượt,
            CÙNG xã (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.SameWard(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopEvent,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopEvent)"/>), CÙNG địa chỉ chuẩn hoá (khác null) và cách lượt ngay trước ≤ <paramref name="gapMinutes"/>
            phút (biên gồm).
            Lượt cùng thời điểm sắp theo mã vận đơn cho tất định.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.SameWard(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopEvent,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopEvent)">
            <summary>
            Cùng xã: cùng <c>WardId</c>; hoặc hai địa chỉ thuộc HAI BỘ danh mục (3 cấp cũ / 2 cấp mới — đơn tạo hai bên mốc 06/2026 giao
            cùng ngày) mà cùng tỉnh đã quy về bộ mới: <c>WardId</c> hai bộ không so được và chưa có ánh xạ xã (AN-5), nên để điều kiện
            cùng địa chỉ chuẩn hoá quyết định (review GĐ C).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopFactBuilder.DifferentWard(Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopEvent,Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsStopEvent)">
            <summary>Khác xã CHẮC CHẮN: cùng bộ danh mục mà khác <c>WardId</c> (khác bộ thì không kết luận được).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.PiiScanResult">
            <summary>Kết quả quét: dữ liệu đã che + cảnh báo cho trợ lý + số chỗ phải che (để log lỗi).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Analytics.PiiOutputGuard">
            <summary>
            Lớp 3 của hàng rào dữ liệu cá nhân (docs/plan-mcp-tra-cuu-so-lieu.md §1, §3.9): quét MỌI kết quả tool số liệu trước
            khi trả — khoá JSON thuộc danh sách cấm bị bỏ hẳn; giá trị chuỗi chứa số điện thoại, email, biển số bị che — mỗi chỗ
            ghi một <c>warnings[]</c> để trợ lý biết số liệu có chỗ bị che, và tool log LỖI để người vận hành đi tìm nguồn rò.
            </summary>
            <remarks>
            <para>
            Hai lớp trước (schema không có cột cấm; login chỉ đọc chỉ thấy schema analytics) chặn cột. Lớp này chặn GIÁ TRỊ:
            chữ tự do trong cột công khai (ví dụ ai đó gõ số điện thoại vào tên bưu cục, gõ biển số vào mẫu xe) — thứ không test
            schema nào bắt được.
            </para>
            <para>
            Mã băm của chính hệ thống (<c>KH-3HT7ZPQA</c>) có thể trùng hình dạng biển số, nên giá trị khớp nguyên
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.AnalyticsCodeHasher.CodePattern"/> được bỏ qua.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Analytics.PiiOutputGuard.MaxDetailedWarnings">
            <summary>Số cảnh báo chi tiết tối đa — quá thì gộp một dòng, không để warnings[] phình theo dữ liệu bẩn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.IAppConfigManagementService">
            <summary>
            Interface cho service quản lý AppConfig
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.IAppConfigManagementService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm AppConfig với SmartTable
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Kết quả tìm kiếm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.IAppConfigManagementService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.CreateAppConfigModel)">
            <summary>
            Tạo hoặc cập nhật AppConfig
            </summary>
            <param name="model">Model AppConfig</param>
            <returns>Kết quả thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.IAppConfigManagementService.GetById(System.Int32)">
            <summary>
            Lấy AppConfig theo Id
            </summary>
            <param name="id">Id của AppConfig</param>
            <returns>AppConfig model</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.IAppConfigManagementService.Delete(System.Int32)">
            <summary>
            Xóa AppConfig
            </summary>
            <param name="id">Id của AppConfig</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.IAppConfigManagementService.ReloadCache">
            <summary>
            Reload cache cho tất cả applications
            </summary>
            <returns>Kết quả reload</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.AppConfigManagementService">
            <summary>
            Implementation của AppConfigManagementService
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.AppConfigManagementService.AssistantOwnedKeyMessage">
            <summary>
            Khoá của trợ lý AI Cổng nhượng quyền chỉ sửa ở màn Cấu hình trợ lý (kiểm model, hạn mức, văn bản nền, dấu ghim nhà
            cung cấp) — security review GĐ G2a.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AppConfigManagementService.ReloadFrameworkCacheAsync">
             <summary>
             Làm mới cache của <c>Lada.Framework</c> sau khi sửa cấu hình.
             </summary>
             <remarks>
             <b>Hai lớp cache song song, hai sơ đồ khoá khác nhau.</b> Lớp này ghi qua
             <c>ICacheService</c> với tiền tố <c>"AppConfig:"</c>, còn
             <c>Lada.Framework.Infrastructures.Services.AppConfigService</c> — nơi phần lớn code nghiệp
             vụ thật sự ĐỌC cấu hình — dùng <c>IMemoryCache</c> với tiền tố <c>"AppConfig_"</c> và TTL
             1 giờ. Xoá tiền tố này không chạm được tiền tố kia.
            
             Hệ quả trước khi có hàm này: sửa một khoá qua màn quản trị (kể cả bấm "reload cache") vẫn
             mất tới một giờ mới có hiệu lực với code đọc qua Framework, mà không có gì báo cho người
             vận hành biết. Phát hiện khi bấm thật GĐ D — nới cửa sổ <c>Kpi.RecloseWindowDays</c> rồi
             gọi ReloadCache mà API vẫn đọc giá trị cũ.
            
             Đây không phải chuyện nhỏ với phân hệ KPI: <c>Kpi.EffectiveFrom</c> và (từ GĐ E)
             <c>Kpi.EnableBonus</c> đều đọc qua Framework, và đều là công tắc đổi được tiền.
             </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AppConfigManagementService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm AppConfig với SmartTable
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Kết quả tìm kiếm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AppConfigManagementService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.CreateAppConfigModel)">
            <summary>
            Tạo hoặc cập nhật AppConfig
            </summary>
            <param name="model">Model AppConfig</param>
            <returns>Kết quả thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AppConfigManagementService.GetById(System.Int32)">
            <summary>
            Lấy AppConfig theo Id
            </summary>
            <param name="id">Id của AppConfig</param>
            <returns>AppConfig model</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AppConfigManagementService.Delete(System.Int32)">
            <summary>
            Xóa AppConfig
            </summary>
            <param name="id">Id của AppConfig</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.AppConfigManagementService.ReloadCache">
            <summary>
            Reload cache cho tất cả applications
            </summary>
            <returns>Kết quả reload</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.BackendAppConfigServiceAdapter">
            <summary>
            Adapter để chuyển đổi Framework IAppConfigService thành Backend IAppConfigService
            (Backward compatibility)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService">
            <summary>
            Interface cho dịch vụ triển khai
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.GetDeployLocations(System.Collections.Generic.List{Lada.Framework.Data.Enums.OrderStatus},Lada.Framework.Data.Enums.OrderPhysicalStatus,Lada.Framework.Data.Enums.AddressType)">
            <summary>
            Lấy danh sách vị trí triển khai
            </summary>
            <param name="status">Trạng thái đơn hàng</param>
            <param name="physicalStatus">Trạng thái vật lý đơn hàng</param>
            <param name="addressType">Loại địa chỉ</param>
            <returns>Danh sách vị trí triển khai</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.GetDeployLocations(System.Collections.Generic.List{Lada.Framework.Data.Enums.OrderStatus},System.Collections.Generic.List{Lada.Framework.Data.Enums.OrderPhysicalStatus},Lada.Framework.Data.Enums.AddressType,System.Nullable{System.Int32})">
            <summary>
            Lấy danh sách vị trí triển khai
            </summary>
            <param name="status">Trạng thái đơn hàng</param>
            <param name="physicalStatus">Trạng thái vật lý đơn hàng</param>
            <param name="addressType">Loại địa chỉ</param>
            <returns>Danh sách vị trí triển khai</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.GetDeployOrders(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy danh sách đơn hàng triển khai
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Kết quả bảng thông minh chứa danh sách đơn hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.AssignPickup(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel)">
            <summary>
            Gán đơn hàng cho người dùng để lấy hàng
            </summary>
            <param name="model">Mô hình gán đơn hàng</param>
            <returns>Kết quả gán đơn hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.UnAssignPickup(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel)">
            <summary>
            Bỏ gán đơn hàng cho người dùng
            </summary>
            <param name="model">Mô hình bỏ gán đơn hàng</param>
            <returns>Kết quả bỏ gán đơn hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.GetDeployMonitor(System.Int32,System.Int32,System.Int32)">
            <summary>
            Lấy danh sách giám sát triển khai
            </summary>
            <param name="pageNumber">Số trang</param>
            <param name="pageSize">Kích thước trang</param>
            <returns>Danh sách giám sát triển khai và tổng số bản ghi</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.GetDeployDetail(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy chi tiết đơn hàng triển khai
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Kết quả bảng thông minh chứa chi tiết đơn hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.GeocodeOrderAddresses(System.Collections.Generic.List{System.Int32},System.Int32,System.String)">
            <summary>
            Lấy toạ độ chính xác cho các địa chỉ đơn hàng còn trống bằng Google Geocoding,
            đồng thời lưu lại vào CSDL để lần sau không phải gọi Google nữa.
            </summary>
            <param name="addressIds">Danh sách Id của OrderAddress cần geocode</param>
            <param name="updatedBy">Id người dùng thao tác</param>
            <param name="updatedByUserName">Tên người dùng thao tác</param>
            <returns>Danh sách toạ độ đã lấy được (bỏ qua địa chỉ geocode thất bại)</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.AssignDelivery(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel)">
            <summary>
            Gán giao hàng
            </summary>
            <param name="model">Model gán</param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.AssignTransit(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel)">
            <summary>
            Gán trung chuyển
            </summary>
            <param name="model">Model gán</param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.ReorderOrders(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.ReorderModel,System.Int32,System.String)">
            <summary>
            Sắp xếp thứ tự hiển thị đơn hàng
            </summary>
            <param name="model">Danh sách đơn hàng với thứ tự mới</param>
            <param name="updatedBy">ID người dùng thao tác</param>
            <param name="updatedByUserName">Tên người dùng thao tác</param>
            <returns>Kết quả sắp xếp</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.GetDeployLocations(Lada.Framework.Data.Enums.DeployType,System.Int32)">
            <summary>
            Lấy danh sách vị trí triển khai theo loại triển khai
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.GetDeployOrders(Lada.Framework.Data.Enums.DeployType,Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32,System.Collections.Generic.List{System.Int32})">
            <summary>
            Lấy danh sách đơn hàng triển khai theo loại triển khai
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.Assign(Lada.Framework.Data.Enums.DeployType,Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel)">
            <summary>
            Gán đơn hàng cho nhân viên theo loại triển khai
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.SetOrderReturn(System.Collections.Generic.List{System.Int32},System.Int32,System.String,System.Int32,System.Nullable{System.Int32})">
            <summary>
            Cập nhật đơn hàng sang chiều trả về (OrderDirection = ToReturn, Status = WaitToReturn)
            </summary>
            <param name="returnAgencyId">Bên phát hoàn dự kiến điều phối chọn (Ví v2 plan §3.8.1); null = bưu cục đã lấy hàng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IDeployService.GetReturnAgencyOptionsAsync">
            <summary>Chi nhánh LADA đang hoạt động — lựa chọn "Bên phát hoàn" ngoài mặc định bưu cục đã lấy hàng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService">
            <summary>
            Triển khai dịch vụ triển khai
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.GetDeployLocations(System.Collections.Generic.List{Lada.Framework.Data.Enums.OrderStatus},Lada.Framework.Data.Enums.OrderPhysicalStatus,Lada.Framework.Data.Enums.AddressType)">
            <summary>
            Lấy danh sách vị trí triển khai
            </summary>
            <param name="status">Trạng thái đơn hàng</param>
            <param name="physicalStatus">Trạng thái vật lý đơn hàng</param>
            <param name="addressType">Loại địa chỉ</param>
            <returns>Danh sách vị trí triển khai</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.GetDeployOrders(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy danh sách đơn hàng triển khai
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Kết quả bảng thông minh chứa danh sách đơn hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.GetDeployMonitor(System.Int32,System.Int32,System.Int32)">
            <summary>
            Lấy danh sách giám sát triển khai
            </summary>
            <param name="pageNumber">Số trang</param>
            <param name="pageSize">Kích thước trang</param>
            <returns>Danh sách giám sát triển khai và tổng số bản ghi</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.GetDeployDetail(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy chi tiết đơn hàng triển khai
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Kết quả bảng thông minh chứa chi tiết đơn hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.GeocodeOrderAddresses(System.Collections.Generic.List{System.Int32},System.Int32,System.String)">
            <summary>
            Geocode các địa chỉ đơn hàng chưa có toạ độ qua Google, rồi lưu lại vào CSDL.
            Nhờ lưu lại nên mỗi địa chỉ chỉ tốn đúng một lần gọi Google trong toàn hệ thống.
            </summary>
            <param name="addressIds">Danh sách Id của OrderAddress cần geocode</param>
            <param name="updatedBy">Id người thao tác</param>
            <param name="updatedByUserName">Tên người thao tác</param>
            <returns>Danh sách toạ độ đã lấy được (bỏ qua địa chỉ geocode thất bại)</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.AssignPickup(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel)">
            <summary>
            Gán đơn hàng cho người dùng để lấy hàng
            </summary>
            <param name="model">Mô hình gán đơn hàng</param>
            <returns>Kết quả gán đơn hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.UnAssignPickup(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel)">
            <summary>
            Bỏ gán đơn hàng cho người dùng
            </summary>
            <param name="model">Mô hình bỏ gán đơn hàng</param>
            <returns>Kết quả bỏ gán đơn hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.AssignDelivery(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel)">
            <summary>
            Gán đơn hàng cho người dùng để giao hàng
            </summary>
            <param name="model">Mô hình gán đơn hàng</param>
            <returns>Kết quả gán đơn hàng</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.AssignItem">
            <summary>Một đơn đã qua kiểm trạng thái trong lô gán, chờ ghi: <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.AssignItem.Apply"/> đổi trạng thái trong bộ nhớ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.AssignItem.#ctor(Lada.Framework.Data.Domains.Orders.Order,Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderTrackModel,System.Action)">
            <summary>Một đơn đã qua kiểm trạng thái trong lô gán, chờ ghi: <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.AssignItem.Apply"/> đổi trạng thái trong bộ nhớ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.SaveAssignBatchAsync(Ladaer.BackEnd.Infrastructures.DTO.Results.Business.AssignResult,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.AssignItem},Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel,System.Int32,System.Boolean)">
            <summary>
            Ghi một lô gán. Người được gán thuộc chi nhánh BẬT VÍ (Ví v2, plan §3.3 "Xuất kho", Docs §5) → TỪNG đơn một giao dịch: đơn đang ở
            chi nhánh khác đi qua điểm chặn <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.OutboundToAgencyAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOutboundRequest,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope,System.Func{System.Threading.Tasks.Task})"/> (khoá ví bưu cục phát, đọc số dư sau
            khoá, giữ E2 / E3 cùng giao dịch); không đủ → đơn ĐÓ bị từ chối kèm số thiếu trong <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Business.AssignResult.Orders"/>, đơn khác vẫn
            đi. Hàng đang ở chính chi nhánh được gán (bưu cục gán lái xe của mình) không phải mốc xuất kho — không kiểm. Người được gán không
            bật ví → đường cũ: một <c>UpdateAsync</c> cả lô, kết quả cả lô như trước (test đối chiếu đơn LADA thuần).
            </summary>
            <param name="deliveryAgencyId">Chi nhánh của người được gán — bên phát P (0 = không kiểm ví).</param>
            <param name="transit">Gán trung chuyển (không phải gán giao): tới lái xe chi nhánh LADA là việc của kho, không phải xuất kho cho bên phát.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.AssignTransit(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel)">
            <summary>
            Gán đơn hàng cho người dùng để giao hàng
            </summary>
            <param name="model">Mô hình gán đơn hàng</param>
            <returns>Kết quả gán đơn hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.GetDeployLocations(Lada.Framework.Data.Enums.DeployType,System.Int32)">
            <summary>
            Lấy danh sách vị trí triển khai theo loại triển khai (sử dụng DeployType)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.GetDeployOrders(Lada.Framework.Data.Enums.DeployType,Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32,System.Collections.Generic.List{System.Int32})">
            <summary>
            Lấy danh sách đơn hàng triển khai theo loại triển khai (sử dụng DeployType)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.Assign(Lada.Framework.Data.Enums.DeployType,Ladaer.BackEnd.Infrastructures.DTO.Models.Business.AssignModel)">
            <summary>
            Gán đơn hàng cho nhân viên theo loại triển khai (sử dụng DeployType)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.SetOrderReturn(System.Collections.Generic.List{System.Int32},System.Int32,System.String,System.Int32,System.Nullable{System.Int32})">
            <summary>
            Cập nhật đơn hàng sang chiều trả về
            Set OrderDirection = ToReturn, Status = WaitToReturn
            </summary>
        </member>
        <!-- Badly formed XML comment ignored for member "M:Ladaer.BackEnd.Infrastructures.Services.Business.DeployService.ReorderOrders(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.ReorderModel,System.Int32,System.String)" -->
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Business.IOperationService">
            <summary>
            Interface for operation service.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IOperationService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Searches for orders based on the provided parameters.
            </summary>
            <param name="param">Search parameters.</param>
            <param name="userId">User ID.</param>
            <returns>Search results.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IOperationService.GetById(System.Int32,System.Int32)">
            <summary>
            Gets an order by its ID.
            </summary>
            <param name="id">Order ID.</param>
            <param name="userId">User ID.</param>
            <returns>Order item.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IOperationService.Pickup(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Operations.PickupModel)">
            <summary>
            Picks up an order.
            </summary>
            <param name="model">Pickup model.</param>
            <returns>Order track result.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IOperationService.Delivery(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Operations.DeliveryModel)">
            <summary>
            Giao hàng thành công
            </summary>
            <param name="model"></param>
            <returns></returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Business.OperationService">
            <summary>
            Implementation of the operation service.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.OperationService.#ctor(Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService,Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.OrderOps},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.OrderFin},Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderTrackService,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.Order},Lada.Framework.Infrastructures.Services.IUnifiedMediaService,System.Data.IDbConnection,Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService)">
            <summary>
            Initializes a new instance of the <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Business.OperationService"/> class.
            </summary>
            <param name="locationService">Location service.</param>
            <param name="userService">User service.</param>
            <param name="orderOpsRepository">Order operations repository.</param>
            <param name="orderFinRepository">Order financial repository.</param>
            <param name="orderTrackService">Order track service.</param>
            <param name="orderRepository">Order repository.</param>
            <param name="unifiedMediaService">Unified media service.</param>
            <param name="dbConnection">Database connection.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.OperationService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Searches for orders based on the provided parameters.
            </summary>
            <param name="param">Search parameters.</param>
            <param name="userId">User ID.</param>
            <returns>Search results.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.OperationService.GetById(System.Int32,System.Int32)">
            <summary>
            Gets an order by its ID.
            </summary>
            <param name="id">Order ID.</param>
            <param name="userId">User ID.</param>
            <returns>Order item.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.OperationService.Pickup(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Operations.PickupModel)">
            <summary>
            Picks up an order.
            </summary>
            <param name="model">Pickup model.</param>
            <returns>Order track result.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.OperationService.Delivery(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Operations.DeliveryModel)">
            <summary>
            Giao hàng.
            </summary>
            <param name="model">model.</param>
            <returns>Order track result.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.OperationService.ValidateUpdateStatus(Lada.Framework.Data.Enums.OrderStatus,Lada.Framework.Data.Enums.OrderPhysicalStatus,Lada.Framework.Data.Enums.OrderStatus,Lada.Framework.Data.Enums.OrderPhysicalStatus)">
            <summary>
            Validates the update status of an order.
            </summary>
            <param name="currentStatus">Current order status.</param>
            <param name="currentPhysicalStatus">Current physical status.</param>
            <param name="newStatus">New order status.</param>
            <param name="newPhysicalStatus">New physical status.</param>
            <returns>True if the update is valid, otherwise false.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Business.IWarehouseService">
            <summary>
            Giao diện cho WarehouseService
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IWarehouseService.Inbound(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Warehouses.InboundModel)">
            <summary>
            Xử lý quá trình nhập kho cho một đơn hàng.
            </summary>
            <param name="model">Mô hình nhập kho chứa thông tin đơn hàng.</param>
            <returns>Kết quả nhập kho chỉ ra kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IWarehouseService.SearchDriversAsync(System.Int32,System.String,System.Int32,System.Int32)">
            <summary>
            Lấy danh sách tài xế theo ID của đại lý với tùy chọn lọc từ khóa và phân trang.
            </summary>
            <param name="agencyId">ID của đại lý.</param>
            <param name="keyword">Từ khóa tùy chọn để lọc tài xế.</param>
            <param name="pageNumber">Số trang cho phân trang.</param>
            <param name="pageSize">Kích thước trang cho phân trang.</param>
            <returns>Danh sách các đối tượng DriverInfoItem.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.IWarehouseService.GetInboundOrdersByDriversAsync(System.Int32,System.Int32,System.Int32)">
            <summary>
            Lấy danh sách đơn hàng cần inbound của 1 lái xe
            </summary>
            <param name="userId">Id của lái xe</param>
            <param name="pageNumber">Số trang</param>
            <param name="pageSize">Số bản ghi / trang</param>
            <returns></returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Business.WarehouseService">
            <summary>
            Lớp dịch vụ để xử lý các hoạt động của kho hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.WarehouseService.#ctor(System.Data.IDbConnection,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.OrderOps},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.Order},Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderTrackService,Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService,Lada.Framework.Infrastructures.Services.IUnifiedMediaService,Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService)">
            <summary>
            Khởi tạo một thể hiện mới của lớp <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Business.WarehouseService"/>.
            </summary>
            <param name="dbConnection">Kết nối cơ sở dữ liệu.</param>
            <param name="orderOpsRepository">Kho lưu trữ các hoạt động đơn hàng.</param>
            <param name="orderRepository">Kho lưu trữ đơn hàng.</param>
            <param name="orderTrackService">Dịch vụ theo dõi đơn hàng.</param>
            <param name="userService">Dịch vụ người dùng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.WarehouseService.SearchDriversAsync(System.Int32,System.String,System.Int32,System.Int32)">
            <summary>
            Lấy danh sách tài xế theo ID của đại lý với tùy chọn lọc từ khóa và phân trang.
            </summary>
            <param name="agencyId">ID của đại lý.</param>
            <param name="keyword">Từ khóa tùy chọn để lọc tài xế.</param>
            <param name="pageNumber">Số trang cho phân trang.</param>
            <param name="pageSize">Kích thước trang cho phân trang.</param>
            <returns>Danh sách các đối tượng DriverInfoItem.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.WarehouseService.GetInboundOrdersByDriversAsync(System.Int32,System.Int32,System.Int32)">
            <summary>
            Lấy danh sách đơn hàng cần inbound của 1 lái xe
            </summary>
            <param name="userId">Id của lái xe</param>
            <param name="pageNumber">Số trang</param>
            <param name="pageSize">Số bản ghi / trang</param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.WarehouseService.Inbound(Ladaer.BackEnd.Infrastructures.DTO.Models.Business.Warehouses.InboundModel)">
            <summary>
            Xử lý quá trình nhập kho cho một đơn hàng.
            </summary>
            <param name="model">Mô hình nhập kho chứa thông tin đơn hàng.</param>
            <returns>Kết quả nhập kho chỉ ra kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Business.WarehouseService.ValidateUpdateStatus(Lada.Framework.Data.Enums.OrderStatus,Lada.Framework.Data.Enums.OrderPhysicalStatus,Lada.Framework.Data.Enums.OrderStatus,Lada.Framework.Data.Enums.OrderPhysicalStatus)">
            <summary>
            Xác thực trạng thái cập nhật của một đơn hàng.
            </summary>
            <param name="currentStatus">Trạng thái hiện tại của đơn hàng.</param>
            <param name="currentPhysicalStatus">Trạng thái vật lý hiện tại của đơn hàng.</param>
            <param name="newStatus">Trạng thái mới của đơn hàng.</param>
            <param name="newPhysicalStatus">Trạng thái vật lý mới của đơn hàng.</param>
            <returns>True nếu cập nhật hợp lệ, ngược lại là false.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyCoverageExcelService">
            <summary>
            Interface cho dịch vụ xuất Excel vùng phủ chi nhánh
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyCoverageExcelService.ExportAsync(System.Collections.Generic.List{System.Int32})">
            <summary>
            Xuất Excel vùng phủ của tất cả chi nhánh (hoặc lọc theo danh sách agencyIds)
            </summary>
            <param name="agencyIds">Danh sách AgencyId được phép xem (null = tất cả)</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Categories.AgencyCoverageExcelService">
            <summary>
            Dịch vụ xuất Excel vùng phủ chi nhánh
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.AgencyCoverageExcelService.ExportAsync(System.Collections.Generic.List{System.Int32})">
            <summary>
            Xuất Excel vùng phủ chi nhánh
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.AgencyCoverageExcelService.GetCoverageDataAsync(System.Collections.Generic.List{System.Int32})">
            <summary>
            Lấy dữ liệu vùng phủ gộp theo chi nhánh
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.AgencyCoverageExcelService.CreateExcelPackage(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Categories.AgencyCoverageRow})">
            <summary>
            Tạo file Excel
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Categories.AgencyCoverageExcelResult">
            <summary>
            Kết quả xuất Excel vùng phủ chi nhánh
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Categories.AgencyCoverageRow">
            <summary>
            Dòng dữ liệu vùng phủ chi nhánh (dùng nội bộ cho Excel)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyLocationService">
            <summary>
            Interface cho service quản lý vùng phủ của đại lý
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyLocationService.GetAgencyCoverage(System.Int32)">
            <summary>
            Lấy thông tin vùng phủ của agency
            </summary>
            <param name="agencyId">ID của đại lý</param>
            <returns>Thông tin vùng phủ</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyLocationService.AddLocationToAgency(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AddLocationsToAgencyModel)">
            <summary>
            Thêm location vào agency
            </summary>
            <param name="model">Thông tin các location cần thêm</param>
            <returns>Kết quả thêm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyLocationService.RemoveLocationFromAgency(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AddLocationsToAgencyModel)">
            <summary>
            Xóa location khỏi agency
            </summary>
            <param name="model">Thông tin các location cần xóa</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyLocationService.GetAvailableLocationsTree(System.Int32,System.Int32)">
            <summary>
            Lấy danh sách location chưa được chọn cho agency dưới dạng cây
            </summary>
            <param name="agencyId">ID của đại lý</param>
            <param name="parentId">ID của location cha (0 = lấy tỉnh/thành phố, >0 = lấy con của location đó)</param>
            <returns>Danh sách location dưới dạng cây</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Categories.AgencyLocationService">
            <summary>
            Service quản lý vùng phủ của đại lý
            Logic: Mỗi phường/xã (Level 3) chỉ thuộc về 1 Agency duy nhất
            Sử dụng Location.AgencyId để xác định ownership
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.AgencyLocationService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Categories.Agency},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Categories.Location})">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Categories.AgencyLocationService"/>.
            </summary>
            <param name="agencyRepository">Repository của Agency</param>
            <param name="locationRepository">Repository của Location</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.AgencyLocationService.GetAgencyCoverage(System.Int32)">
            <summary>
            Lấy thông tin vùng phủ của agency
            Logic: Lấy tất cả Location có AgencyId = agencyId, sau đó build hierarchy
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.AgencyLocationService.AddLocationToAgency(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AddLocationsToAgencyModel)">
            <summary>
            Thêm location vào agency
            Logic: 
            1. Validate locations exist và là Level 3 (phường/xã)
            2. Kiểm tra location chưa thuộc agency khác
            3. Set AgencyId cho các location
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.AgencyLocationService.RemoveLocationFromAgency(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AddLocationsToAgencyModel)">
            <summary>
            Xóa location khỏi agency
            Logic: 
            1. Validate locations exist và thuộc agency này
            2. Set AgencyId = 0 cho các location
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.AgencyLocationService.GetAvailableLocationsTree(System.Int32,System.Int32)">
            <summary>
            Lấy danh sách location chưa được gán cho bất kỳ agency nào dưới dạng cây
            Logic: Location.AgencyId = 0 hoặc NULL = chưa được gán
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Collections.Generic.List{System.Int32})">
            <summary>
            Tìm kiếm đại lý
            </summary>
            <param name="param"></param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyModel)">
            <summary>
            Tạo/cập nhật đại lý
            </summary>
            <param name="model"></param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyService.GetById(System.Int32)">
            <summary>
            Lấy thông tin đại lý
            </summary>
            <param name="id"></param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa đại lý
            </summary>
            <param name="id"></param>
            <param name="currentUser"></param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyService.UpdateStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.AgencyStatusModel)">
            <summary>
            Cập nhật trạng thái đại lý
            </summary>
            <param name="agencyStatusModel"></param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyService.GetTree(System.String)">
            <summary>
            Lấy danh sách chi nhánh
            </summary>
            <param name="keyword"></param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IAgencyService.GetAgencyWithDescendantIdsAsync(System.Int32)">
            <summary>
            Lấy danh sách AgencyId bao gồm agency hiện tại và tất cả agency con cháu (đệ quy).
            Kết quả được cache 10 phút.
            </summary>
            <param name="agencyId">ID agency gốc</param>
            <returns>Danh sách tất cả AgencyId trong nhánh</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.AgencyService.GetAgencyWithDescendantIdsAsync(System.Int32)">
            <summary>
            Lấy danh sách AgencyId bao gồm agency hiện tại và tất cả agency con cháu.
            Cache kết quả 10 phút.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Categories.IEndPointsService">
            <summary>
            Interface cho dịch vụ EndPoints.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IEndPointsService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm EndPoints dựa trên tham số SmartTable.
            </summary>
            <param name="param">Tham số SmartTable.</param>
            <returns>Kết quả tìm kiếm dưới dạng SmartTableResult.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IEndPointsService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.EndPointsModel)">
            <summary>
            Tạo mới hoặc cập nhật EndPoints.
            </summary>
            <param name="model">Mô hình EndPoints.</param>
            <returns>Kết quả của việc tạo mới hoặc cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IEndPointsService.GetById(System.Int32)">
            <summary>
            Lấy EndPoints theo Id.
            </summary>
            <param name="id">Id của EndPoints.</param>
            <returns>Mô hình EndPoints.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IEndPointsService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa EndPoints theo Id.
            </summary>
            <param name="id">Id của EndPoints.</param>
            <param name="currentUser">Người dùng hiện tại.</param>
            <returns>Kết quả của việc xóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IEndPointsService.AutoGenerate(Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tự động tạo EndPoints.
            </summary>
            <param name="currentUser">Người dùng hiện tại.</param>
            <returns>Kết quả của việc tự động tạo.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IEndPointsService.GetEndPoints(System.Int32)">
            <summary>
            Lấy thông tin điểm đầu cuối EndPoints.
            </summary>
            <param name="id">Id của EndPoints.</param>
            <returns>Thông tin điểm đầu cuối EndPoints.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Categories.EndPointsService">
            <summary>
            Dịch vụ EndPoints.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.EndPointsService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Categories.EndPoints},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Categories.Location})">
            <summary>
            Khởi tạo một instance của EndPointsService.
            </summary>
            <param name="endPointsRepository">Repository của EndPoints.</param>
            <param name="locationRepository">Repository của Location.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.EndPointsService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm EndPoints dựa trên tham số SmartTable.
            </summary>
            <param name="param">Tham số SmartTable.</param>
            <returns>Kết quả tìm kiếm dưới dạng SmartTableResult.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.EndPointsService.AdditionInfo(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.EndPointsItem})">
            <summary>
            Thêm thông tin bổ sung cho danh sách EndPointsItem.
            </summary>
            <param name="items">Danh sách EndPointsItem.</param>
            <returns>Danh sách EndPointsItem đã được thêm thông tin bổ sung.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.EndPointsService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.EndPointsModel)">
            <summary>
            Tạo mới hoặc cập nhật EndPoints.
            </summary>
            <param name="model">Mô hình EndPoints.</param>
            <returns>Kết quả của việc tạo mới hoặc cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.EndPointsService.Create(Lada.Framework.Data.Domains.Categories.EndPoints)">
            <summary>
            Tạo mới EndPoints.
            </summary>
            <param name="endPoints">Thực thể EndPoints.</param>
            <returns>Kết quả của việc tạo mới.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.EndPointsService.Update(Lada.Framework.Data.Domains.Categories.EndPoints)">
            <summary>
            Cập nhật EndPoints.
            </summary>
            <param name="endPoints">Thực thể EndPoints.</param>
            <returns>Kết quả của việc cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.EndPointsService.GetById(System.Int32)">
            <summary>
            Lấy EndPoints theo Id.
            </summary>
            <param name="id">Id của EndPoints.</param>
            <returns>Mô hình EndPoints.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.EndPointsService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa EndPoints theo Id.
            </summary>
            <param name="id">Id của EndPoints.</param>
            <param name="currentUser">Người dùng hiện tại.</param>
            <returns>Kết quả của việc xóa.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.EndPointsService.AutoGenerate(Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tự động tạo EndPoints theo từng batch 1000 bản ghi để tránh delay.
            </summary>
            <param name="currentUser">Người dùng hiện tại.</param>
            <returns>Kết quả của việc tự động tạo.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.EndPointsService.GetEndPoints(System.Int32)">
            <summary>
            Lấy thông tin điểm đầu cuối EndPoints.
            </summary>
            <param name="id">Id của EndPoints.</param>
            <returns>Thông tin điểm đầu cuối EndPoints.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService">
            <summary>
            Dịch vụ xử lý các thao tác liên quan đến địa điểm
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm địa điểm theo tham số SmartTable
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Kết quả tìm kiếm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Categories.LocationModel)">
            <summary>
            Tạo mới hoặc cập nhật địa điểm
            </summary>
            <param name="model">Thông tin địa điểm</param>
            <returns>Kết quả tạo mới hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.GetSugLocations(System.String,Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.SuggestionType,System.Int32,System.Nullable{Lada.Framework.Data.Domains.Categories.LocationLevelType})">
            <summary>
            Lấy danh sách gợi ý địa điểm theo từ khóa
            </summary>
            <param name="keyword">Từ khóa tìm kiếm</param>
            <param name="sugType">Loại gợi ý</param>
            <param name="parentId">ID cha</param>
            <returns>Danh sách gợi ý</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.GetSugLocationById(Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.SuggestionType,System.Int32)">
            <summary>
            Lấy danh sách gợi ý địa điểm theo ID
            </summary>
            <param name="sugType">Loại gợi ý</param>
            <param name="id">ID địa điểm</param>
            <returns>Danh sách gợi ý</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.GetById(System.Int32)">
            <summary>
            Lấy thông tin địa điểm theo ID
            </summary>
            <param name="id">ID địa điểm</param>
            <returns>Thông tin địa điểm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.GetByIds(System.Collections.Generic.List{System.Int32})">
            <summary>
            Lấy danh sách địa điểm theo danh sách ID
            </summary>
            <param name="ids">Danh sách ID</param>
            <returns>Danh sách địa điểm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa địa điểm theo ID
            </summary>
            <param name="id">ID địa điểm</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.GetFullAddress(System.Int32,System.Int32)">
            <summary>
            Lấy địa chỉ đầy đủ theo ID và cấp độ
            </summary>
            <param name="id">ID địa điểm</param>
            <param name="level">Cấp độ địa điểm</param>
            <returns>Địa chỉ đầy đủ</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.GetFullAddress(System.Collections.Generic.List{System.Int32},System.Int32)">
            <summary>
            Lấy danh sách địa chỉ đầy đủ theo danh sách ID và cấp độ
            </summary>
            <param name="ids">Danh sách ID</param>
            <param name="level">Cấp độ địa điểm</param>
            <returns>Danh sách địa chỉ đầy đủ</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.UpdateWardLatLong">
            <summary>
            Cập nhật tọa độ latlong cho các phường/xã chưa có
            </summary>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.UpdateEndPointsDistance">
            <summary>
            Cập nhật khoảng cách và văn bản khoảng cách của EndPoints
            </summary>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.UpdateCombinedName">
            <summary>
            Cập nhật tên kết hợp
            </summary>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.PlaceAutocomplete(System.String)">
            <summary>
            Tìm kiếm địa điểm tự động hoàn thành
            </summary>
            <param name="keyword">Từ khóa tìm kiếm</param>
            <returns>Kết quả tự động hoàn thành</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.PlaceDetail(System.String)">
            <summary>
            Lấy chi tiết địa điểm theo Place ID
            </summary>
            <param name="placeId">Place ID</param>
            <returns>Chi tiết địa điểm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.ImportFromAntin(System.String)">
            <summary>
            Import dữ liệu Location ĐVHC mới từ database Antin
            </summary>
            <param name="antinConnectionString">Connection string tới database AntinDb</param>
            <returns>Kết quả import</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.ImportFromExcel(System.IO.Stream,System.String)">
            <summary>
            Import dữ liệu Location 2 cấp từ file Excel.
            Format: Tỉnh/TP (Mã) | Tên Xã mới | Mã Xã mới
            </summary>
            <param name="file">File Excel upload</param>
            <returns>Kết quả import</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.BatchUpdateLatLong(System.Collections.Generic.List{System.Int32})">
            <summary>
            Cập nhật tọa độ lat/long hàng loạt cho các location theo danh sách ID
            </summary>
            <param name="ids">Danh sách ID location cần cập nhật</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService.GeocodeAddress(System.String)">
            <summary>
            Lấy toạ độ (lat/long) của một địa chỉ dạng văn bản qua Google Geocoding API.
            Dùng khi địa chỉ chưa được ghim toạ độ — ví dụ địa chỉ đơn hàng nhập tay.
            </summary>
            <param name="fullAddress">Địa chỉ đầy đủ, ví dụ "12 Lê Lợi, Phường Bến Nghé, TP Hồ Chí Minh"</param>
            <returns>Toạ độ tìm được; Result = Failed nếu Google không trả kết quả</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.LocationService.GetSugLocations(System.String,Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.SuggestionType,System.Int32,System.Nullable{Lada.Framework.Data.Domains.Categories.LocationLevelType})">
            <summary>
            Lấy danh sách gợi ý địa điểm theo từ khóa
            </summary>
            <param name="keyword">Từ khóa tìm kiếm</param>
            <param name="sugType">Loại gợi ý</param>
            <param name="parentId">ID cha</param>
            <returns>Danh sách gợi ý</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.LocationService.GetSugLocationById(Ladaer.BackEnd.Infrastructures.DTO.Items.Categories.SuggestionType,System.Int32)">
            <summary>
            Lấy danh sách gợi ý địa điểm theo ID
            </summary>
            <param name="sugType">Loại gợi ý</param>
            <param name="id">ID địa điểm</param>
            <returns>Danh sách gợi ý</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.LocationService.GeocodeAddress(System.String)">
            <summary>
            Lấy toạ độ của một địa chỉ dạng văn bản qua Google Geocoding API.
            Chỉ là lớp bọc công khai cho <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Categories.LocationService.GetLatLngFromAddress(System.String)"/> đã dùng nội bộ,
            để service khác (Deploy) geocode được địa chỉ đơn hàng mà không lặp lại logic gọi Google.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.LocationService.ImportFromAntin(System.String)">
            <summary>
            Import dữ liệu Location ĐVHC mới từ database Antin.
            Đọc Location 2 cấp từ AntinDb, insert vào LADA, và cập nhật MappedWardId cho Location 3 cấp.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.LocationService.ImportFromExcel(System.IO.Stream,System.String)">
            <summary>
            DTO nội bộ để đọc Location từ AntinDb
            </summary>
            <summary>
            Import dữ liệu Location 2 cấp từ file Excel.
            Format cột: Tỉnh/TP (Mã) | Tên Xã mới | Mã Xã mới
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Categories.MapWardListNavPermissions">
            <summary>
            Luật "ai thấy gì" của trang Bản đồ tô phường/xã (rule quyen-hien-thi).
            </summary>
            <remarks>
            Hàm thuần — nhận role đã phân giải qua <c>IUserRoleResolver</c>, không chạm DB hay <c>HttpContext</c>.
            <c>CanManage</c> không kéo theo <c>CanView</c>: các lời gọi nạp trang đòi đúng <c>MapWardList.View</c>,
            người chỉ có <c>Manage</c> mà thấy trang thì ăn 403 ngay khi nạp danh sách.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Categories.MapWardListNavPermissions.Founder">
            <summary>Vai bỏ qua mọi kiểm tra role — ẩn nút của Founder là dựng hàng rào không có thật.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Categories.MapWardListNavPermissions.View">
            <summary>Role của các lời gọi đọc: lists, get-by-id, provinces, wards.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Categories.MapWardListNavPermissions.Manage">
            <summary>Role của các lời gọi ghi: create-or-update, delete.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.MapWardListNavPermissions.Resolve(System.Collections.Generic.IEnumerable{System.String})">
            <param name="roles">Role đã phân giải; <c>null</c> hoặc rỗng = không có role nào</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Categories.MapWardListNavFlags">
            <summary>Cờ hiển thị của trang Bản đồ tô phường/xã — mỗi cờ gác đúng một bó quyền</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.MapWardListNavFlags.#ctor(System.Boolean,System.Boolean)">
            <summary>Cờ hiển thị của trang Bản đồ tô phường/xã — mỗi cờ gác đúng một bó quyền</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Categories.IMapWardListService">
            <summary>
            Danh sách phường/xã để tô trên trang Bản đồ tô phường/xã. Chỉ nhận phường/xã bộ 2 cấp
            (LevelType = 2, Level = 3) — ranh giới trên bản đồ là của đơn vị sau sáp nhập, ghép theo Location.Code.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IMapWardListService.GetProvinces">
            <summary>Tỉnh/thành bộ 2 cấp kèm số phường/xã — bước chọn tỉnh đầu trang</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.IMapWardListService.GetWards(System.Int32)">
            <summary>Toàn bộ phường/xã bộ 2 cấp của một tỉnh; <c>null</c> khi Id không phải tỉnh bộ 2 cấp</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.MapWardListService.ProvinceQuery">
            <summary>Tỉnh/thành bộ 2 cấp còn hiệu lực — Level = 1 (bộ 2 cấp không có cấp huyện)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.MapWardListService.WardQuery">
            <summary>Phường/xã bộ 2 cấp còn hiệu lực</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Categories.MenuAllowRoles">
            <summary>
            Luật "ô <c>Menu.AllowRoles</c> có mở cho người này không": so đúng TÊN role, không so chuỗi con. Trước 2026-10-10
            <c>MenuService</c> dùng <c>AllowRoles.Contains(role)</c> nên <c>Lead.Search</c> khớp <c>,FranchiseLead.Search,</c> —
            mọi Sale thấy menu "Đăng ký nhượng quyền" (H-4, plan nhượng quyền website §9), lái xe có role <c>Driver</c> thấy
            "Đánh giá lái xe". Hàm thuần để có test; số đo trước khi vá: <c>Sql/KhaoSat/MenuAllowRoles.KhaoSat.sql</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.MenuAllowRoles.IsOpenTo(System.String,System.Collections.Generic.IEnumerable{System.String})">
            <summary>
            Ô rỗng = ai có role cũng thấy. Ô có chữ thì tách theo dấu phẩy (bọc phẩy hai đầu hay không đều được), bỏ khoảng
            trắng, và phải có một tên trùng nguyên văn (phân biệt hoa thường như luật cũ) với role của người dùng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.MenuAllowRoles.VisibleTo(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Categories.Menu},System.Collections.Generic.IEnumerable{System.String})">
            <summary>
            Các mục menu người dùng thấy, xếp theo đúng thứ tự ghép của luật cũ: ô rỗng trước, rồi theo role ĐẦU TIÊN của
            người dùng mở được mục đó. <c>MenuService</c> sắp tiếp bằng <c>OrderBy(DisplayOrder)</c> (ổn định) nên các mục
            trùng <c>DisplayOrder</c> giữ nguyên chỗ trên sidebar như trước bản vá.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.MenuAllowRoles.RolePositions(System.Collections.Generic.IEnumerable{System.String})">
            <summary>Tên role (bỏ khoảng trắng hai đầu) → vị trí lần đầu xuất hiện trong danh sách role của người dùng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Categories.MenuAllowRoles.Rank(System.String,System.Collections.Generic.Dictionary{System.String,System.Int32})">
            <summary><c>null</c> = không mở; <c>-1</c> = ô rỗng; còn lại = vị trí role đầu tiên của người dùng có tên trong ô.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.IBlockValidationContextFactory">
            <summary>Dựng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext"/> cho một vật chủ khối nội dung.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContextFactory">
            <summary>
            Media domain lấy ĐÚNG nguồn mà ảnh tải lên dùng để ghép URL (<c>ImageService.GetUrlBySystemPath</c>): khoá
            <c>AppConfig</c> <c>Media.Domain</c>, lùi về <c>MediaProcessingSettings.Domain</c>. Lấy nguồn khác là ảnh vừa tải
            qua <c>UploadTopicContentPicture</c> bị chính validator từ chối.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.ICategoryService">
            <summary>
            Giao diện cho dịch vụ quản lý danh mục.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ICategoryService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh mục.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm danh mục.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ICategoryService.GetTree(System.String,Lada.Framework.Data.Enums.ContentType)">
            <summary>
            Lấy cây danh mục.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <returns>Danh sách cây danh mục.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ICategoryService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.CategoryModel)">
            <summary>
            Tạo hoặc cập nhật danh mục.
            </summary>
            <param name="model">Thông tin danh mục.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ICategoryService.GetById(System.Int32)">
            <summary>
            Lấy thông tin danh mục qua Id.
            </summary>
            <param name="CategoryId">Id của danh mục.</param>
            <returns>Thông tin danh mục.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ICategoryService.Delete(System.Int32)">
            <summary>
            Xóa danh mục.
            </summary>
            <param name="CategoryId">Id của danh mục.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.CategoryService">
            <summary>
            Triển khai dịch vụ quản lý danh mục.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.CategoryService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Cms.Category},Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRecordService)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Cms.CategoryService"/>.
            </summary>
            <param name="categoryRepository">Đối tượng IRepository của Category.</param>
            <param name="urlRecordService">Dịch vụ quản lý UrlRecord.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.CategoryService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.CategoryModel)">
            <summary>
            Tạo hoặc cập nhật danh mục.
            </summary>
            <param name="model">Thông tin danh mục.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.CategoryService.Create(Lada.Framework.Data.Domains.Cms.Category)">
            <summary>
            Tạo danh mục.
            </summary>
            <param name="category">Thông tin danh mục.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.CategoryService.Update(Lada.Framework.Data.Domains.Cms.Category)">
            <summary>
            Cập nhật danh mục.
            </summary>
            <param name="category">Thông tin danh mục.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.CategoryService.ChuanHoaMaNhanhNoiDung(System.String)">
            <summary>
            Mã nhánh nội dung luôn được lưu IN HOA và không khoảng trắng ("a1" → "A1"), vì kho nội dung
            tra danh mục bằng đúng chuỗi này. Chuỗi rỗng lưu thành null: một mã rỗng không phải là mã,
            và để nguyên chuỗi rỗng thì chỉ số duy nhất sẽ coi mọi danh mục chưa gắn mã là trùng nhau.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.CategoryService.Delete(System.Int32)">
            <summary>
            Xóa danh mục.
            </summary>
            <param name="categoryId">Id của danh mục.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.CategoryService.GetById(System.Int32)">
            <summary>
            Lấy thông tin danh mục qua Id.
            </summary>
            <param name="categoryId">Id của danh mục.</param>
            <returns>Thông tin danh mục.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.CategoryService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh mục.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm danh mục.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.CategoryService.GetTree(System.String,Lada.Framework.Data.Enums.ContentType)">
            <summary>
            Lấy cây danh mục.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <returns>Danh sách cây danh mục.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.CategoryService.GetChilds(Lada.Framework.Data.Domains.Cms.Category,System.Collections.Generic.List{Lada.Framework.Data.Domains.Cms.Category},System.Int32)">
            <summary>
            Lấy danh sách con của danh mục.
            </summary>
            <param name="category">Danh mục.</param>
            <param name="categorys">Danh sách danh mục.</param>
            <param name="level">Cấp độ.</param>
            <returns>Danh sách con của danh mục.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.CmsOptionalLink">
            <summary>
            Quy ước ghi các khoá liên kết tuỳ chọn mới thêm cho CMS ở đợt bưu cục (<c>Product.RouteFromCityId/RouteToCityId</c>,
            <c>Post.AgencyId</c>): <b>null = client không gửi → giữ nguyên</b>, 0 = bỏ liên kết, &gt; 0 = đặt.
            </summary>
            <remarks>
            Form Dịch vụ / Bài viết trước GĐ B1 chưa có các ô này nên gửi null ở mọi lần lưu — gán thẳng là mỗi lần lưu xoá mất
            liên kết marketing đã đặt (bẫy DTO nullable, docs/plan-buu-cuc.md §7). Số âm bị chặn ở bước validate trước khi tới đây.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.CmsOptionalLink.ApplyOnUpdate(System.Nullable{System.Int32},System.Nullable{System.Int32})">
            <summary>Giá trị mới khi SỬA bản ghi có sẵn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.CmsOptionalLink.ApplyOnCreate(System.Nullable{System.Int32})">
            <summary>Giá trị khi TẠO mới — AutoMapper chép nguyên 0 sang entity, 0 phải về null kẻo đụng khoá ngoại.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Cms.CmsOptionalLink.IsRouteCity">
            <summary>
            Đích hợp lệ của <c>Product.RouteFromCityId/RouteToCityId</c>: tỉnh bộ 2 cấp (sau sáp nhập).
            Dùng CHUNG cho bước validate lúc lưu và cho danh sách ô chọn của form — ô chọn đưa ra tỉnh nào thì lưu tỉnh đó
            phải qua, không trôi dạt. Xoá mềm do <c>IRepository.Query()</c> lọc.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Cms.CmsOptionalLink.IsLinkableAgency">
            <summary>
            Đích hợp lệ của <c>Post.AgencyId</c>: chi nhánh LADA hoặc chi nhánh nhượng quyền (không nhận khu vực, phòng ban).
            Dùng CHUNG cho <c>PostService.ValidateAgencyAsync</c> và <c>PostService.AgencyOptions</c> — cùng lý do như
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Cms.CmsOptionalLink.IsRouteCity"/>. Xoá mềm do <c>IRepository.Query()</c> lọc.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.CmsOptionalLink.NeedsValidation(System.Nullable{System.Int32},System.Nullable{System.Int32})">
            <summary>
            Giá trị gửi lên có phải kiểm hợp lệ không: chỉ khi ĐẶT một liên kết khác liên kết đang lưu. Form luôn gửi lại giá
            trị đang có (null = giữ, 0 = bỏ); kiểm lại cả giá trị không đổi thì một liên kết về sau hết hợp lệ (bưu cục bị xoá,
            tỉnh bị gộp) chặn MỌI lần lưu bài/trang — kể cả sửa một lỗi chính tả (review B1).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.IGoodsCategoryConfigService">
            <summary>
            Dịch vụ cấu hình tính giá cho danh mục hàng hóa động
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.CodePattern">
            <summary>
            Mã thuộc tính chỉ cho phép chữ thường, số và gạch ngang
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.PriceAxisRoles">
            <summary>
            Role được phép bật/tắt trục bảng giá. Người có <c>GoodsCategoryConfig.CreateOrUpdate</c> sửa được
            cấu hình, nhưng đổi trục là đổi cách tính tiền của cả danh mục nên cần thêm cửa hẹp hơn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm cấu hình danh mục hàng hóa
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.GetById(System.Int32)">
            <summary>
            Lấy cấu hình theo Id (kèm thuộc tính và lựa chọn còn hiệu lực)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.GetByCategoryId(System.Int32)">
            <summary>
            Lấy cấu hình theo danh mục hàng hóa (dùng cho form lên đơn và app khách)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.GetAllActive">
            <summary>
            Lấy toàn bộ cấu hình đang bật (kèm thuộc tính và lựa chọn còn hiệu lực)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryConfigModel)">
            <summary>
            Tạo mới hoặc cập nhật cấu hình kèm đồng bộ thuộc tính + lựa chọn
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.Delete(System.Int32)">
            <summary>
            Xóa mềm cấu hình kèm toàn bộ thuộc tính và lựa chọn con
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.CalculateAttributeFee(System.Int32,System.Collections.Generic.List{Lada.Framework.DTO.SelectedGoodsAttributeModel})">
            <summary>
            Tính tổng phí thuộc tính theo lựa chọn của client.
            Giá luôn resolve từ DB theo AttributeId / OptionId — không tin giá client gửi.
            Logic thuần dùng chung với Lada.AppBackEnd qua GoodsAttributeFeeHelper.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.BuildItem(Lada.Framework.Data.Domains.Cms.GoodsCategoryConfig)">
            <summary>
            Dựng Item kèm thuộc tính và lựa chọn đã sắp theo thứ tự hiển thị
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.ValidateAttributes(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryAttributeModel})">
            <summary>
            Kiểm tra hợp lệ danh sách thuộc tính, trả null nếu hợp lệ
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.FindOverlap(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsAttributeOptionModel})">
            <summary>
            Tìm cặp khoảng bị chồng nhau, trả null nếu không có
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.KiemTraDoiTruc(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryConfigModel)">
            <summary>
            Gác cửa và ghi log cho việc đổi trục bảng giá. Trả <see cref="F:Lada.Framework.DTO.Result.Success"/> khi được phép đi tiếp.
            </summary>
            <remarks>
            <para>
            Bật trục cho một thuộc tính là chuyển cả danh mục từ nhánh tính theo TRỌNG LƯỢNG sang nhánh tra Ô
            BẢNG GIÁ theo (tuyến, danh mục, lựa chọn trục) — mọi đơn thuộc danh mục đó ra số khác kể từ giây
            tiếp theo, không có bước duyệt nào ở giữa. Tắt trục cũng vậy, theo chiều ngược lại.
            </para>
            <para>
            Chỉ chặn khi cờ THỰC SỰ đổi, xem <see cref="M:Lada.Framework.Infrastructures.Services.PriceAxisRule.DiffAxisChanges(System.Collections.Generic.IEnumerable{Lada.Framework.Infrastructures.Services.PriceAxisState},System.Collections.Generic.IEnumerable{Lada.Framework.Infrastructures.Services.PriceAxisState})"/>: người sửa tên thuộc tính
            hay thêm lựa chọn trong danh mục đã có trục từ trước vẫn lưu được bình thường.
            </para>
            <para>
            Vai trò kiểm bằng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserRoleResolver"/> chứ không phải <c>User.IsInRole</c> — role không
            nằm trong JWT của hệ thống này nên <c>IsInRole</c> luôn trả false.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.KiemTraXoaLuaChonConOGia(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryConfigModel)">
            <summary>
            Chặn lưu nếu lần lưu này sẽ xoá mềm lựa chọn mà bảng giá theo loại hàng còn ô trỏ tới (nợ N8).
            </summary>
            <remarks>
            <para>
            Phải chạy <b>trước</b> mọi lệnh ghi: <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.SyncAttributes(System.Int32,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryAttributeModel},System.Int32,System.String)"/> xoá mềm ngay trong vòng lặp, chặn
            sau đó thì lựa chọn đã mất rồi. Đây cũng là lý do luật đứng ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryConfigModel)"/> chứ
            không nằm trong hai hàm Sync — hai hàm đó đã ở giữa chừng một lần ghi.
            </para>
            <para>
            Gom cả hai đường biến mất của một lựa chọn: (1) thuộc tính cha bị bỏ khỏi payload ⇒
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.SoftDeleteOptions(System.Int32,System.Int32,System.String)"/> xoá sạch lựa chọn con; (2) thuộc tính còn nhưng lựa chọn bị bỏ
            khỏi danh sách con. Bỏ sót đường nào cũng là bỏ lọt đúng ca hỏng cần chặn.
            </para>
            </remarks>
            <returns>Câu lỗi, hoặc <c>null</c> nếu không lựa chọn nào vướng ô giá.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.SyncAttributes(System.Int32,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryAttributeModel},System.Int32,System.String)">
            <summary>
            Đồng bộ thuộc tính của cấu hình: Id = 0 → thêm (hồi sinh bản ghi xoá mềm cùng mã nếu có);
            Id > 0 → sửa; thiếu trong payload → xóa mềm
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.ApDungModel(Lada.Framework.Data.Domains.Cms.GoodsCategoryAttribute,Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsCategoryAttributeModel)">
            <summary>
            Chép các trường của model vào entity thuộc tính. Dùng chung cho CẢ nhánh thêm và nhánh sửa.
            </summary>
            <remarks>
            <para>
            Trước đây hai nhánh chép tay riêng, và <c>IsPriceAxis</c> bị sót ở cả hai — đó chính là nợ N4:
            cờ trục có trong entity, có người đọc, nhưng <b>không đường nào ghi được</b>.
            </para>
            <para>
            Gộp về một chỗ vì mật thử đã chứng minh hai nhánh song song không được canh: bỏ hẳn dòng gán ở
            nhánh sửa mà toàn bộ 177 ca test vẫn xanh (service nằm ở project <c>Ladaer.BackEnd</c>, ngoài tầm
            tham chiếu của project test). Khi đã không có lưới test đỡ, cách chặn còn lại là làm cho việc sót
            nhánh <b>không thể xảy ra</b>: thêm trường mới vào đây là cả hai đường ghi cùng có.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.SyncOptions(System.Int32,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.GoodsAttributeOptionModel},System.Int32,System.String)">
            <summary>
            Đồng bộ lựa chọn của một thuộc tính theo cùng quy tắc diff theo Id
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.GoodsCategoryConfigService.SoftDeleteOptions(System.Int32,System.Int32,System.String)">
            <summary>
            Xóa mềm toàn bộ lựa chọn của một thuộc tính
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.IPostService">
            <summary>
            Giao diện cho dịch vụ quản lý bài viết.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IPostService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm bài viết
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm bài viết.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IPostService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostModel)">
            <summary>
            Tạo / cập nhật bài viết
            </summary>
            <param name="model">Thông tin bài viết.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IPostService.GetById(System.Int32)">
            <summary>
            Lấy thông tin bài viết qua Id
            </summary>
            <param name="postId">Id của bài viết.</param>
            <returns>Thông tin bài viết.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IPostService.Delete(System.Int32)">
            <summary>
            Xóa bài viết
            </summary>
            <param name="postId">Id của bài viết.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IPostService.UpdatePostStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostStatusModel)">
            <summary>
            Cập nhật trạng thái bài viết
            </summary>
            <param name="model">Thông tin trạng thái bài viết.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IPostService.AgencyOptions">
            <summary>
            Nguồn cho ô "Bưu cục liên quan" của form Bài viết: đúng tập chi nhánh mà bước lưu bài chấp nhận, sắp theo tên.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.PostService">
            <summary>
            Triển khai dịch vụ quản lý bài viết.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.PostService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Cms.Post},Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRecordService,Microsoft.Extensions.Options.IOptions{Ladaer.BackEnd.Infrastructures.AppSettings.CmsSetting},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Cms.Category},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Cms.Tag},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Cms.UrlRecord},Ladaer.BackEnd.Infrastructures.Services.Cms.ITagService,Ladaer.BackEnd.Infrastructures.Services.Cms.IPostCategoryService,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Cms.PostTag},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Cms.PostCategory},Lada.Framework.Infrastructures.Services.IContentFingerprint{Lada.Framework.Data.Domains.Cms.Post},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Categories.Agency},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Network.AgencyProfile})">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Cms.PostService"/>.
            </summary>
            <param name="postRepository">Đối tượng IRepository của Post.</param>
            <param name="urlRecordService">Dịch vụ quản lý UrlRecord.</param>
            <param name="cmsSettings">Cài đặt CMS.</param>
            <param name="categoryRepository">Đối tượng IRepository của Category.</param>
            <param name="tagRepository">Đối tượng IRepository của Tag.</param>
            <param name="urlRecordRepository">Đối tượng IRepository của UrlRecord.</param>
            <param name="agencyProfileRepository">Hồ sơ bưu cục — chỉ đọc tên hiển thị/trạng thái cho ô chọn bưu cục.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.PostService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm bài viết
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm bài viết.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.PostService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostModel)">
            <summary>
            Tạo hoặc cập nhật bài viết
            </summary>
            <param name="model">Thông tin bài viết.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.PostService.ValidateAgencyAsync(System.Nullable{System.Int32},System.Nullable{System.Int32})">
            <summary>
            Cập nhật bài viết
            </summary>
            <param name="post">Thông tin bài viết.</param>
            <returns>Kết quả của thao tác.</returns>
            <summary>
            Bưu cục gắn với bài (phân hệ bưu cục) phải là chi nhánh LADA hoặc nhượng quyền chưa xoá. null/0 không kiểm; giá
            trị trùng liên kết đang lưu (<paramref name="currentAgencyId"/>) cũng không kiểm lại
            (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.CmsOptionalLink.NeedsValidation(System.Nullable{System.Int32},System.Nullable{System.Int32})"/>). Trả null nếu hợp lệ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.PostService.AgencyOptions">
            <summary>
            Nguồn cho ô "Bưu cục liên quan" của form Bài viết. Lọc bằng CHÍNH <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Cms.CmsOptionalLink.IsLinkableAgency"/>
            của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.PostService.ValidateAgencyAsync(System.Nullable{System.Int32},System.Nullable{System.Int32})"/> nên mọi dòng đưa ra đều lưu được. Tên hiển thị/trạng thái công bố lấy từ hồ sơ
            bưu cục còn sống nếu có.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.PostService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostModel)">
            <summary>
            Tạo bài viết
            </summary>
            <param name="post">Thông tin bài viết.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.PostService.Delete(System.Int32)">
            <summary>
            Xóa bài viết
            </summary>
            <param name="postId">Id của bài viết.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.PostService.GetById(System.Int32)">
            <summary>
            Lấy thông tin bài viết qua Id
            </summary>
            <param name="postId">Id của bài viết.</param>
            <returns>Thông tin bài viết.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.PostService.UpdatePostStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostStatusModel)">
            <summary>
            Cập nhật trạng thái bài viết
            </summary>
            <param name="model">Thông tin trạng thái bài viết.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.PostService.UpdatePostCategories(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostCategoryModel})">
            <summary>
            Cập nhật danh mục bài viết
            </summary>
            <param name="postCategories">Danh sách danh mục bài viết.</param>
            <returns>Danh sách danh mục đã cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.PostService.UpdatePostTags(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.PostTagModel},System.Int32,System.String)">
            <summary>
            Cập nhật thẻ bài viết
            </summary>
            <param name="postTags">Danh sách thẻ bài viết.</param>
            <param name="createdBy">Người tạo.</param>
            <param name="createdByUserName">Tên người tạo.</param>
            <returns>Danh sách thẻ đã cập nhật.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockRouteRef">
            <summary>
            Tham chiếu bảng giá theo tuyến rút ra từ payload PriceTable mode=route —
            service dùng để kiểm tra tuyến/danh mục có tồn tại thật trong DB.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockFileRef">
            <summary>
            Tham chiếu tệp riêng tư của Cổng nhượng quyền rút ra từ payload khối Video (<c>source=file</c>) và Tài liệu —
            validator là hàm thuần nên không tự tra database; service kiểm tệp còn sống, đúng loại và THUỘC MỤC của topic
            đang lưu (docs/plan-cong-nhuong-quyen.md §3.4).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockFileRef.AllowDownload">
            <summary>Chỉ có nghĩa với tài liệu: khách được tải tệp về.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext">
            <summary>
            Ngữ cảnh kiểm khối: vật chủ (quyết loại khối, luật số lượng, bộ icon) và media domain (quyết ảnh https nào
            được nhận). Dựng bằng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Cms.IBlockValidationContextFactory"/> để media domain đọc đúng nguồn ảnh tải lên.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator">
            <summary>
            Kiểm tra cấu trúc Payload JSON của từng loại khối nội dung — schema mục 3.2 của
            docs/plan-block-dich-vu-website.md (loại 1–8) và §3.3 của docs/plan-nhuong-quyen-website.md (9–12, v1.2).
            Đây là ranh giới tin cậy: payload sai cấu trúc hoặc mang link/ảnh/icon ngoài luật bị chặn ngay lúc ghi,
            để trang public không bao giờ phải đỡ dữ liệu hỏng.
            </summary>
            <remarks>
            Schema v1.2 chỉ THÊM trường tuỳ chọn cho loại cũ — payload trang dịch vụ thiếu hết trường mới vẫn hợp lệ (test neo
            <c>ProductBlockPayloadAnchorTests</c> chạy mọi payload thật). Ba luật mới cũng chạm loại cũ, đều đã đo trên payload
            thật: link (<c>ctaLink</c> của Quy trình), ảnh (<c>url</c> của Hình ảnh), icon (<c>items[].icon</c> của Cam kết).
            Trường chuỗi đọc đã <c>Trim()</c> như <c>ProductBlockViewFactory.ReadString</c> — kiểm đúng thứ website sẽ in.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ValidateAll(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductBlockModel},Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext,System.Collections.Generic.List{System.ValueTuple{System.Int32,Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockRouteRef}},System.Collections.Generic.List{System.ValueTuple{System.Int32,Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockFileRef}})">
            <summary>
            Kiểm cả bộ khối của một vật chủ: từng khối theo <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.Validate(Lada.Framework.Data.Enums.ProductBlockType,System.String,System.String,Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext,Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockRouteRef@,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockFileRef})"/>, rồi luật số lượng của vật chủ
            (vd. trang nhượng quyền đúng một Form đăng ký). Null = hợp lệ; ngược lại câu báo lỗi tiếng Việt kèm số thứ tự
            khối. Tham chiếu bảng giá theo tuyến gom vào <paramref name="routeRefs"/>, tham chiếu tệp riêng tư gom vào
            <paramref name="fileRefs"/> — service kiểm chúng với DB.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.Normalize(Lada.Framework.Data.Enums.ProductBlockType,System.String)">
            <summary>
            Payload ở dạng LƯU. Hiện chỉ khối Video đổi: link biên tập viên dán (<c>url</c>) thành nhà cung cấp + mã video
            (<see cref="T:Lada.Framework.Data.Domains.Cms.BlockVideoEmbed"/>) và bỏ trường của nguồn không dùng — database không giữ URL tự do nào của video.
            Gọi SAU khi <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.Validate(Lada.Framework.Data.Enums.ProductBlockType,System.String,System.String,Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext,Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockRouteRef@,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockFileRef})"/> đã nhận; payload không đọc được thì trả nguyên.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.Validate(Lada.Framework.Data.Enums.ProductBlockType,System.String,System.String,Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext,Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockRouteRef@,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockFileRef})">
            <summary>
            Trả về null nếu khối hợp lệ với vật chủ trong <paramref name="context"/>, ngược lại trả thông báo lỗi tiếng Việt.
            <paramref name="title"/> là tiêu đề khối (cột <c>Title</c>) — bắt buộc với Hero vì nó là H1.
            Với PriceTable mode=route, trả thêm tham chiếu (routeId, goodsCategoryId)
            qua <paramref name="routeRef"/> để service kiểm tra tồn tại. Khối Video (tệp) và Tài liệu thêm tham chiếu tệp
            riêng tư vào <paramref name="fileRefs"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ValidateSteps(Newtonsoft.Json.Linq.JObject)">
            <summary>
            Quy trình. Cổng nhượng quyền thêm tuỳ chọn cho TỪNG bước: <c>resources</c> (nguồn lực cần chuẩn bị) và
            <c>duration</c> (thời lượng) — skin trang dịch vụ và trang đích không in hai trường này.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ValidateSlideshow(Newtonsoft.Json.Linq.JObject,Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext)">
            <summary>
            Trình chiếu ảnh: <c>slides[]</c> 1–40 {image, alt, title?, caption?} — <c>image</c> là ảnh tải lên (bắt buộc),
            <c>alt</c> bắt buộc vì slide là nội dung chứ không phải trang trí; <c>autoplaySec</c> 0–20 (0 = không tự
            chạy), <c>effect</c> <c>fade|kenburns</c>, <c>showCounter</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ValidateVideo(Newtonsoft.Json.Linq.JObject,Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockFileRef})">
            <summary>
            Video. <c>source=embed</c>: link YouTube / Vimeo biên tập viên dán (<c>url</c>) hoặc dạng đã chuẩn hoá
            (<c>provider</c> + <c>videoId</c> [+ <c>hash</c>]) — host ngoài danh sách bị từ chối. <c>source=file</c>:
            <c>fileId</c> của tệp video riêng tư. Tuỳ chọn: <c>poster</c> (ảnh tải lên), <c>description</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ReadEmbed(Newtonsoft.Json.Linq.JObject)">
            <summary>Video nhúng của payload — luật ưu tiên nằm ở <see cref="M:Lada.Framework.Data.Domains.Cms.BlockVideoEmbed.FromPayload(System.String,System.String,System.String,System.String)"/>, chung với factory website.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ValidateDocuments(Newtonsoft.Json.Linq.JObject,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockFileRef})">
            <summary>
            Tài liệu: <c>items[]</c> 1–20 {fileId, title, description?, allowDownload}. Một tệp chỉ xuất hiện một lần trong
            khối. Tệp có thật, đúng loại và thuộc mục hay không do service kiểm (validator không chạm database).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.CollectFileRefs(Lada.Framework.Data.Enums.ProductBlockType,System.String)">
            <summary>
            Tệp riêng tư mà một khối ĐÃ LƯU tham chiếu, đọc khoan dung: payload hỏng hoặc sai luật ở trường khác vẫn trả
            các tham chiếu đọc được. Cho những nơi cần biết "khối này đang trỏ tới tệp nào" mà không kiểm cả khối — cảnh
            báo "khối trỏ tới tệp không còn" ở màn Nội dung cổng, chặn xoá tệp đang dùng (CNQ-32). Đọc đúng hai trường mà
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ValidateVideo(Newtonsoft.Json.Linq.JObject,Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockFileRef})"/> / <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ValidateDocuments(Newtonsoft.Json.Linq.JObject,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockFileRef})"/> gom lúc kiểm — có test giữ hai bên khớp nhau.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ValidateFeatures(Newtonsoft.Json.Linq.JObject,Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext)">
            <summary>
            Cam kết / cột trụ. v1.2 thêm tuỳ chọn: <c>image</c> {url, alt}, <c>tags[]</c>, <c>ctaText</c>/<c>ctaLink</c>,
            <c>layout</c> <c>pillars</c>; <c>items[].icon</c> phải thuộc bộ icon cố định của vật chủ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ValidateHero(System.String,Newtonsoft.Json.Linq.JObject,Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext)">
            <summary>
            Khối mở đầu (S01). Tiêu đề khối là H1 nên bắt buộc. Payload: <c>eyebrow</c>, <c>description</c> (đoạn dẫn —
            trường chung v1.1, thay cho "lead" của bảng §3.3), <c>primaryButton</c>/<c>secondaryButton</c> {text, link},
            <c>image</c> {url, alt}, <c>showPattern</c> (hoạ tiết nền).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ValidateStats(Newtonsoft.Json.Linq.JObject,Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext)">
            <summary>
            Số liệu nổi bật (S02): <c>items[]</c> {value, label} 1–6 dòng, <c>showCoverage</c> (in danh sách tỉnh vùng phủ
            đọc từ dữ liệu — GĐ E), <c>note</c> (nguồn số liệu), <c>images[]</c> tối đa 2.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ValidateGallery(Newtonsoft.Json.Linq.JObject,Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext)">
            <summary>
            Bộ ảnh (S05): <c>items[]</c> 1–6 ảnh {url, alt, caption}. <c>url</c> được để trống — khung ảnh chờ buổi chụp
            (nợ NQW-3) in khung giữ chỗ theo <c>alt</c> — nhưng mỗi ảnh phải có ít nhất url hoặc alt.
            </summary>
            <remarks>
            Cổng nhượng quyền thêm tuỳ chọn <c>frame</c> (<c>none|phone|browser</c>) cho CẢ khối — khung điện thoại / trình
            duyệt quanh ảnh chụp màn hình; thiếu = ảnh trần như trước. <c>caption</c> của từng ảnh đã có từ v1.2.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ValidateLeadForm(Newtonsoft.Json.Linq.JObject)">
            <summary>
            Form đăng ký (S07) — CHỈ CHỮ: <c>eyebrow</c>, <c>description</c>, <c>submitText</c>, <c>successText</c>.
            Ô nhập, danh sách tỉnh và câu đồng ý xử lý dữ liệu cá nhân cố định ở view — câu đồng ý là văn bản pháp lý
            được ghi nguyên văn vào lead, không cho biên tập viên sửa; trường nào khác trong payload đều bị bỏ qua.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.CheckOptionalString(Newtonsoft.Json.Linq.JObject,System.String,System.Nullable{System.Int32},System.String)">
            <summary>Chuỗi tuỳ chọn: có mặt (khác null) thì phải là chuỗi và không dài quá <paramref name="maxLength"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.CheckOneOf(Newtonsoft.Json.Linq.JObject,System.String,System.Collections.Generic.IReadOnlyList{System.String})">
            <summary>Giá trị liệt kê tuỳ chọn (vd. <c>layout</c>); thiếu hoặc rỗng = mặc định.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.CheckLink(Newtonsoft.Json.Linq.JObject,System.String,System.String)">
            <summary>Link tuỳ chọn: rỗng = không có; có thì phải qua <see cref="M:Lada.Framework.Data.Domains.Cms.BlockUrl.IsSafeLink(System.String)"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.CheckImageUrl(Newtonsoft.Json.Linq.JObject,System.String,System.String,Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext)">
            <summary>Link ảnh tuỳ chọn: rỗng = không có; có thì phải qua <see cref="M:Lada.Framework.Data.Domains.Cms.BlockUrl.IsSafeImage(System.String,System.String)"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.CheckImage(Newtonsoft.Json.Linq.JToken,System.String,Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext)">
            <summary>Ảnh tuỳ chọn dạng object {url, alt}; <c>url</c> trống = khung giữ chỗ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.CheckImageArray(Newtonsoft.Json.Linq.JObject,System.String,System.Int32,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext)">
            <summary>Mảng ảnh {url, alt, caption} từ <paramref name="min"/> tới <paramref name="max"/>; mỗi ảnh phải có url hoặc alt.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.CheckButton(Newtonsoft.Json.Linq.JObject,System.String)">
            <summary>Nút {text, link}: bỏ trống cả hai = không có nút; điền một nửa thì báo thiếu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.CheckIcon(Newtonsoft.Json.Linq.JObject,System.String,Ladaer.BackEnd.Infrastructures.Services.Cms.BlockValidationContext)">
            <summary>Icon tuỳ chọn: thuộc bộ icon cố định mà skin của vật chủ vẽ được (khoá hoặc class đã lưu).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.CheckStringArray(Newtonsoft.Json.Linq.JObject,System.String,System.Int32,System.Int32)">
            <summary>Mảng chuỗi tuỳ chọn (vd. <c>tags</c>): mỗi mục là chuỗi không rỗng, giới hạn số mục và độ dài.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ValidateKeyFacts(Newtonsoft.Json.Linq.JObject)">
            <summary>
            Khối "trả lời thẳng" (plan GEO §3.6). Mọi trường nội dung đều tuỳ chọn — khối nào
            marketing chưa có số thì bỏ trống, không bịa — nhưng phải còn <b>ít nhất một dòng</b>
            để khối có nghĩa, và <c>updatedAt</c> thì bắt buộc: một bảng số không có ngày cập nhật
            là tín hiệu tin cậy âm.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ReadInt(Newtonsoft.Json.Linq.JObject,System.String)">
            <summary>Số nguyên không âm tuỳ chọn; trả -1 khi có mặt nhưng không phải số hợp lệ (nơi gọi báo lỗi).</summary>
            <remarks>
            <c>(long)token</c> NÉM <see cref="T:System.OverflowException"/> khi JSON mang số vượt long
            (Newtonsoft parse thành BigInteger mà vẫn giữ <c>JTokenType.Integer</c>). Hàm này chạy
            trước mọi thứ trong <c>ProductService.ValidateBlocksAsync</c> — nơi KHÔNG có try/catch —
            nên để lọt exception là API trả 500 thay vì một câu báo lỗi cho admin.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ReadDecimal(Newtonsoft.Json.Linq.JObject,System.String)">
            <summary>Số tiền tuỳ chọn; trả -1 khi có mặt nhưng không phải số hợp lệ. Xem ghi chú ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ReadInt(Newtonsoft.Json.Linq.JObject,System.String)"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.ReadOptionalString(Newtonsoft.Json.Linq.JObject,System.String)">
            <summary>
            Chuỗi tuỳ chọn, cùng luật với <c>ProductBlockViewFactory.ReadString</c> phía website:
            chỉ nhận <see cref="F:Newtonsoft.Json.Linq.JTokenType.String"/>, mọi kiểu khác coi như rỗng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.RequireString(Newtonsoft.Json.Linq.JObject,System.String)">
            <summary>Trường bắt buộc kiểu chuỗi, không rỗng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockPayloadValidator.RequireObjectArray(Newtonsoft.Json.Linq.JObject,System.String,System.String[])">
            <summary>Mảng object bắt buộc, không rỗng; mỗi phần tử phải có đủ các trường chuỗi kể tên.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.IProductService">
            <summary>
            Giao diện cho dịch vụ quản lý dịch vụ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IProductService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm dịch vụ
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm dịch vụ.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IProductService.GetById(System.Int32)">
            <summary>
            Lấy thông tin dịch vụ qua Id
            </summary>
            <param name="productId">Id của dịch vụ.</param>
            <returns>Thông tin dịch vụ.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IProductService.DeleteAsync(System.Int32)">
            <summary>
            Xóa bài viết
            </summary>
            <param name="productId">Id của bài viết.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IProductService.RouteCityOptions(System.String)">
            <summary>
            Nguồn cho ô "Tỉnh đi / Tỉnh đến" của form Dịch vụ: tỉnh bộ 2 cấp + gợi ý đoán từ tên trang.
            </summary>
            <param name="name">Tên trang đang soạn; rỗng thì không đoán, vẫn trả danh sách tỉnh.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IProductService.GetBlockProfile">
            <summary>
            Bộ khối của trang dịch vụ (vật chủ <c>Product</c>): loại khối được thêm + bộ icon cố định — editor FE đọc từ
            đây thay cho danh sách chép tay (nhượng quyền website GĐ F). Icon trang dịch vụ lưu class Font Awesome.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductService.GetById(System.Int32)">
            <summary>
            Lấy thông tin dịch vụ qua Id
            </summary>
            <param name="productId">Id của dịch vụ.</param>
            <returns>Thông tin dịch vụ.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel)">
            <summary>
            Tạo hoặc cập nhật dịch vụ
            </summary>
            <param name="model">Thông tin dịch vụ.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel)">
            <summary>
            Cập nhật dịch vụ
            </summary>
            <param name="product">Thông tin dịch vụ.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel)">
            <summary>
            Tạo dịch vụ
            </summary>
            <param name="product">Thông tin dịch vụ.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductService.RouteCityOptions(System.String)">
            <summary>
            Nguồn cho ô "Tỉnh đi / Tỉnh đến" của form Dịch vụ. <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.ProductRouteCityOptions.Provinces"/> dùng đúng
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Cms.CmsOptionalLink.IsRouteCity"/> của bước lưu nên tỉnh nào chọn được thì lưu được.
            </summary>
            <remarks>
            Đoán tuyến bằng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ServiceRouteGuesser"/> trên tên tỉnh Level 1 của <b>cả hai</b> bộ (như
            <c>list_service_pages</c>) vì tên trang dịch vụ phần lớn viết trước sáp nhập, rồi map từng vế sang bộ 2 cấp.
            Vế là tỉnh cũ đã sáp nhập thì Id gợi ý null nhưng tên đoán thô vẫn trả về.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductService.ValidateRouteCitiesAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel,System.Nullable{System.Int32},System.Nullable{System.Int32})">
            <summary>
            Tỉnh đi/đến của trang tuyến (phân hệ bưu cục) phải là tỉnh sống của bộ đơn vị hành chính 2 cấp
            (<c>Location</c> Level 1 LevelType 2). null/0 không kiểm; giá trị trùng tỉnh đang lưu cũng không kiểm lại
            (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.CmsOptionalLink.NeedsValidation(System.Nullable{System.Int32},System.Nullable{System.Int32})"/> — tỉnh cũ bị gộp không được chặn mọi lần lưu trang). Trả null nếu
            hợp lệ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductService.ValidateBlocksAsync(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductBlockModel})">
            <summary>
            Kiểm tra toàn bộ khối nội dung của model theo bộ khối trang dịch vụ (<see cref="F:Lada.Framework.Data.Domains.Cms.BlockHostProfiles.Product"/>,
            loại 1–8): cấu trúc payload theo loại, link/ảnh/icon theo luật v1.2, và với PriceTable mode=route thì tuyến +
            danh mục hàng phải tồn tại thật (gom kiểm tra tồn tại thành 2 truy vấn dù có nhiều block bảng giá).
            Trả về null nếu hợp lệ, ngược lại trả thông báo lỗi tiếng Việt.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductService.ReplaceBlocksAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductModel,System.DateTimeOffset)">
            <summary>
            Ghi lại toàn bộ khối nội dung của dịch vụ theo kiểu replace-all
            (xoá cứng bộ cũ rồi chèn bộ mới) — cùng pattern với Tags/Categories.
            model.Blocks == null nghĩa là client không gửi trường này → không đụng blocks hiện có.
            Xoá + chèn nằm trong một transaction để lỗi giữa chừng không làm mất trắng bộ block cũ.
            SortOrder được chuẩn hoá lại thành 0..n-1 theo thứ tự client gửi lên.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductService.UpdateProductTags(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductTagModel},System.Int32,System.String)">
            <summary>
            Cập nhật thẻ dịch vụ
            </summary>
            <param name="productTags">Danh sách thẻ dịch vụ.</param>
            <param name="createdBy">Người tạo.</param>
            <param name="createdByUserName">Tên người tạo.</param>
            <returns>Danh sách thẻ đã cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ProductService.DeleteAsync(System.Int32)">
            <summary>
            Xóa bài viết
            </summary>
            <param name="productId">Id của bài viết.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicNavPermissions">
            <summary>
            Cờ hiển thị của màn sửa topic và danh sách topic (rule <c>quyen-hien-thi</c>): người mở được topic bằng <c>Topic.GetById</c> (menu tắt
            "Nội dung trang nhượng quyền") chưa chắc lưu hay tải ảnh được — nút "Lưu lại" và nút tải ảnh của khối phải ẩn hẳn,
            nếu không bấm vào là 403 và interceptor đá cả SPA sang trang không quyền, mất bài đang sửa. Hàm thuần nhận danh sách
            role để có test; mỗi cờ đọc đúng bó role của endpoint nó gác (test đọc <c>[Authorize(Roles)]</c> bằng reflection).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicNavPermissions.SaveRole">
            <summary>POST api/Topic/CreateOrUpdate.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicNavPermissions.UploadPictureRole">
            <summary>POST api/Picture/UploadTopicContentPicture.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicNavPermissions.PublishRole">
            <summary>POST api/Topic/PublishBlocks — người duyệt nội dung (GĐ G).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicNavPermissions.PreviewRole">
            <summary>POST api/Topic/PreviewToken — như đọc topic: link chỉ lộ bản đang sửa mà role này đã đọc được.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicNavPermissions.DeleteRole">
            <summary>DELETE api/Topic/Delete — mục "Xóa" ở danh sách topic.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.ITopicPublishStore">
            <summary>
            Ghi các cột xuất bản của <see cref="T:Lada.Framework.Data.Domains.Cms.Topic"/> bằng MỘT lệnh <c>UPDATE</c> chỉ chạm đúng các cột đó (NQW-17).
            <c>UpdateAsync</c> cả dòng <c>Topic</c> (lưu topic) không ghi được các cột này — <c>TopicMap</c> đặt
            <c>AfterSaveBehavior.Ignore</c> — nên lưu topic đúng lúc người khác xuất bản không xoá mất lần xuất bản, và xuất
            bản không đè tiêu đề vừa sửa. Tách thành store riêng để <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService"/> test được bằng repo giả
            (<c>ExecuteUpdateAsync</c>/<c>ExecuteDeleteAsync</c> chỉ chạy trên EF thật). Cấp link xem trước cũng ở đây (thêm
            dòng + dọn link đã hết hạn).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ITopicPublishStore.SavePublishedAsync(System.Int32,System.String,System.DateTimeOffset,System.Int32,System.String)">
            <summary>Ghi ảnh chụp xuất bản + người/lúc xuất bản. False = không có dòng nào (topic đã bị xoá).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ITopicPublishStore.AddPreviewLinkAsync(System.Int32,System.String,System.DateTimeOffset,System.DateTimeOffset,System.Int32,System.String)">
            <summary>
            Thêm một link xem trước (băm token + hạn) — link khác của topic vẫn sống tới hạn của chúng; dọn luôn các link
            của topic này đã hết hạn trước <paramref name="now"/>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.ITopicService">
            <summary>
            Màn topic CMS (<c>api/Topic</c>). Topic là nội dung một mục Cổng nhượng quyền KHÔNG đi qua interface này với BẤT
            KỲ ai (kể cả Founder): không liệt kê, đọc / lưu / xuất bản / xem trước đều trả như không tồn tại, xoá bị từ chối.
            Nội dung cổng chỉ đi qua <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Cms.IFranchisePortalSectionContentService"/> (màn Nội dung cổng, role
            <c>FranchisePortal.Content</c> / <c>Manage</c>) — plan cổng §3.10, nợ CNQ-12.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ITopicService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm topic. Topic của Cổng nhượng quyền (theo tên hoặc theo tham chiếu từ mục) không bao giờ có trong
            danh sách.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm dịch vụ.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ITopicService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel)">
            <summary>
            Tạo/sửa topic. Người thao tác đọc từ <c>model.UpdatedBy</c> (controller đóng dấu). Topic của Cổng nhượng
            quyền trả "không tìm thấy"; tên hệ thống <c>FranchisePortal.…</c> không tạo mới và không đặt cho topic thường
            được ở đây — mục cổng chỉ sinh ra ở màn Nội dung cổng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ITopicService.GetById(System.Int32)">
            <summary>Topic của Cổng nhượng quyền trả model rỗng (như không tồn tại).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ITopicService.GetIdBySystemName(System.String)">
            <summary>
            Id của topic theo tên hệ thống (khớp nguyên chuỗi đã cắt khoảng trắng); 0 = không có (kể cả topic của Cổng
            nhượng quyền). Menu tắt của SPA mở thẳng một topic hệ thống (vd. <c>FranchiseLanding</c>) qua đây thay vì ghi
            cứng Id — Id khác nhau giữa các DB.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ITopicService.DeleteAsync(System.Int32)">
            <summary>
            Xóa bài viết
            </summary>
            <param name="topicId">Id của bài viết.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ITopicService.GetBlockProfile(System.String)">
            <summary>
            Bộ khối của topic theo tên hệ thống (khai ở <see cref="T:Lada.Framework.Data.Domains.Cms.BlockHostProfiles"/>) cho editor FE.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ITopicService.PublishBlocksAsync(System.Int32,System.Int32,System.String,System.String)">
            <summary>
            Xuất bản bộ khối đang sửa: kiểm TOÀN BỘ khối theo bộ khối của topic (luật lưu + luật số lượng lúc xuất bản)
            rồi chụp thành <c>Topic.PublishedBlocksJson</c> (+ <c>PublishedAt</c>, <c>PublishedBy</c>) qua
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Cms.ITopicPublishStore"/> — chỉ ghi 4 cột đó (NQW-17). Website chỉ đọc ảnh chụp này.
            <c>POST api/Topic/PublishBlocks</c>, role <c>Topic.Publish</c> (plan nhượng quyền website §6.3).
            </summary>
            <param name="expectedDraftVersion">
            Dấu <c>DraftVersion</c> người bấm đã thấy (GetById). Khác dấu bản đang sửa hiện tại → không xuất bản,
            <c>DraftChanged = true</c>. Null = không kiểm (chỉ dùng trong test/công cụ nội bộ).
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.ITopicService.IssuePreviewTokenAsync(System.Int32,System.Int32,System.String)">
            <summary>
            Cấp link xem trước bản ĐANG SỬA trên website, hạn 30 phút (<see cref="T:Lada.Framework.Data.Domains.Cms.TopicPreviewToken"/>). Mỗi lần cấp một
            link mới; link cấp trước vẫn sống tới hạn của nó. Chỉ topic có bộ khối và có trang công khai riêng
            (<c>PublicPath</c>).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.GetById(System.Int32)">
            <summary>
            Lấy thông tin dịch vụ qua Id
            </summary>
            <param name="topicId">Id của dịch vụ.</param>
            <returns>Thông tin dịch vụ.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel)">
            <summary>
            Tạo hoặc cập nhật dịch vụ
            </summary>
            <param name="model">Thông tin dịch vụ.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel)">
            <summary>
            Cập nhật dịch vụ
            </summary>
            <param name="topic">Thông tin dịch vụ.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel)">
            <summary>
            Tạo dịch vụ
            </summary>
            <param name="topic">Thông tin dịch vụ.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PublishDraftAsync(System.Int32,Lada.Framework.Data.Domains.Cms.BlockHostProfile,System.Int32,System.String,System.String)">
            <summary>
            Thân việc xuất bản — nơi gọi ĐÃ qua cửa của mình (màn topic: không phải nội dung cổng; màn Nội dung cổng: role
            cổng + mục có thật) và đã có bộ khối của topic.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.AddPreviewLinkAsync(System.Int32,System.Int32,System.String)">
            <summary>Sinh token xem trước, lưu băm + hạn. Trả token RÕ (chỉ có mặt trong link trả cho người gọi) và hạn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.HasUnpublishedChanges(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductBlockModel},System.String)">
            <summary>
            Bản đang sửa khác ảnh chụp đã xuất bản? So NỘI DUNG (<see cref="M:Lada.Framework.Data.Domains.Cms.PublishedBlocks.SameContent(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Cms.PublishedBlock},System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Cms.PublishedBlock})"/>), không so chuỗi
            JSON thô hay Id khối. Chưa xuất bản lần nào / ảnh chụp hỏng mà đã có khối → có thay đổi (xuất bản sẽ sửa).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.LoadBlockModelsAsync(System.Int32)">
            <summary>
            Khối đang sửa của topic, sắp theo thứ tự. Đọc qua <c>Query()</c> của chính bảng khối — xoá mềm lọc ở gốc truy
            vấn — thay cho Include từ <c>Topic</c>: Include thường KHÔNG lọc xoá mềm của bảng con (plan §7).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.CanAccessPortalContentAsync(System.Int32)">
            <summary>
            Người này có được chạm nội dung mục cổng không: <c>FranchisePortal.Content</c>, <c>FranchisePortal.Manage</c>
            hoặc Founder — đúng bó quyền của màn Nội dung cổng (plan §3.8). Chỉ cửa của màn Nội dung cổng
            (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Cms.IFranchisePortalSectionContentService"/>) hỏi câu này; màn topic thì từ chối nội dung cổng với mọi
            người, vì role <c>Topic.*</c> không được là đường đọc/sửa/xuất bản mục "Kế hoạch kinh doanh".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.FindHostedSectionAsync(System.Int32)">
            <summary>Mục cổng (chưa xoá) đang lấy topic này làm vật chủ; <c>null</c> = không có.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.IsPortalContentAsync(System.Int32,System.String)">
            <summary>
            Topic là nội dung của cổng: theo TÊN (<c>FranchisePortal.&lt;Code&gt;</c>) HOẶC theo THAM CHIẾU (một mục đang trỏ
            <c>TopicId</c> tới nó). Chỉ xét tên là để lại đường vòng "đổi tên rồi làm gì cũng được".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.CheckPortalTopicAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel)">
            <summary>
            Null = qua. Chặn ba việc ở màn topic: (1) tạo topic mang tên của cổng — topic cổng chỉ sinh ra cùng mục ở màn
            Nội dung cổng; (2) sửa topic của cổng (theo tên hoặc theo tham chiếu từ mục) — với MỌI người, trả đúng câu
            "không tìm thấy" của topic không tồn tại, nên cũng không đổi tên / tách mục khỏi nội dung của nó được;
            (3) đổi một topic thường thành tên của cổng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.CheckSystemNameAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel,Lada.Framework.Data.Domains.Cms.BlockHostProfile)">
            <summary>
            Tên hệ thống có bộ khối không được trùng topic khác — website tra trang theo tên hệ thống, hai topic cùng tên
            là biên tập viên sửa một trang còn website in trang kia. Kiểm cả khi không gửi khối.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.ValidateBlocksAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel,Lada.Framework.Data.Domains.Cms.BlockHostProfile)">
            <summary>
            Null = hợp lệ. <c>Blocks == null</c> = không gửi khối → không kiểm, không ghi. Topic không có bộ khối chỉ nhận
            danh sách rỗng. Topic có bộ khối: kiểm từng khối + luật số lượng, theo đúng thứ tự sẽ lưu (SortOrder) để
            "Khối nội dung thứ N" trong câu lỗi chỉ đúng khối biên tập viên thấy.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.ValidateBlockListAsync(System.Int32,System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductBlockModel},Lada.Framework.Data.Domains.Cms.BlockHostProfile)">
            <summary>
            Luật LƯU của một bộ khối, dùng chung cho màn topic và màn Nội dung cổng: từng khối theo schema + luật số lượng
            của vật chủ, rồi tệp riêng tư mà khối tham chiếu (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.CheckFileRefsAsync(System.Int32,System.Collections.Generic.List{System.ValueTuple{System.Int32,Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockFileRef}})"/>). Null = hợp lệ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.NormalizeBlocks(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductBlockModel})">
            <summary>Khối đã qua kiểm → đổi sang dạng LƯU (vd. link video dán vào thành nhà cung cấp + mã video).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.CheckFileRefsAsync(System.Int32,System.Collections.Generic.List{System.ValueTuple{System.Int32,Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockFileRef}})">
            <summary>
            Tệp riêng tư mà khối Video / Tài liệu tham chiếu phải còn sống, đúng loại và thuộc ĐÚNG MỤC mà topic này là
            vật chủ. Thiếu phép kiểm "thuộc mục" thì biên tập viên nhúng được tệp của mục khác (vd. mục "Kế hoạch kinh
            doanh" còn khoá) vào một mục đang mở cho khách — cửa <c>/tep</c> của website cũng kiểm lại điều này lúc đọc.
            Chạy cả lúc lưu lẫn lúc xuất bản: tệp có thể bị xoá giữa hai lần.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PortalFileFact">
            <summary>Phần của một dòng tệp riêng tư mà phép kiểm tham chiếu cần — không đọc <c>ExtractedText</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PortalFileFact.#ctor(System.Int32,Lada.Framework.Data.Enums.FranchisePortalFileKind,System.Nullable{System.Int32},System.String)">
            <summary>Phần của một dòng tệp riêng tư mà phép kiểm tham chiếu cần — không đọc <c>ExtractedText</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.LoadPortalFileFactsAsync(System.Collections.Generic.IEnumerable{System.Int32})">
            <summary>Các tệp riêng tư CÒN SỐNG trong danh sách Id — tệp đã xoá không có mặt trong kết quả.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.CheckFileRef(Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockFileRef,Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PortalFileFact,System.Int32)">
            <summary>
            Null = khối được tham chiếu tệp này. <paramref name="file"/> null = không có / đã xoá. Tài liệu không phải PDF
            trình duyệt không xem trong trang được nên phải cho tải — nếu không khách thấy tên tệp mà không mở được.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.ReplaceBlocksAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel,System.DateTimeOffset)">
            <summary>
            Ghi lại toàn bộ khối đang sửa theo kiểu replace-all (xoá cứng bộ cũ rồi chèn bộ mới, như ProductService).
            Nơi gọi đã mở transaction. SortOrder chuẩn hoá thành 0..n-1 theo thứ tự client gửi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.ReplaceBlockListAsync(System.Int32,System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductBlockModel},System.Int32,System.String,System.DateTimeOffset)">
            <summary>Thân việc của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.ReplaceBlocksAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.TopicModel,System.DateTimeOffset)"/> — đường ghi DUY NHẤT lên <c>TopicBlock</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.DeleteAsync(System.Int32)">
            <summary>
            Xóa bài viết
            </summary>
            <param name="topicId">Id của bài viết.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PortalSectionTopic">
            <summary>Topic vật chủ của một mục, đã có bộ khối của cổng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PortalSectionTopic.#ctor(System.Int32,Lada.Framework.Data.Domains.Cms.BlockHostProfile,System.String,System.Nullable{System.DateTimeOffset},System.String)">
            <summary>Topic vật chủ của một mục, đã có bộ khối của cổng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PortalSectionDoor">
            <summary>
            Kết quả mở cửa. <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PortalSectionDoor.Section"/> null = không có mục HOẶC người gọi thiếu role cổng (hai ca trả giống
            nhau). <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PortalSectionDoor.Topic"/> null = mục không có khối (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PortalSectionDoor.Error"/> null: mục bảng giá) hoặc nội dung lệch.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PortalSectionDoor.#ctor(Lada.Framework.Data.Domains.Network.FranchisePortalSection,Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PortalSectionTopic,System.String)">
            <summary>
            Kết quả mở cửa. <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PortalSectionDoor.Section"/> null = không có mục HOẶC người gọi thiếu role cổng (hai ca trả giống
            nhau). <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PortalSectionDoor.Topic"/> null = mục không có khối (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PortalSectionDoor.Error"/> null: mục bảng giá) hoặc nội dung lệch.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.OpenPortalSectionAsync(System.Int32,System.Int32)">
            <summary>
            Cửa của màn Nội dung cổng — MỌI đường của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Cms.IFranchisePortalSectionContentService"/> đi qua đây trước.
            Kiểm role ở service là lớp thứ hai sau <c>[Authorize]</c> của controller: một action thêm sau quên khai role
            vẫn không đọc / sửa được nội dung mục khoá.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.BlockFileSource">
            <summary>Phần của một khối (đang sửa hoặc đã xuất bản) mà phép tìm tệp tham chiếu cần.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.BlockFileSource.#ctor(Lada.Framework.Data.Enums.ProductBlockType,System.String,System.String)">
            <summary>Phần của một khối (đang sửa hoặc đã xuất bản) mà phép tìm tệp tham chiếu cần.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.FindFileWarningsAsync(System.Int32,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.BlockFileSource})">
            <summary>
            Khối trỏ tới tệp không còn dùng được, theo đúng luật của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.CheckFileRef(Ladaer.BackEnd.Infrastructures.Services.Cms.ProductBlockFileRef,Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService.PortalFileFact,System.Int32)"/> (đã xoá, sai loại, thuộc mục
            khác, tài liệu không phải PDF mà không cho tải) — CNQ-32: biên tập viên thấy trước khi lưu / xuất bản bị từ chối.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.IFranchisePortalSectionContentService">
            <summary>
            Khối nội dung của một mục Cổng nhượng quyền — CỬA của màn "Nội dung cổng" (docs/plan-cong-nhuong-quyen.md §3.9,
            §6.8, nợ CNQ-12): đọc / lưu bản đang sửa, xuất bản, cấp link xem trước. Người gọi phải có
            <c>FranchisePortal.Content</c> / <c>FranchisePortal.Manage</c> (hoặc Founder) — KHÔNG cần role <c>Topic.*</c> nào.
            </summary>
            <remarks>
            Mọi lời gọi đi vào bằng <b>Id mục</b>, không bằng Id topic: cửa này chỉ mở tới topic mà một mục đang trỏ tới, nên
            không dùng nó để chạm một topic thường được. Thân việc (luật khối, kiểm tệp tham chiếu, ghi <c>TopicBlock</c>, chụp
            bản xuất bản) là của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Cms.TopicService"/> — cửa này và màn topic gọi chung, không có đường ghi thứ hai.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IFranchisePortalSectionContentService.GetBlocksAsync(System.Int32,System.Int32)">
            <summary><c>null</c> khi không có mục hoặc người gọi thiếu role cổng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IFranchisePortalSectionContentService.SaveBlocksAsync(System.Int32,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductBlockModel},System.String,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>
            Thay TOÀN BỘ khối đang sửa của mục. Khối sai schema, hoặc trỏ tới tệp không thuộc đúng mục này, bị từ chối trước
            mọi lệnh ghi. Không đổi gì trên trang khách đang thấy — chỉ <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IFranchisePortalSectionContentService.PublishAsync(System.Int32,System.String,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)"/> mới đổi.
            </summary>
            <param name="expectedDraftVersion">
            Dấu <c>DraftVersion</c> của bản người lưu đã mở — bắt buộc. Lưu là thay cả bộ khối nên hai biên tập viên cùng
            mở một mục thì người lưu sau đè mất bản người lưu trước; dấu đã cũ → từ chối, <c>DraftChanged = true</c>.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IFranchisePortalSectionContentService.PublishAsync(System.Int32,System.String,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Xuất bản đúng bản người bấm đã thấy (<paramref name="expectedDraftVersion"/> bắt buộc), cần ít nhất 1 khối.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IFranchisePortalSectionContentService.IssuePreviewTokenAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>
            Cấp link xem trước bản ĐANG SỬA của đúng mục này trên website, hạn 30 phút (<see cref="T:Lada.Framework.Data.Domains.Cms.TopicPreviewToken"/>).
            Mỗi lần cấp một link mới; link cấp trước vẫn sống tới hạn của nó.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRecordService">
            <summary>
            Giao diện cho dịch vụ quản lý UrlRecord.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRecordService.GetByPostId(System.Int32)">
            <summary>
            Lấy thông tin bài viết qua Id.
            </summary>
            <param name="postId">Id của bài viết.</param>
            <returns>Thông tin UrlRecord của bài viết.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRecordService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordModel)">
            <summary>
            Tạo hoặc cập nhật UrlRecord.
            </summary>
            <param name="model">Thông tin UrlRecord.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRecordService.GenerateUrlRecord(System.String)">
            <summary>
            Tạo slug cho UrlRecord.
            </summary>
            <param name="slug">Slug cần tạo.</param>
            <returns>Slug đã được tạo.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRecordService.GenerateUrlRecord(System.String,Ladaer.BackEnd.Infrastructures.Services.Cms.UrlEntityType,System.Int32)">
            <summary>
            Tạo slug cho UrlRecord với loại thực thể.
            </summary>
            <param name="slug">Slug cần tạo.</param>
            <param name="urlEntityType">Loại thực thể của UrlRecord.</param>
            <returns>Slug đã được tạo.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRecordService.GetUrlRecordBySlug(System.String)">
            <summary>
            Lấy UrlRecord theo slug.
            </summary>
            <param name="slug">Slug của UrlRecord.</param>
            <returns>Thông tin UrlRecord.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRecordService.Add(Lada.Framework.Data.Domains.Cms.UrlRecord)">
            <summary>
            Thêm mới UrlRecord.
            </summary>
            <param name="urlRecord">Thông tin UrlRecord.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRecordService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm UrlRecord.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm UrlRecord.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRecordService.GetById(System.Int32)">
            <summary>
            Lấy thông tin UrlRecord theo Id.
            </summary>
            <param name="id">Id của UrlRecord.</param>
            <returns>Thông tin UrlRecord.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRecordService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordModel)">
            <summary>
            Tạo hoặc cập nhật UrlRecord.
            </summary>
            <param name="urlRecordModel">Thông tin UrlRecord.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRecordService.UpdateUrlRecordInfo(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordUpdateModel)">
            <summary>
            Cập nhật thông tin cơ bản của UrlRecord.
            </summary>
            <param name="model">Model chứa thông tin cập nhật UrlRecord.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService">
            <summary>
            Triển khai dịch vụ quản lý UrlRecord.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Cms.UrlRecord})">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService"/>.
            </summary>
            <param name="urlRecordRepository">Đối tượng IRepository của UrlRecord.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordModel)">
            <summary>
            Tạo hoặc cập nhật UrlRecord.
            </summary>
            <param name="model">Thông tin UrlRecord.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService.GetByPostId(System.Int32)">
            <summary>
            Lấy thông tin bài viết qua Id.
            </summary>
            <param name="postId">Id của bài viết.</param>
            <returns>Thông tin UrlRecord của bài viết.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService.GenerateUrlRecord(System.String)">
            <summary>
            Tạo slug cho UrlRecord.
            </summary>
            <param name="slug">Slug cần tạo.</param>
            <returns>Slug đã được tạo.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService.GenerateUrlRecord(System.String,System.Nullable{System.Int32})">
            <summary>
            Tạo slug cho UrlRecord.
            </summary>
            <param name="slug">Slug cần tạo.</param>
            <returns>Slug đã được tạo.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService.GenerateUrlRecord(System.String,Ladaer.BackEnd.Infrastructures.Services.Cms.UrlEntityType,System.Int32)">
            <summary>
            Tạo slug cho UrlRecord với loại thực thể.
            </summary>
            <param name="slug">Slug cần tạo.</param>
            <param name="urlEntityType">Loại thực thể của UrlRecord.</param>
            <param name="currentId">UrlRecordId hiện tại</param>
            <returns>Slug đã được tạo.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService.GetUrlRecordBySlug(System.String)">
            <summary>
            Lấy UrlRecord theo slug.
            </summary>
            <param name="slug">Slug của UrlRecord.</param>
            <returns>Thông tin UrlRecord.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService.Add(Lada.Framework.Data.Domains.Cms.UrlRecord)">
            <summary>
            Thêm mới UrlRecord.
            </summary>
            <param name="urlRecord">Thông tin UrlRecord.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm UrlRecord.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm UrlRecord.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService.GetById(System.Int32)">
            <summary>
            Lấy thông tin UrlRecord theo Id.
            </summary>
            <param name="id">Id của UrlRecord.</param>
            <returns>Thông tin UrlRecord.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordModel)">
            <summary>
            Tạo hoặc cập nhật UrlRecord.
            </summary>
            <param name="urlRecordModel">Thông tin UrlRecord.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService.Create(Lada.Framework.Data.Domains.Cms.UrlRecord)">
            <summary>
            Thêm mới UrlRecord.
            </summary>
            <param name="urlRecord">Thông tin UrlRecord.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService.Update(Lada.Framework.Data.Domains.Cms.UrlRecord)">
            <summary>
            Cập nhật UrlRecord.
            </summary>
            <param name="urlRecord">Thông tin UrlRecord.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRecordService.UpdateUrlRecordInfo(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRecordUpdateModel)">
            <summary>
            Cập nhật thông tin cơ bản của UrlRecord.
            </summary>
            <param name="model">Model chứa thông tin cập nhật UrlRecord.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlEntityType">
            <summary>
            Enum đại diện cho loại thực thể của UrlRecord.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRedirectService">
            <summary>
            Quản trị luật chuyển hướng URL của website công khai.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRedirectService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách luật, có lọc/sắp/phân trang theo <c>SmartTable</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRedirectService.GetById(System.Int32)">
            <summary>Một luật để mở form sửa; <c>null</c> khi không có hoặc đã xoá.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRedirectService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.UrlRedirectModel)">
            <summary>Thêm hoặc sửa một luật, sau khi qua hết các luật kiểm tra.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRedirectService.Delete(System.Int32,System.Int32,System.String)">
            <summary>Xoá mềm một luật.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRedirectService">
             <summary>
             Tầng lưu của bảng <c>UrlRedirect</c> — nơi đặt <b>toàn bộ</b> luật kiểm tra của miền này.
            
             <para>
             <b>Vì sao luật nằm ở đây mà không phải ở <c>DataAnnotations</c> của model.</b> Ba trong năm luật
             phải đọc dữ liệu: đường dẫn cũ đã có luật khác chưa, đích có trùng nguồn của luật khác không, có
             bản ghi <c>UrlRecord</c> nào cùng đường dẫn không. Chia đôi giữa hai chỗ là để hai chỗ lệch
             nhau, mà chỗ nào cũng trông như chỗ đúng.
             </para>
            
             <para>
             <b>Bảng này có hiệu lực trên trang công khai mà không cần deploy.</b> Middleware của website đọc
             nó với cache 5 phút, nên một dòng sai là một nhánh URL thật của website đi sai chỗ trong vòng
             năm phút — và với mã 301 thì công cụ tìm kiếm đã ghi nhận trước khi ai kịp sửa. Đó là lý do tầng
             này từ chối thẳng thay vì "lưu rồi cảnh báo".
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRedirectService.SortableFields">
            <summary>
            Các cột người dùng được phép sắp xếp theo.
            </summary>
            <remarks>
            <c>OrderByName</c> dựng biểu thức bằng reflection và <b>ném</b> khi tên cột không tồn tại,
            nên một khoá sắp xếp lạ từ client sẽ thành lỗi 500 thay vì bị bỏ qua. Danh sách trắng biến
            nó thành "dùng sắp xếp mặc định".
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRedirectService._searchUrlRepository">
            <summary>
            Hàng tồn kho URL dựng từ chính <c>sitemap.xml</c> (miền đồng bộ công cụ tìm kiếm, GĐ B).
            </summary>
            <remarks>
            Cần nó vì sitemap sinh từ <b>bảy</b> nguồn, mà hơn mười đường dẫn tĩnh và toàn bộ trang bưu
            cục <c>/mang-luoi/{slug}</c> không đi qua <c>UrlRecord</c>. Soi mỗi <c>UrlRecord</c> rồi kết
            luận "không còn trong sitemap" là nói về một nhóm mình chưa kiểm.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRedirectService.BuildQuery(System.Boolean)">
            <summary>
            Phép chiếu dùng chung của màn danh sách: bảng luật cộng cờ đối chiếu với sitemap.
            </summary>
            <param name="sitemapInventoryReady">
            Hàng tồn kho sitemap (<c>SearchUrl</c>) đã có dữ liệu hay chưa — quyết định cờ
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.UrlRedirectItem.ConflictsWithSitemap"/> được phép kết luận <c>false</c> hay phải
            trả <c>null</c>.
            </param>
            <remarks>
            Mọi truy vấn con <c>Any</c> dịch được sang SQL nên bộ lọc và phân trang vẫn chạy ở DB, không
            phải kéo cả bảng về rồi lọc trong bộ nhớ. Slug của <c>UrlRecord</c> không có dấu <c>/</c>
            đầu nên phải cắt một ký tự của <c>FromPath</c> trước khi so.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRedirectService.StampDaysActive(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.UrlRedirectItem})">
            <summary>
            Điền <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Cms.UrlRedirectItem.DaysActive"/> — số ngày luật đã tồn tại, để giao diện không
            trình bày <c>HitCount = 0</c> của một luật vừa tạo như thể đã đo được là không ai vào.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRedirectService.FindChainConflictAsync(System.Int32,System.String,System.String,System.Boolean)">
            <summary>
            Chặn chuỗi và vòng: đích của luật này không được là nguồn của luật khác, và nguồn của luật
            này không được là đích của luật khác. Trả <c>null</c> khi không có xung đột.
            </summary>
            <remarks>
            <b>Chặn chuỗi là chặn luôn mọi vòng, dài bao nhiêu cũng vậy.</b> Nếu không luật nào có đích
            trùng nguồn của luật nào, thì không dựng được đường đi hai bước — mà vòng thì bắt buộc phải
            đi ít nhất hai bước. Vì thế ở đây không cần thuật toán dò vòng, chỉ cần kiểm hai chiều.
            <para>
            <b>Chỉ xét các luật đang bật, và chỉ xét khi luật đang lưu cũng đang bật.</b> Một luật tắt
            không chuyển hướng gì nên không tạo được chuỗi. Bật nó lên là một lần sửa, và lần sửa đó lại
            đi qua đúng hàm này.
            </para>
            <para>
            Đích được lưu ở dạng có thể mang query, nên phải quy về đường dẫn trước khi so — việc đó làm
            trong bộ nhớ. Bảng này là bảng nhỏ do người nhập tay (bốn dòng lúc dựng, hàng chục dòng là
            nhiều), nên tải danh sách luật đang bật về là rẻ; đổi lại được dùng đúng một hàm chuẩn hoá
            với middleware thay vì viết lại phép cắt query bằng SQL.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRedirectService.ResolveSortField(System.String)">
            <summary>Đưa khoá sắp xếp của giao diện về đúng tên cột trong danh sách trắng; <c>null</c> = dùng mặc định.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Cms.UrlRedirectService.AppendNote(System.String,System.String)">
            <summary>Nối một dòng vào ghi chú sẵn có mà không xoá chữ của người nhập.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentAccessTokenService">
            <summary>
            Token truy cập cá nhân (PAT) <c>lada_cs_…</c> cho MCP — đường phụ cho Claude Code (<c>--header</c>) và kiểm thử
            (plan §3.4). Chỉ lưu SHA-256; chuỗi gốc hiện một lần lúc tạo. Token luôn gắn với một user thật, không Founder.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentAccessTokenService.List(System.Nullable{System.Int32},System.Boolean)">
            <summary>Danh sách token (không chứa chuỗi/hash), mới trước; mặc định ẩn token đã thu hồi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentAccessTokenService.Validate(System.String)">
            <summary>Kiểm chuỗi token lúc xác thực /mcp: tồn tại, chưa thu hồi, chưa hết hạn, user còn sống, không bị khoá.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentAccessTokenService.Hash(System.String)">
            <summary>SHA-256 hex thường của toàn bộ chuỗi token — public để test và script kiểm thử tính cùng một cách.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService">
            <summary>
            Bài viết trong kho nội dung AI (đặc tả §5.2–§5.3). GĐ A chỉ có tạo bản nháp, đọc, tìm và render;
            duyệt / điền ô / đăng thuộc các giai đoạn sau.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.CreateDraft(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)">
            <summary>
            Tạo bản nháp bài 4 phần. Chạy hết mọi lớp kiểm tra (hình thức → đề → slug → cổng chặn → phiếu chấm → ảnh → ô)
            rồi mới ghi, tất cả trong một transaction. Không ghi gì khi bất kỳ lớp nào báo lỗi cứng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.CheckForm(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleModel)">
            <summary>
            Kiểm hình thức payload y như bước đầu của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.CreateDraft(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)"/> mà không ghi gì — để dry-run nhập
            liệu báo được "file này sẽ bị từ chối vì thiếu gì" thay vì chỉ "đọc được".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.GetById(System.Int32)">
            <summary>Bài đầy đủ theo Id — null nếu không có (controller trả 404).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.GetByTopicCode(System.String)">
            <summary>Bài đầy đủ theo mã đề — null nếu đề chưa có bài.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách bài rút gọn theo SmartTableParam (Keyword, Status, CategoryL2, PageType, WeekNo, DraftedBy).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.Render(System.Int32,System.String)">
            <summary>
            Render thân bài + FAQ ở dạng html hoặc markdown (GĐ A chưa thay ô). Null nếu không có bài;
            format lạ → VALIDATION_ERROR.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleUpdateModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)">
            <summary>
            Sửa nội dung bài (đặc tả §5.2 <c>update_article</c>). Kiểm <c>ExpectedVersion</c> trước mọi thứ,
            chạy lại cổng chặn / phiếu chấm / luật ảnh như lúc tạo, trích lại ô dữ liệu và ghi một phiên bản mới —
            tất cả trong một transaction.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.SetStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleStatusModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)">
            <summary>
            Đổi trạng thái bài theo máy trạng thái §3.3e. Không đi qua đây được:
            <c>Approved</c> và đường rút lại từ <c>Approved</c> (cả hai chiều đi qua
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.Approve(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleApproveModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)"/> / <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.RevokeApproval(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleRevokeApprovalModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)"/> vì gác bằng role khác), và
            <c>Published</c> (job đồng bộ CMS — GĐ F).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.Approve(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleApproveModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)">
            <summary>
            Duyệt đăng: chạy đủ 8 điều kiện §3.3d rồi mới chuyển sang <c>Approved</c>. Thiếu bất kỳ điều kiện
            nào → <c>PUBLISH_PRECONDITION_FAILED</c> kèm <c>Extra.Missing</c> và <c>Extra.Checks</c>,
            <b>không ghi gì</b> — kể cả ba cờ ghi đè trong payload.
            <para>
            Không có đường vòng cho ai cả (plan §7.4c): Founder qua đúng hàm này. Đường ghi duy nhất cho
            <c>PublishWithoutImages</c> / <c>OverrideNote</c> cũng ở đây, vì hai cờ đó chỉ có nghĩa trong
            một lần duyệt cụ thể.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.RevokeApproval(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleRevokeApprovalModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)">
            <summary>
            Rút lại bài đã duyệt (<c>Approved</c> → <c>PendingReview</c>), lý do bắt buộc. Tách khỏi
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.SetStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleStatusModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)"/> vì <b>huỷ</b> một quyết định duyệt phải cần đúng quyền đã ra quyết định đó.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.SetPeople(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticlePeopleModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)">
            <summary>Gán tác giả / người kiểm tra cho bài — điều kiện đăng §3.3d(2)(3) đọc hai trường này.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.CheckSlug(System.String)">
            <summary>
            <c>check_slug</c> (đặc tả §5.3): slug còn trống không, kèm gợi ý. Nhìn cả bài trong kho lẫn
            <c>UrlRecord</c> của CMS <b>kể cả bản xoá mềm</b> — URL cuối cùng vẫn là <c>/{slug}</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.Versions(System.Int32)">
            <summary>
            Lịch sử phiên bản của một bài, mới nhất trước. Null khi không có bài (controller trả 404).
            Không kèm nội dung từng bản — xem <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentArticleVersionItem"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.SetImageStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageStatusModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)">
            <summary>
            Cập nhật kết quả một dòng ảnh sau khi nộp file (đặc tả §5.3 <c>set_image_status</c>):
            <c>AssetUrl</c>/<c>OgAssetUrl</c>/<c>Status</c>/ghi chú kiểm. Không đụng thông số ảnh và
            <b>không</b> tạo phiên bản bài — bộ ảnh không nằm trong ảnh chụp <c>ContentArticleVersion</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.DeleteImage(System.Int32,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)">
            <summary>
            Bỏ một ảnh khỏi bộ ảnh của bài (xoá mềm). Dùng khi bài không cần tấm đó — trước đây bộ ảnh
            sinh một lần lúc tạo nháp rồi không ai bỏ bớt được.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.PublishCheck(System.Int32)">
            <summary>
            Chạy tám điều kiện đăng §3.3d ở chế độ <b>chỉ đọc</b> để màn duyệt hiện danh sách còn thiếu.
            Không đổi gì trong DB; GĐ E mới nối lớp kiểm này vào <c>SetStatus(Approved)</c>.
            Null khi không có bài.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.TopicCodeUniqueIndex">
            <summary>Tên unique index trong ContentArticleMap — nhận diện va chạm đồng thời từ chuỗi lỗi mà Repository bọc lại.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService._imageKit">
            <summary>Bộ công cụ ảnh — chỉ dùng để ghép prompt đầy đủ khi trả chi tiết bài, không ghi gì.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.NormalizeUnicode``1(``0)">
            <summary>
            Chuẩn hoá toàn bộ chuỗi trong payload về FormC bằng một vòng JSON (Newtonsoft giữ nguyên JsonExtensionData
            của Brief). Chuỗi Unicode hỏng (surrogate lẻ) không chuẩn hoá được thì giữ nguyên payload.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.ValidateForm(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleModel)">
            <summary>Kiểm hình thức payload — gom mọi lỗi, Field = tên trường PascalCase của DTO.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.ValidateImageLengths(Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreValidationResult,Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageModel,System.Int32)">
            <summary>Độ dài các cột nvarchar(n) của ContentImage; FrameCode/Lane so trên bản Trim vì entity lưu bản Trim.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.Truncate(System.String,System.Int32)">
            <summary>Cắt về đúng độ dài cột; null → chuỗi rỗng (cột IsRequired).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.SuggestSlug(System.String)">
            <summary>Slug trống đầu tiên trong slug-2, slug-3… (tối đa 20 thử); null nếu đều đã dùng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.DetailQuery">
            <summary>Chỉ đọc: không tracking; collection Images tách truy vấn để tránh tích Descartes.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.BuildDetail(Lada.Framework.Data.Domains.ContentStore.ContentArticle,Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentImageKitSnapshot)">
            <summary>
            Map phần phẳng bằng AutoMapper rồi điền JSON + ảnh đã sắp thứ tự, và ghép prompt đầy đủ
            cho từng ảnh từ <paramref name="kit"/> (khối STYLE BASE + tên khuôn + ảnh tham chiếu).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.BuildFaqMarkdown(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentFaqModel})">
            <summary>Khối FAQ dạng Markdown nối sau thân bài; chuỗi rỗng khi không có FAQ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.ChangedFieldNames(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticlePatchModel)">
            <summary>Tên các trường thật sự có trong patch — ghi vào audit thay vì ghi cả nội dung bài.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.ValidatePatchForm(System.String,System.Collections.Generic.List{System.String},System.String,System.String,System.String)">
            <summary>Kiểm hình thức bản đã hợp nhất (patch + bài cũ) — cùng giới hạn cột như lúc tạo.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.RequiresReason(Lada.Framework.Data.Enums.ContentArticleStatus)">
            <summary>Trạng thái mà người duyệt phải nói rõ vì sao — để bài không bị treo mà không ai biết lý do.</summary>
            <summary>
            Đích bắt buộc nêu lý do. <see cref="F:Lada.Framework.Data.Enums.ContentArticleStatus.NeedsRewrite"/> nằm đây vì lý do là
            <b>đầu vào của trợ lý viết lại</b> — nó đọc đúng câu đó để biết sửa gì; "chưa đạt" cộc lốc thì nó
            viết ra đúng bài cũ (quyết định 2026-09-13). Bản sao của luật này ở frontend là
            <c>STATUS_CAN_LY_DO</c> trong <c>constants/contentStore.js</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.IsSafeAssetUrl(System.String)">
            <summary>Đường dẫn ảnh chấp nhận được: tương đối, hoặc http/https tuyệt đối. Chặn <c>javascript:</c>/<c>data:</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.BuildPublishCheckInput(Lada.Framework.Data.Domains.ContentStore.ContentArticle,Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleApproveModel)">
            <summary>
            Dựng đầu vào cho <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IPublishPreconditionChecker"/> từ một bài đã nạp kèm <c>Author</c> và
            <c>Images</c>. Dùng chung cho đường chỉ đọc (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.PublishCheck(System.Int32)"/>) và đường ghi
            (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.Approve(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleApproveModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)"/>) — nhân bản logic này ra hai chỗ là cách chắc chắn để hai đường lệch nhau.
            </summary>
            <param name="overrides">
            Ba cờ ghi đè do người duyệt gửi trong chính lời gọi duyệt; null thì lấy giá trị đang lưu của bài.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.FindForEdit(System.Nullable{System.Int32},System.String)">
            <summary>Bài để sửa — có tracking (khác <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.DetailQuery"/> chỉ đọc). Id thắng khi gửi cả hai.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.NewVersion(Lada.Framework.Data.Domains.ContentStore.ContentArticle,System.String,System.String,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor,System.DateTimeOffset)">
            <summary>Ảnh chụp nội dung hiện tại của bài thành một dòng <see cref="T:Lada.Framework.Data.Domains.ContentStore.ContentArticleVersion"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.ChoTrongConSot(System.Int32)">
            <summary>
            Cảnh báo mềm khi bài còn chuỗi <c>[[CẦN …]]</c> của cơ chế ô chờ đã bỏ (2026-09-12).
            Cảnh báo chứ không chặn: chuỗi ấy bị xoá lúc đăng, và người duyệt là người quyết định đăng hay không.
            </summary>
            <remarks>
            Câu cảnh báo phải nói <b>cách làm đúng</b>, không chỉ nói cách cũ đã bỏ — trợ lý AI đọc đúng chuỗi này
            rồi tự sửa bài; nói trống "cơ chế đã bỏ" thì nó không biết phải làm gì thay thế.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.CountImages(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageModel})">
            <summary>Luôn đủ 4 khoá tên enum ContentImageDecision.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleService.ToImageModel(Lada.Framework.Data.Domains.ContentStore.ContentImage)">
            <summary>Dòng ảnh đã lưu → DTO, để chạy lại <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IImageSpecValidator"/> khi sửa thân bài.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleTransitions">
            <summary>
            Máy trạng thái bài viết (plan §3.3e) — <b>một nơi duy nhất</b> quyết định bài được đi từ đâu tới đâu
            và bản nháp mới sinh ra ở trạng thái nào.
            <para>
            Gom về đây theo khuyến nghị review GĐ A: trước đó luật "điểm &lt; 70 thì ép NeedsRewrite" nằm trong
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.SelfScoreValidator"/> còn bảng chuyển trạng thái chưa có, nên hai nửa của cùng một luật ở
            hai chỗ. <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.SelfScoreValidator"/> nay chỉ tính điểm và gọi <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleTransitions.InitialStatus(System.Nullable{System.Boolean},System.Int32,System.Nullable{Lada.Framework.Data.Enums.ContentSelfScoreVerdict},System.String@)"/>.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleTransitions.Allowed">
            <summary>
            Bảng chuyển hợp lệ. Đọc: từ khoá → các đích được phép. Trạng thái không có trong bảng
            (<see cref="F:Lada.Framework.Data.Enums.ContentArticleStatus.Published"/>, <see cref="F:Lada.Framework.Data.Enums.ContentArticleStatus.Rejected"/>) là điểm cuối.
            <para>
            <b>Hàng đợi viết lại (quyết định 2026-09-13).</b> <see cref="F:Lada.Framework.Data.Enums.ContentArticleStatus.NeedsRewrite"/> vốn chỉ do
            hệ thống đặt lúc tự chấm (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleTransitions.InitialStatus(System.Nullable{System.Boolean},System.Int32,System.Nullable{Lada.Framework.Data.Enums.ContentSelfScoreVerdict},System.String@)"/>); nay người duyệt còn đánh dấu tay được từ
            <c>PendingReview</c> / <c>NeedsData</c> / <c>Hold</c> — đó chính là hàng đợi mà trợ lý AI lấy về viết lại
            (<c>list_articles status=needs_rewrite</c>). Lý do bắt buộc, vì trợ lý đọc đúng câu đó mà sửa.
            <b>Cố ý không mở</b> cho <c>Approved</c> / <c>Published</c> / <c>Rejected</c>: bài đã duyệt phải rút duyệt
            (<c>RevokeApproval</c>, role <c>ContentStore.Approve</c>) trước, không thì kho và website lệch nhau
            mà không ai biết.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleTransitions.ManualTargetsNotAllowed">
            <summary>Đích chỉ đạt tới bằng đường riêng, không qua <c>set_article_status</c> của người duyệt.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleTransitions.IsApprovalOnlySource(Lada.Framework.Data.Enums.ContentArticleStatus)">
            <summary>
            Trạng thái mà mọi đường ra đều cần role <c>ContentStore.Approve</c>, nên không hiện trong danh sách
            đích của <c>set_article_status</c>: rút lại một quyết định duyệt phải cần đúng quyền đã duyệt.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleTransitions.IsUpdateOnly(Lada.Framework.Data.Enums.ContentArticleStatus,Lada.Framework.Data.Enums.ContentArticleStatus)">
            <summary>Chuyển chỉ hợp lệ khi đi qua <c>update_article</c>, không phải qua đổi trạng thái tay.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleTransitions.ManualTargetsFrom(Lada.Framework.Data.Enums.ContentArticleStatus)">
            <summary>Các đích người duyệt bấm được ngay bây giờ (bỏ đích cần đường riêng).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleTransitions.Describe(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Enums.ContentArticleStatus})">
            <summary>Danh sách đích hợp lệ dạng chữ, để nhét vào thông báo INVALID_TRANSITION.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentArticleTransitions.InitialStatus(System.Nullable{System.Boolean},System.Int32,System.Nullable{Lada.Framework.Data.Enums.ContentSelfScoreVerdict},System.String@)">
            <summary>
            Trạng thái của bản nháp vừa tạo / vừa sửa, suy từ phiếu tự chấm (§3.3c):
            tự khai chưa qua cổng chặn hoặc tổng &lt; 70 → <see cref="F:Lada.Framework.Data.Enums.ContentArticleStatus.NeedsRewrite"/> (ưu tiên),
            kết luận "tạm giữ" → <see cref="F:Lada.Framework.Data.Enums.ContentArticleStatus.Hold"/>, còn lại chờ duyệt.
            </summary>
            <param name="reason">Lý do ép trạng thái, ghi vào <c>ContentArticle.StatusReason</c>; null nếu không ép.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentAuthorService">
            <summary>
            Tác giả / người kiểm tra đứng tên trên bài (đặc tả §4.8 <c>people</c>, §5.3 <c>list_people</c>).
            Đây là hồ sơ E-E-A-T, <b>không</b> phải tài khoản đăng nhập: một người có thể chưa có tài khoản
            mà vẫn đứng tên bài, nên <c>UserId</c> là tham chiếu mềm và có thể để trống.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentAuthorService.List(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAuthorListRequest)">
            <summary><c>list_people</c> — danh sách gọn cho trợ lý AI và ô chọn trên màn duyệt.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentAuthorService.Save(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentAuthorModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)">
            <summary>Tạo mới (Id = 0) hoặc sửa. Trùng họ tên với người còn hoạt động khác → cảnh báo, không chặn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentAuthorService.Delete(System.Int32,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)">
            <summary>Xoá mềm. Người còn bài đứng tên thì từ chối — bài mất tác giả là mất điều kiện đăng §3.3d(2).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentAuthorService.LaDuongDanRaMayChuKhac(System.String)">
            <summary>
            URL bắt đầu bằng <c>//</c> hoặc <c>/\</c> — trình duyệt đọc cả hai là "giao thức tương đối" và đi
            ra <b>máy chủ khác</b>, dù chuỗi trông như đường dẫn nội bộ. Dùng chung với
            <c>ContentArticleService.IsSafeAssetUrl</c>: hai hàm kiểm URL trong cùng một miền phải nói cùng một luật.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentAuthorService.FillArticleCounts(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentAuthorItem})">
            <summary>Đếm bài đứng tên trong một truy vấn gộp — để danh sách không sinh N+1.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentDeployCheckService">
            <summary>
            Ảnh chụp trạng thái triển khai của kho nội dung AI, đọc được <b>từ trình duyệt</b> — thay cho việc mở
            SQL client vào database production.
            </summary>
            <remarks>
            <para>
            <b>Vì sao có thứ này (quyết định Q7, chốt 2026-09-07 — plan §7.12).</b> Trình tự deploy §4.4 bước 1 đòi
            "xác nhận bằng query": đếm bảng <c>Content*</c>, đếm role, kiểm ba khoá công tắc. Nhưng ràng buộc
            2026-08-27 cấm chạy <c>SELECT</c>/<c>INSERT</c>/<c>UPDATE</c> tay vào <c>Ladaer2</c> production. Endpoint
            này là đường thay thế: <b>chỉ đọc</b>, không tham số, gác role, và trả đúng những con số bước 1 cần.
            </para>
            <para>
            <b>Nó còn kiểm được hai thứ mà SQL không kiểm được.</b> (1) <i>Khoá OpenIddict là khoá thật hay khoá
            tạm</i> — thứ này chỉ hiện trong nhật ký lúc dựng pipeline, mà khoá tạm nghĩa là mọi token OAuth chết
            sau mỗi lần khởi động lại. (2) <i>Reverse proxy có gửi đúng header không</i> — <c>Scheme</c> và
            <c>ClientIp</c> ở đây là <b>thứ API thật sự nhìn thấy</b>, nên đọc chúng là cách duy nhất kết luận đúng
            về bẫy Forwarded Headers thay vì suy luận (checklist §5).
            </para>
            <para>
            <b>Không được lộ gì nhạy cảm.</b> Chỉ số đếm, cờ boolean và URL công khai. Không trả nội dung
            <c>SigningKeyPem</c>/<c>EncryptionKey</c>, không trả <c>McpAllowedIps</c>, không trả danh sách người.
            Ca test <c>DeployCheck_KhongLoKhoaVaKhongLoDaiIp</c> canh đúng mệnh đề này.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentDeployCheckService.Kiem(Microsoft.AspNetCore.Http.HttpContext,System.Threading.CancellationToken)">
            <summary>Đọc trạng thái triển khai. Không ghi một dòng nào.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheckService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentDeployCheckService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheckService.RoleCanCo">
            <summary>
            Mười role của kho nội dung do migration <c>M202609041520</c> seed, cộng <c>Post.Publish</c> của CMS
            (đường "Đăng ngay" §7.11 đòi nó). Liệt kê tường minh để <b>role thiếu vẫn hiện ra</b> — hỏi database
            "có role nào tên ContentStore.*" thì một seed chạy nửa chừng trông y hệt một seed đủ.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheckService.CongTacCanXem">
            <summary>Ba công tắc quyết định hệ thống có đổi hành vi hay không. Cả ba phải <c>false</c> sau bước 2.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheckService.MoTaMcp(Ladaer.BackEnd.Infrastructures.AppSettings.ContentStoreMcpSettings,Ladaer.BackEnd.Infrastructures.Mcp.McpIpAllowlist)">
            <summary>
            Cấu hình MCP đang chạy, dạng an toàn để in ra: URL công khai và <b>cờ</b> về khoá, không phải khoá.
            </summary>
            <remarks>
            <c>PersistentSigningKey = false</c> nghĩa là API đang chạy bằng khoá tạm sinh lúc khởi động —
            mọi access token và refresh token chết sau mỗi lần khởi động lại, và Cowork sẽ đòi đăng nhập lại
            sau mỗi lần deploy. Đây là hỏng lặng lẽ nhất của cả đợt: không có lỗi nào, chỉ có người dùng
            "tự nhiên bị đăng xuất".
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheckService.MoTaRequest(Microsoft.AspNetCore.Http.HttpContext,Ladaer.BackEnd.Infrastructures.Mcp.McpIpAllowlist)">
            <summary>
            Thứ API <b>thật sự nhìn thấy</b> về request này — nửa còn lại của bẫy Forwarded Headers.
            </summary>
            <remarks>
            <para>
            <c>Scheme</c> phải là <c>https</c> khi gọi qua tên miền công khai. Thấy <c>http</c> nghĩa là proxy
            chưa gửi <c>X-Forwarded-Proto</c>, hoặc <c>ForwardedHeadersMiddleware</c> đã bỏ header vì proxy
            không nằm trong <c>KnownProxies</c> — và hệ quả là OpenIddict <b>từ chối mọi</b> <c>/connect/*</c>
            ngoài Development.
            </para>
            <para>
            <c>ClientIp</c> là kết quả của <see cref="T:Ladaer.BackEnd.Infrastructures.Networking.ClientIpResolver"/> — đúng thứ whitelist và rate limit dùng.
            So nó với IP thật của máy đang bấm là cách kiểm duy nhất đáng tin; suy luận từ cấu hình proxy đã sai
            một lần rồi. <c>ForwardedFor</c> là header do <b>chính người gọi</b> gửi lên nên in lại không lộ gì.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheckService.DocPhienBanSchema(System.Threading.CancellationToken)">
            <summary>
            Migration mới nhất đã áp dụng. Đọc thẳng <c>VersionInfo</c> — bảng do FluentMigrator sở hữu,
            ứng dụng không tham chiếu project migration nên không có đường EF nào tới nó.
            </summary>
            <remarks>
            Cùng câu lệnh mà <c>StartupHostedService.LogSchemaVersionAsync</c> in ra nhật ký lúc khởi động —
            đây là bản đọc được từ trình duyệt, cho người không có quyền đọc nhật ký máy chủ.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheckService.DemBang(System.Threading.CancellationToken)">
            <summary>
            Đếm dòng từng bảng của miền, cộng <c>OpenIddictApplications</c>.
            </summary>
            <remarks>
            <para>
            Đếm <b>tất cả</b> dòng, kể cả dòng đã xoá mềm: câu hỏi của bước 1 là "bảng có tồn tại và migration
            đã ăn chưa", không phải "còn bao nhiêu dòng đang dùng".
            </para>
            <para>
            <c>OpenIddictApplications</c> có mặt ở đây vì nợ <b>CS-16</b>: mỗi lần Claude/ChatGPT kết nối là một
            client DCR mới được tạo và chưa có job dọn. Con số này là cách theo dõi nó phình sau khi mở công khai.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheckService.Dem``1(System.Threading.CancellationToken)">
            <summary>Đếm một bảng; bảng chưa tồn tại (migration chưa chạy) trả <c>-1</c> thay vì làm hỏng cả lời gọi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheckService.DemRole(System.Threading.CancellationToken)">
            <summary>
            Với mỗi role: đã seed chưa, và bao nhiêu <b>người còn hiệu lực</b> đang có nó.
            </summary>
            <remarks>
            Quyền tới người theo <b>hai</b> đường và phải cộng cả hai rồi loại trùng: gán trực tiếp
            (<c>UserRole</c>) và gán qua nhóm quyền (<c>User.PermissionId</c> → <c>PermissionRole</c>) — đúng
            hai nguồn mà <c>UserRoleResolver</c> hợp nhất lúc chạy. Đếm mỗi <c>UserRole</c> là ra số nhỏ hơn
            thực tế, vì hầu hết nhân viên nhận quyền qua nhóm.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheck">
            <summary>Ảnh chụp trạng thái triển khai — xem <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentDeployCheckService"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheck.CheckedAt">
            <summary>Thời điểm đọc, theo múi giờ máy chủ — để không nhầm ảnh chụp cũ với ảnh mới.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheck.Environment">
            <summary>
            <c>ASPNETCORE_ENVIRONMENT</c> đang chạy. Phải là <c>Production</c> trên máy chủ thật: handler lỗi
            an toàn (CS-25) và việc tắt Swagger đều gắn vào điều kiện "không phải Development".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheck.SchemaVersion">
            <summary>Migration mới nhất đã áp dụng — thay cho <c>SELECT MAX(Version) FROM VersionInfo</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheck.Tables">
            <summary>Số dòng từng bảng; <c>-1</c> = không đọc được (bảng chưa có).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheck.Roles">
            <summary>Role của miền: đã seed chưa và bao nhiêu người đang có.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheck.Switches">
            <summary>Ba công tắc — sau bước 2 của §4.4 cả ba phải là <c>false</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheck.Mcp">
            <summary>Cấu hình MCP/OAuth đang chạy, dạng an toàn để in.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployCheck.Request">
            <summary>Thứ API nhìn thấy về chính request này — mật thử cho reverse proxy.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployTable">
            <param name="Name">Tên bảng.</param>
            <param name="Rows">Số dòng, hoặc <c>-1</c> khi không đọc được.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployTable.#ctor(System.String,System.Int32)">
            <param name="Name">Tên bảng.</param>
            <param name="Rows">Số dòng, hoặc <c>-1</c> khi không đọc được.</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployTable.Name">
            <summary>Tên bảng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployTable.Rows">
            <summary>Số dòng, hoặc <c>-1</c> khi không đọc được.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployRole">
            <param name="Role">Tên role.</param>
            <param name="Seeded">Role đã có trong bảng <c>Role</c> chưa.</param>
            <param name="Users">Số người còn hiệu lực đang có role (trực tiếp + qua nhóm quyền).</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployRole.#ctor(System.String,System.Boolean,System.Int32)">
            <param name="Role">Tên role.</param>
            <param name="Seeded">Role đã có trong bảng <c>Role</c> chưa.</param>
            <param name="Users">Số người còn hiệu lực đang có role (trực tiếp + qua nhóm quyền).</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployRole.Role">
            <summary>Tên role.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployRole.Seeded">
            <summary>Role đã có trong bảng <c>Role</c> chưa.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployRole.Users">
            <summary>Số người còn hiệu lực đang có role (trực tiếp + qua nhóm quyền).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeploySwitch">
            <param name="Key">Khoá <c>AppConfig</c>.</param>
            <param name="Value">Giá trị hiện tại — công tắc boolean, không phải bí mật.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeploySwitch.#ctor(System.String,System.String)">
            <param name="Key">Khoá <c>AppConfig</c>.</param>
            <param name="Value">Giá trị hiện tại — công tắc boolean, không phải bí mật.</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeploySwitch.Key">
            <summary>Khoá <c>AppConfig</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeploySwitch.Value">
            <summary>Giá trị hiện tại — công tắc boolean, không phải bí mật.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployMcp">
            <summary>Cấu hình MCP/OAuth dạng an toàn để in ra — cờ và URL, không có khoá.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployMcp.#ctor(System.String,System.String,System.String,System.String,System.String,System.Boolean,System.Boolean,System.Boolean,System.Int32,System.Int32,System.Int32,System.Int32,System.Collections.Generic.IReadOnlyList{System.String})">
            <summary>Cấu hình MCP/OAuth dạng an toàn để in ra — cờ và URL, không có khoá.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployRequest">
            <summary>Thứ API thật sự nhìn thấy về request đang gọi — dùng để kết luận về reverse proxy.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentDeployRequest.#ctor(System.String,System.String,System.String,System.String,System.String,System.String,System.Boolean)">
            <summary>Thứ API thật sự nhìn thấy về request đang gọi — dùng để kết luận về reverse proxy.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.GateRuleKind">
            <summary>Cách một luật gate quyết định có báo một match hay không.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.GateRuleKind.Plain">
            <summary>Báo mọi match.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.GateRuleKind.LadaSubjectSameSentence">
            <summary>
            Chỉ báo khi câu chứa match (đoạn giữa các dấu <c>.!?</c> hoặc xuống dòng) có chữ "LADA" đứng trước match
            và giữa LADA với match không có từ phủ định (không / chưa / chẳng). Không thoả → bỏ qua hẳn, vì bài
            được phép nói về đối thủ ("Viettel Post phủ 63 tỉnh").
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.GateRuleKind.NoDigitInSentence">
            <summary>Chỉ báo khi câu chứa match không có chữ số nào — có số cụ thể thì không còn là sáo ngữ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.GateRule">
            <summary>Một dòng trong bảng luật cổng chặn (đặc tả §7.1). Bất biến, dùng chung cho mọi request.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.GateRule.Code">
            <summary>Mã luật, ví dụ GATE_01_HOTLINE_CU — ghi vào ContentStoreIssue.Rule.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.GateRule.IsHard">
            <summary>true = lỗi cứng (chặn lưu); false = cảnh báo mềm (chỉ trả về).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.GateRule.Message">
            <summary>Thông điệp tiếng Việt cho người đọc.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateRules">
            <summary>
            Bảng luật cổng chặn nội dung — hằng trong code (không đọc từ DB) để mỗi dòng có test riêng
            và đổi luật là đổi code có review. Thứ tự trong <see cref="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateRules.All"/> là thứ tự báo lỗi trong một trường.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateRules.Options">
            <summary>Mọi regex của gate: không phân biệt hoa thường (Unicode, kể cả Đ/đ), bất biến văn hoá, biên dịch sẵn.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateRules.MetaDescriptionSoftMax">
            <summary>Meta description dài hơn ngưỡng này → cảnh báo mềm GATE_06_META_DAI (Google cắt khoảng 155–160 ký tự).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateInput">
            <summary>Văn bản đưa qua cổng chặn — mọi trường người đọc nhìn thấy được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateInput.BriefTexts">
            <summary>
            Chuỗi trong brief, dạng (đường dẫn, văn bản) từ ContentStoreJson.FlattenStrings — Field báo lỗi là
            "Brief.&lt;đường dẫn&gt;". Đây là <b>trường nội bộ</b>: vi phạm trong brief chỉ ra cảnh báo, không chặn lưu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateInput.MaskPlaceholders">
            <summary>
            true (mặc định, lúc tạo bài): che nội dung bên trong ô [[…]] bằng khoảng trắng cùng độ dài trước khi chạy luật,
            vì mô tả ô là chỉ dẫn cho người điền, không phải nội dung đăng. false khi kiểm bản đã thay ô (§3.3d bước 7).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentGateService">
            <summary>
            Cổng chặn nội dung (đặc tả §7.1, plan §3.3b). Luật là hằng trong ContentGateRules, mỗi dòng có test riêng.
            Lỗi cứng → Code = CONTENT_GATE_FAILED, Rule = mã luật, Field = trường, Position = "dòng n", Excerpt ≤ 80 ký tự.
            Cảnh báo mềm (tiền tệ / thời gian giao cụ thể, meta &gt; 155) → Warnings.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateService">
            <summary>
            Cài đặt cổng chặn: chạy bảng <see cref="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateRules.All"/> lên từng trường văn bản theo thứ tự
            Title → AltTitles → MetaDescription → Cta → BodyMarkdown → Faq → Brief. Thuần, không DB, không trạng thái.
            Văn bản được đưa về Unicode FormC trước khi so để chữ có dấu dạng tổ hợp (FormD) không lọt lưới regex.
            Phần áp luật lên một chuỗi nằm ở <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateText"/> (tách ở GĐ A2 bưu cục, hành vi giữ nguyên —
            test <c>ContentGateTextTests</c> so từng phát hiện với bản chụp trước khi tách).
            </summary>
            <remarks>
            <b>Trường lên website và trường nội bộ chịu mức phạt khác nhau</b> (phản hồi của trợ lý AI 2026-09-13).
            Sáu trường đầu là thứ độc giả đọc — vi phạm cứng ở đó chặn lưu. <c>Brief</c> thì không có trường nào lên
            trang: <c>audience</c>, <c>data_needed</c>, <c>editorial_notes</c> là ghi chú cho người duyệt. Trước đây
            chúng chạy cùng một mức phạt, nên một dòng ghi chú hoàn toàn vô hại — "hồ sơ tác giả duy nhất trong kho" —
            dính GATE_03C và làm hỏng cả lời gọi <c>create_article_draft</c>; trợ lý phải né chữ trong ghi chú của
            chính mình, tức là luật chống hứa hẹn quảng cáo lại đi cấm một câu chẳng ai đọc.
            <para>
            Vẫn <b>chạy</b> luật trên brief chứ không bỏ qua: brief ghi "hotline 1900 4509" hay "LADA là chuyển phát
            nhanh" là chỉ dẫn sai cho chính người viết bài sau đó — người duyệt cần thấy, chỉ là không đáng chặn lưu.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateService.MaxIssuesPerRuleAndField">
            <summary>Số phát hiện tối đa cho một cặp luật × trường — đủ để sửa, không làm phình kết quả trả về.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateService.InternalFieldNote">
            <summary>
            Đuôi câu gắn vào cảnh báo của trường nội bộ — nói rõ vì sao lần này không chặn, để người đọc không
            tưởng cổng chặn đang hỏng.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateService.MetaTooLongRule">
            <summary>Mã cảnh báo mềm khi meta description dài hơn <see cref="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateRules.MetaDescriptionSoftMax"/>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateService.GateText">
            <summary>Một đoạn văn bản đưa qua bảng luật, kèm việc nó có lên website hay không.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateService.GateText.#ctor(System.String,System.String,System.Boolean)">
            <summary>Một đoạn văn bản đưa qua bảng luật, kèm việc nó có lên website hay không.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateService.CollectTexts(Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateInput)">
            <summary>Gom (Field, văn bản đã FormC) theo thứ tự người đọc gặp; bỏ qua trường rỗng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateService.MaskPlaceholders(System.String)">
            <summary>Thay mỗi ô [[…]] bằng khoảng trắng cùng độ dài, giữ nguyên ký tự xuống dòng để số dòng báo lỗi không lệch.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateText">
            <summary>
            Chạy bảng luật cổng chặn <see cref="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateRules.All"/> lên MỘT chuỗi văn bản — phần lõi tách ra khỏi
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateService"/> (neo vào <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateInput"/> hình bài viết) để miền khác dùng được:
            hồ sơ bưu cục kiểm <c>Intro</c>, chú thích ảnh, hỏi đáp, thông báo tạm ngưng (docs/plan-buu-cuc.md §3.3 #10).
            </summary>
            <remarks>
            Thuần, không DB, không trạng thái. Văn bản được đưa về Unicode FormC trước khi so để chữ có dấu dạng tổ hợp
            (FormD) không lọt lưới regex. Không che ô <c>[[…]]</c> — đó là quy ước riêng của kho nội dung, việc của
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateService"/>. Lỗi cứng: Code = <c>CONTENT_GATE_FAILED</c>, Rule = mã luật,
            Position = "dòng n", Excerpt ≤ 80 ký tự; luật mềm và mọi vi phạm ở trường nội bộ → Warnings.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateText.NegationWord">
            <summary>Từ phủ định đứng giữa "LADA" và match làm câu thành phủ định ("LADA không phủ 63 tỉnh") — "không phải" đã nằm trong "không".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateText.Check(System.String,System.String,System.Boolean)">
            <summary>
            Áp đủ bảng luật lên <paramref name="text"/>, báo phát hiện dưới tên trường <paramref name="field"/>.
            <paramref name="isInternal"/> = true: trường không lên website — vi phạm cứng chỉ thành cảnh báo
            (xem <see cref="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateService.InternalFieldNote"/>).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateText.Check(System.String,System.String,System.Boolean,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreValidationResult)">
            <summary>Như <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateText.Check(System.String,System.String,System.Boolean)"/> nhưng ghi thêm vào một kết quả có sẵn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateText.ApplyRule(Ladaer.BackEnd.Infrastructures.Services.ContentStore.GateRule,System.String,System.String,System.Boolean,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreValidationResult)">
            <summary>
            Chạy một luật lên một trường. Vi phạm cứng ở trường lên website là <b>lỗi</b>; cùng vi phạm đó ở
            trường nội bộ chỉ là <b>cảnh báo</b> — xem <see cref="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateService.InternalFieldNote"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateText.SentenceBounds(System.String,System.Text.RegularExpressions.Match,System.Int32@,System.Int32@)">
            <summary>Câu chứa match: [start, end) là đoạn không chứa dấu .!? hay xuống dòng bao quanh match.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateText.HasLadaSubjectBefore(System.String,System.Text.RegularExpressions.Match)">
            <summary>Trong câu có "LADA" đứng trước match, và từ LADA gần nhất tới match không có từ phủ định.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateText.NormalizeUnicode(System.String)">
            <summary>FormC; chuỗi có surrogate hỏng thì giữ nguyên — vẫn chạy luật được.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentHtmlSanitizeResult">
            <summary>Kết quả một lượt lọc HTML — kèm danh sách thứ bị cắt để đường xem trước nói được cho người bấm.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentHtmlSanitizeResult.Html">
            <summary>HTML sau khi lọc. Đây là chuỗi duy nhất được phép ghi vào <c>Post.Description</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentHtmlSanitizeResult.Removed">
            <summary>Mô tả từng thứ bị cắt ("thẻ &lt;iframe&gt;", "thuộc tính onerror trên &lt;img&gt;"…), đã gộp trùng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentHtmlSanitizeResult.RemovedCount">
            <summary>Số lần cắt (đếm cả lần lặp lại), khác với số dòng trong <see cref="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentHtmlSanitizeResult.Removed"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentHtmlSanitizeResult.Clean">
            <summary>Không cắt gì — nghĩa là HTML vào và ra giống nhau về cấu trúc.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentHtmlSanitizer">
            <summary>
            Lọc HTML theo allowlist trước khi nó ra trang công khai (CS-9).
            <para>
            Vì sao cần dù đã có <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer"/>: <c>DisableHtml()</c> chặn HTML <b>thô trong nguồn
            Markdown</b>, nó không lọc được thứ do chính extension của Markdig sinh ra, và cũng không bảo vệ được
            đoạn HTML mà GĐ F tự ghép thêm (khối <c>&lt;figure&gt;&lt;img&gt;</c> chèn sau H2). Đây là lớp cuối cùng
            đứng giữa kho nội dung và <c>Post.Description</c> — chỗ website đọc ra bằng <c>Html.Raw</c>.
            </para>
            <para>
            Allowlist dựng từ số đo thật, không phải từ trí nhớ: 23 bài trong kho render ra đúng 20 thẻ
            (<c>td p strong li tr h2 th h3 ul hr table thead tbody ol a em h1 code h4 blockquote</c>) và 5 loại
            thuộc tính (<c>h1–h4@id</c>, <c>a@href</c>) — plan §4.7 câu 5. Phần còn lại của danh sách là những thẻ
            mà các extension <b>đang bật</b> có thể sinh ra dù nội dung hôm nay chưa dùng tới; thiếu chúng thì một
            bài dùng danh sách định nghĩa hay chú thích chân trang sẽ bị cắt mất chữ.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentHtmlSanitizer.Sanitize(System.String)">
            <summary>Lọc và cho biết đã cắt những gì. Trả chuỗi rỗng khi đầu vào rỗng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentHtmlSanitizer.SanitizeRichText(System.String)">
            <summary>
            Chính sách thứ hai, cho ô chữ định dạng người dùng gõ trong TinyMCE (Intro hồ sơ bưu cục — plan bưu cục §3.3):
            chỉ đoạn văn, xuống dòng, đậm/nghiêng/gạch chân, danh sách, tiêu đề phụ, trích dẫn; KHÔNG thuộc tính nào,
            KHÔNG link, KHÔNG ảnh. Thẻ ngoài danh sách bị gỡ nhưng GIỮ chữ bên trong (dán từ Word ra &lt;span style&gt;,
            &lt;font&gt;, &lt;o:p&gt; không làm mất câu); thẻ chạy mã / nhúng (script, style, iframe, object…) bỏ cả nội dung.
            </summary>
            <remarks>
            Không cho thuộc tính vì luật "không số điện thoại trong nội dung" chạy trên chữ thuần — số giấu trong
            <c>href="tel:…"</c>, <c>title</c>, <c>alt</c> sẽ lọt. Không cho ảnh vì ảnh lên trang phải qua bước duyệt ảnh riêng.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentHtmlSanitizer">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentHtmlSanitizer"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentHtmlSanitizer.TheChoPhep">
            <summary>
            Thẻ được giữ. Ba nhóm: (1) 20 thẻ đo được trên 23 bài thật; (2) thẻ các extension đang bật có thể
            sinh — <c>pre</c> (khối code rào), <c>dl/dt/dd</c> (DefinitionLists), <c>abbr</c> (Abbreviations),
            <c>del/ins/sub/sup/mark</c> (EmphasisExtras), <c>col/colgroup/caption/tfoot</c> (Pipe/GridTables),
            <c>div/section</c> + <c>input</c> (Footnotes, TaskLists), <c>h5/h6</c>, <c>br</c>;
            (3) thẻ do chính GĐ F ghép thêm: <c>figure/figcaption/img</c> cho ảnh chèn sau H2.
            <para><b>Cố ý KHÔNG có <c>span</c>.</b> HTML đăng lên website không được còn ô
            <c>&lt;span class="ld-placeholder"&gt;</c> nào — đó là thứ chỉ dùng cho màn duyệt. Không cho
            <c>span</c> nghĩa là nếu một ô lọt được tới đây thì nó lộ ra ngay ở lượt xem trước.</para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentHtmlSanitizer.ThuocTinhChoPhep">
            <summary>
            Thuộc tính được giữ, áp cho mọi thẻ. Không có <c>on*</c>, không có <c>srcset</c>, không có
            <c>formaction</c>, không có <c>data-*</c>.
            <para><c>style</c> có mặt vì PipeTables sinh <c>style="text-align: right;"</c> cho cột căn lề —
            cắt nó là bảng số trong bài mất căn lề. Nhưng nó chỉ là <b>cửa</b>: nội dung bên trong bị
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentHtmlSanitizer.ThuocTinhCss"/> siết xuống đúng một thuộc tính, nên <c>style="position:fixed"</c>
            (lớp phủ toàn màn hình) vẫn bị cắt sạch.</para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentHtmlSanitizer.ThuocTinhCss">
            <summary>Thuộc tính CSS duy nhất được giữ trong <c>style</c> — căn lề cột bảng của PipeTables.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentHtmlSanitizer.SchemeChoPhep">
            <summary>
            Scheme URL được phép trong <c>href</c>/<c>src</c>. <c>data:</c> vắng mặt là có chủ đích:
            <c>data:text/html;base64,…</c> trong một thẻ <c>a</c> là XSS ở mọi trình duyệt còn chạy điều hướng.
            URL tương đối vẫn qua được vì <c>BaseUrl</c> để trống.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentHtmlSanitizer.TextFormattingTags">
            <summary>Thẻ của chính sách chữ định dạng (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentHtmlSanitizer.SanitizeRichText(System.String)"/>).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentHtmlSanitizer.TagsDroppedWithContent">
            <summary>
            Thẻ bị gỡ CÙNG nội dung ở chính sách chữ định dạng — chữ bên trong là mã hoặc nội dung nhúng, giữ lại thành
            chữ thường chỉ là rác ("alert(1)" giữa đoạn giới thiệu).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentImageKitService">
            <summary>
            Bộ công cụ ảnh: khối STYLE BASE/DO NOT dùng chung, từ điển khuôn ảnh, ảnh tham chiếu thương hiệu.
            </summary>
            <remarks>
            Ba danh mục nhỏ phục vụ đúng một việc: biến đặc tả ảnh trong kho nội dung thành thứ người tạo
            ảnh dùng được ngay — prompt ghép sẵn thay vì hai dòng "[… dán nguyên khối]", tên khuôn tiếng
            Việt thay vì mã "E2b", và ảnh tham chiếu tải về được thay vì phải đi tìm.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentImageKitService.GetSnapshot">
            <summary>Ảnh chụp dùng để ghép prompt và hiện hướng dẫn ở màn chi tiết bài (chỉ đọc).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentImageKitService.GetKit">
            <summary>Toàn bộ bộ công cụ cho màn cấu hình, kể cả bản đã tắt, kèm số ảnh đang dùng từng khối.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentImageKitService.GetSnapshot">
            <summary>
            Style base lấy CẢ bản đã tắt: ảnh cũ trỏ tới một phiên bản cụ thể phải ghép được bằng đúng
            bản đó, kể cả khi bản ấy đã nghỉ hưu. Ảnh tham chiếu thì chỉ lấy bản đang bật — đó là thứ
            người dùng sắp tải về.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentImageKitService.LaDuongDanAnhHopLe(System.String)">
            <summary>
            Đường dẫn ảnh chỉ được là đường dẫn tương đối hoặc http/https.
            </summary>
            <remarks>
            Giá trị này đi thẳng vào <c>&lt;img :src&gt;</c> và <c>&lt;a :href&gt;</c> của tab Bộ ảnh, hiện cho
            <b>mọi</b> người có <c>ContentStore.GetById</c> — rộng hơn hẳn nhóm sửa được nó. Không chặn
            scheme thì một người có <c>ManageAssets</c> gài được <c>javascript:</c> vào liên kết mà người
            khác bấm. Bình thường trường này do <c>PictureController</c> điền nên luôn là đường dẫn tương đối.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentImportFile">
            <summary>Một file nháp đã đọc vào bộ nhớ — service không biết gì về HTTP hay đĩa.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentImportService">
            <summary>
            Nhập bài từ file Markdown 4 phần: đọc file → tạo đề bài nếu hàng đợi chưa có → tạo bản nháp
            bằng đúng <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentArticleService.CreateDraft(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)"/> mà MCP và REST dùng.
            <para>
            Đây là đường vào cho trợ lý <b>không</b> có MCP (ChatGPT, Gemini) và cho 30 file nháp đã viết trước
            khi kho nội dung tồn tại. Không có luật nghiệp vụ riêng ở đây: mọi cổng chặn, phiếu chấm, luật ảnh
            đều là của <c>CreateDraft</c>, nếu không sẽ có hai bộ luật lệch nhau.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentImportService.Import(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentImportFile},Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor,System.Boolean)">
            <param name="dryRun">Chỉ đọc và soát, không ghi gì — để xem trước 30 file trước khi nhập thật.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentImportService.ImportFolder(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImportFolderModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)">
            <summary>Nhập cả thư mục trên máy chạy API; đường dẫn do người gọi đưa, không hard-code.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentImportService.MarkdownExtension">
            <summary>Đuôi file duy nhất nhận vào.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentImportService.MaxFilesPerRun">
            <summary>Số file tối đa một lượt — 30 file là cỡ thật, để rộng gấp đôi cho chắc.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentImportService.FindMissingTopics(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParseResult})">
            <summary>Đề bài chưa có trong hàng đợi — dựng từ dòng 1 của file (mã, nhánh L2, loại trang) + tiêu đề bài.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentImportService.FillDryRun(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImportFileResultModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParseResult,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicModel})">
            <summary>Soát trước: nói rõ đề đã có chưa, slug còn trống không — không ghi gì.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentLegacyPlaceholder">
            <summary>
            Dọn chuỗi <c>[[CẦN …]]</c> còn sót trong nội dung cũ.
            </summary>
            <remarks>
            <para>
            Kho nội dung từng có cơ chế "ô chờ": trợ lý AI để trống mọi số liệu chưa kiểm chứng bằng
            <c>[[CẦN SỐ THẬT: …]]</c> / <c>[[CẦN NGUỒN: …]]</c>, người duyệt điền từng ô, và bài không đăng
            được khi còn ô mở. Cơ chế đó bị <b>bỏ hẳn 2026-09-12</b> (plan §6.8): quá nhiều ô, điền tay còn
            lâu hơn tự viết. Nay trợ lý AI tra cứu và viết thẳng số vào bài.
            </para>
            <para>
            Lớp này là thứ duy nhất còn lại của cơ chế cũ, và nó không còn là "ô" nữa mà là <b>bộ lọc rác</b>:
            bài nháp cũ (và bài do prompt chưa cập nhật sinh ra) vẫn có thể mang chuỗi ấy, mà chuỗi ấy lọt
            ra trang công khai thì rất khó coi. Dùng ở ba chỗ: làm sạch nội dung lúc đăng, lọc heading khi
            sinh slug và mục lục, và che khỏi cổng chấm nội dung để luật gate không chấm nhầm phần chỉ dẫn.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentLegacyPlaceholder.Pattern">
            <summary>
            Nhóm 1 = nhãn ("CẦN SỐ THẬT"), nhóm 2 = mô tả sau dấu hai chấm (có thể vắng).
            Nhãn không chứa ']' hay ':'; mô tả non-greedy tới ']]' đầu tiên.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentLegacyPlaceholder.DoRong">
            <summary>
            Bản dò RỘNG: chỉ cần <c>[[</c> + khoảng trắng tuỳ ý + <c>CẦN</c> là tính, không đòi đóng <c>]]</c>.
            </summary>
            <remarks>
            <para>
            Hàng rào cũ (<c>ContentPublishHtmlBuilder.ODuLieuConSot</c>) chặn đăng bằng đúng phép dò tiền tố này,
            nên nó phủ cả những chuỗi <b>dị dạng</b> mà <see cref="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentLegacyPlaceholder.Pattern"/> không khớp: <c>[[ CẦN NGUỒN: …]]</c>
            (thừa dấu cách), <c>[[CẦN NGUỒN [1]: …]]</c> (nhãn có <c>]</c>), <c>[[CẦN: …]]</c> (thiếu dấu cách),
            <c>[[CẦN SỐ THẬT: 2024</c> (file nhập bị cắt, không đóng ngoặc).
            </para>
            <para>
            Dùng bản chặt cho việc <b>bóc tách</b> (parser cần hai nhóm nhãn/mô tả), dùng bản rộng cho việc
            <b>dọn và đếm</b> — thu hẹp phép dò lúc dọn là để chỉ dẫn biên tập nội bộ lọt ra trang công khai
            mà không ai được cảnh báo.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentLegacyPlaceholder.Dem(System.String)">
            <summary>Đếm số chuỗi còn sót — để cảnh báo trước khi đăng (không chặn đăng). Đếm theo bản RỘNG.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentLegacyPlaceholder.ConSot(System.String)">
            <summary>Còn chuỗi nào không — dùng để canh bất biến "không chuỗi ô chờ nào ra trang công khai".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentLegacyPlaceholder.XoaHet(System.String)">
            <summary>
            Xoá sạch chuỗi <c>[[CẦN …]]</c>, gộp khoảng trắng thừa và dọn dấu câu bị bỏ rơi.
            </summary>
            <remarks>
            Xoá trơ để lại những câu kiểu "Phạt tiền  ." hoặc "mức phạt là ,". Không cứu được nghĩa
            câu — người viết mới cứu được — nhưng ít nhất không để lại khoảng trắng đôi và dấu câu lơ lửng.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentLegacyPlaceholder.ThayBangKhoangTrang(System.String)">
            <summary>Thay bằng một khoảng trắng — dùng khi cần giữ ranh giới từ (sinh slug, mục lục).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPromptComposer">
            <summary>
            Ghép prompt đầy đủ cho một ảnh: khối STYLE BASE dùng chung + phần riêng của ảnh + khối DO NOT.
            </summary>
            <remarks>
            <para>
            Đặc tả §4.6 cố ý chỉ lưu phần riêng trong <c>ContentImage.PromptEn</c>. Người viết bài viết
            phần riêng theo <b>hai kiểu</b>, cả hai đều gặp trong dữ liệu thật:
            </para>
            <list type="number">
            <item>Có chỗ trống — một dòng "[STYLE BASE … dán nguyên khối]" ở đầu và "[DO NOT … ]" ở cuối;
            khi đó phải <b>thay đúng dòng đó</b> để giữ nguyên phần giữa.</item>
            <item>Không có chỗ trống (như fixture <c>w2-01.md</c>) — prompt tự chứa; khi đó nối khối chung
            vào trước và sau.</item>
            </list>
            <para>
            Lớp này thuần hàm, không chạm DB, để test được không cần fixture: mọi dữ liệu tra cứu truyền
            vào qua <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentImageKitSnapshot"/>.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPromptComposer.DefaultLane">
            <summary>Làn mặc định khi ảnh không ghi làn nào — làn A là brand kit ON, đúng mặc định của đặc tả §4.6.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPromptComposer.StyleBaseLine">
            <summary>
            Dòng chỗ trống: mở đầu bằng "[", có chữ khoá, kết thúc bằng "]" trên cùng một dòng.
            Bắt cả "[STYLE BASE — LADA EXPRESS (brand kit ON) — dán nguyên khối]" lẫn "[STYLE BASE làn A …]".
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPromptComposer.ComposeResult">
            <summary>Kết quả ghép — tách riêng lý do thiếu để giao diện nói được cụ thể thay vì im lặng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPromptComposer.ComposeResult.FullPrompt">
            <summary>Prompt đã ghép; null khi không ghép được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPromptComposer.ComposeResult.StyleBaseMissing">
            <summary>Không tìm được khối STYLE BASE nào áp dụng cho ảnh này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPromptComposer.ComposeResult.StyleBaseCode">
            <summary>Mã phiên bản đã dùng (để giao diện chỉ đúng bản ghi khi cần sửa).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPromptComposer.Compose(System.String,System.String,System.String,System.String,System.Collections.Generic.IReadOnlyCollection{Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentStyleBaseItem})">
            <summary>
            Ghép prompt cho một ảnh. <paramref name="promptEn"/> rỗng (ảnh dựng tay, chụp thật, không ảnh)
            thì trả <c>FullPrompt = null</c> và <b>không</b> coi là thiếu khối chung — những ảnh đó vốn không có prompt.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPromptComposer.Resolve(System.String,System.String,System.Collections.Generic.IReadOnlyCollection{Ladaer.BackEnd.Infrastructures.DTO.Items.ContentStore.ContentStyleBaseItem})">
            <summary>
            Tìm khối chung áp dụng cho ảnh.
            </summary>
            <remarks>
            <para>
            Ảnh <b>có ghi</b> mã phiên bản: tra đúng mã đó, kể cả bản đã tắt — ảnh cũ phải ghép được bằng
            đúng bản nó tham chiếu. Không thấy mã đó thì trả <c>null</c> (→ <c>StyleBaseMissing</c>):
            lặng lẽ thay bằng bản mặc định là đưa cho người tạo ảnh một câu lệnh trông như đã ghép đúng,
            trong khi nó tả một bộ nhận diện khác với bộ mà bài này được viết cho.
            </para>
            <para>
            Ảnh <b>không ghi</b> mã: lấy bản mặc định của làn, rồi tới bản đang bật đầu tiên của làn.
            Bản đã tắt không bao giờ được chọn ở nhánh này — tắt nghĩa là "đừng dùng cho ảnh mới".
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishImage">
            <summary>Một ảnh sẵn sàng chèn vào thân bài.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishImage.H2Key">
            <summary>Slug của H2 mà ảnh thuộc về — khớp <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.Slugify(System.String)"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishImage.CaptionAlt">
            <summary>Chú thích, đồng thời là <c>alt</c>. Rỗng thì không in <c>figcaption</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishHtmlResult">
            <summary>Kết quả dựng thân bài — HTML, mục lục và các con số để đối chiếu ở lượt soát thử.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishHtmlResult.ImageCount">
            <summary>Số ảnh thật sự chèn được — ảnh có <c>H2Key</c> không khớp H2 nào thì không chèn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishHtmlResult.AnhKhongKhopH2">
            <summary>Ảnh bị bỏ vì không tìm được H2 tương ứng; hiện ra ở lượt soát thử chứ không im lặng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishHtmlResult.H1DaXuLy">
            <summary>Số H1 gặp trong thân bài. Bằng <see cref="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishHtmlResult.H1DaGo"/> + <see cref="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishHtmlResult.H1DaHa"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishHtmlResult.H1DaGo">
            <summary>H1 MỞ ĐẦU bị gỡ hẳn vì trang đã có H1 tiêu đề — nhiều nhất một cái.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishHtmlResult.H1DaHa">
            <summary>H1 được hạ xuống H2 vì nó là một mục nội dung thật, không phải bản sao tiêu đề.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishHtmlResult.H2TrungTen">
            <summary>
            H2 trùng tên nhau — ảnh khai <c>H2Key</c> theo slug sẽ dồn hết vào cái ĐẦU, vì slug thứ hai đã
            bị đổi thành <c>-2</c>. Hiện ra ở lượt soát thử chứ không im lặng.
            </summary>
        </member>
        <!-- Badly formed XML comment ignored for member "T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishHtmlBuilder" -->
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishHtmlBuilder.HeadingBlock">
            <summary>Một khối heading trọn vẹn — thẻ mở, thuộc tính, phần trong, thẻ đóng.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishHtmlBuilder.ODuLieuConSot">
            <summary>Ô dữ liệu chưa điền còn sót lại — không được phép ra trang công khai.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishHtmlBuilder.DungMucLuc(System.Collections.Generic.List{System.ValueTuple{System.Int32,System.String,System.String}})">
            <summary>
            Mục lục đúng hình dạng CMS đang dùng — <c>&lt;ul&gt;&lt;li&gt;&lt;a href="#slug"&gt;</c>, khớp
            <c>Views/Post/Detail.cshtml</c> vốn <c>Html.Raw</c> thẳng khối này vào <c>div.ld-toc</c>.
            H3 nằm trong một <c>&lt;ul&gt;</c> lồng bên trong mục H2 chứa nó — <c>.ld-toc ul ul</c> của
            <c>site.css</c> đã có sẵn thụt lề và đánh số "1.1." cho đúng hình dạng này.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishHtmlBuilder.Figure(Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishImage)">
            <summary>
            Khối ảnh chèn sau H2. <c>CaptionAlt</c> đóng cả hai vai — <c>alt</c> và chú thích nhìn thấy được —
            nên <c>alt</c> để RỖNG khi đã in <c>figcaption</c>: trình đọc màn hình đọc <c>figcaption</c> như
            phần của <c>figure</c>, để cả hai là nó đọc đúng câu đó hai lần. Ảnh không có chú thích thì
            ngược lại — <c>alt</c> là thứ duy nhất mô tả ảnh, phải giữ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishHtmlBuilder.DuyNhat(System.String,System.Collections.Generic.HashSet{System.String})">
            <summary>Hai H2 trùng tên thì neo thứ hai thành <c>-2</c> — trùng id là mục lục nhảy sai chỗ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentPublishService">
            <summary>
            Xuất bản một bài từ kho nội dung sang CMS <c>Post</c> — bước cuối của cả đợt, và là <b>lần đầu tiên
            dữ liệu kho nội dung chạm tới website đang phục vụ khách</b> (nguyên tắc §1 của plan).
            </summary>
            <remarks>
            <para>
            <b>Ba lớp chặn, xếp theo thứ tự cố ý.</b> (1) Công tắc <c>AppConfig ContentStore.PublishEnabled</c> —
            mặc định TẮT, và <b>chỉ chặn đường ghi</b>: soát thử vẫn chạy được khi công tắc tắt, vì soát thử là
            cách người vận hành kiểm bài trước khi xin bật công tắc. (2) Bài phải đang ở <c>Approved</c>.
            (3) <b>Chạy lại đủ 8 điều kiện §3.3d ngay trước khi ghi</b> — CS-34.
            </para>
            <para>
            <b>Vì sao (3) không thừa dù bài đã <c>Approved</c>.</b> <c>Approved</c> nghĩa là "đủ điều kiện <i>tại
            thời điểm duyệt</i>", không phải "đủ điều kiện mãi mãi". GĐ E đã bịt hai cửa làm hỏng điều kiện sau khi
            duyệt (<c>SetStatus</c>, <c>SetPeople</c>) nhưng vẫn còn đường vòng thật: <c>ContentAuthor/CreateOrUpdate</c>
            xoá <c>ProfileUrl</c> của một tác giả là phá điều kiện (2) của <b>mọi</b> bài đã duyệt của người đó cùng
            lúc. Bịt cửa không thay được việc kiểm lại.
            </para>
            <para>
            <b>Soát thử không ghi một dòng nào.</b> Nhánh <c>DryRun</c> rẽ <b>trước mọi lệnh ghi</b>, không phải sau —
            đúng khuôn rút ra từ lỗi GĐ E (tool chốt cụm dữ liệu — nay đã gỡ cùng cơ chế ô chờ — gọi
            <c>Save(Confirm=true)</c> rồi mới rẽ nhánh <c>dry_run</c>, spec §13.8). Ở đây hậu quả nặng hơn hẳn một bậc: một bài rác trên website thật.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentPublishService.Publish(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)">
            <summary>
            Soát thử hoặc xuất bản. Trả cùng một hình dạng kết quả cho cả hai chế độ để người bấm so được
            "sẽ ra cái gì" với "đã ra cái gì".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentPublishService.ResyncImages(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishResyncModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)">
            <summary>
            Đồng bộ lại <b>ảnh</b> của một bài đã xuất bản sang đúng <c>Post</c> của nó — ảnh đại diện / OG và
            ảnh chèn trong thân bài. Đường sửa sau cho trường hợp ảnh không sang cùng lúc đăng.
            </summary>
            <remarks>
            <para>
            <b>Chỉ đụng ba cột của <c>Post</c>:</b> <c>Thumbnail</c>, <c>OgImage</c>, và <c>Description</c>/<c>TOC</c>.
            Không tạo <c>Post</c>, không đổi slug, danh mục, FAQ, trạng thái đăng hay trạng thái bài — đó là việc
            của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentPublishService.Publish(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)"/>, và gộp hai việc vào một hàm là cách chắc chắn để một ngày nào đó lượt
            "sửa ảnh" ghi đè cả bài.
            </para>
            <para>
            <b>Không ghi đè thân bài người ta đã sửa tay.</b> Thân bài chỉ được ghi lại khi
            <c>Post.Description</c> hiện tại còn đúng bằng bản kho dựng ra (có ảnh hoặc chưa có ảnh). Khác đi
            nghĩa là ai đó đã sửa trong CMS — lượt này chỉ cập nhật ảnh đại diện và nói rõ phần thân bài phải
            tự chèn.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentPublishService.SyncPublishedStatus">
            <summary>
            Job đồng bộ: bài có <c>PostId</c> mà <c>Post</c> đã <c>Published</c> ⇒ bài sang <c>Published</c>.
            Ghi audit từng bài — job không được là nơi duy nhất biết chuyện đó.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentPublishService.Categories">
            <summary>
            Danh mục CMS cho bài viết (<c>ContentType = Post</c>), đánh dấu cái đang là mặc định.
            <para>
            <b>Vì sao miền này tự phục vụ danh sách thay vì để giao diện gọi <c>Category/GetTree</c>.</b>
            Đường kia gác role <c>Category.GetTree</c> — một role của miền CMS. Người chỉ có
            <c>ContentStore.Publish</c> sẽ thấy màn đăng với ô chọn danh mục trống rỗng và không hiểu vì sao.
            Đây đúng là hình dạng của CS-28 (màn token chết vì thiếu <c>User.SugStaff</c>); không lặp lại.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentPublishService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService.PublishEnabledKey">
            <summary>Khoá công tắc — mặc định "false", và khoá thiếu cũng là "false" (không cache khoá thiếu).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService.DefaultCategoryKey">
            <summary>Danh mục CMS mặc định khi bài không chọn (§7.10).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService.RolePostPublish">
            <summary>Role của CMS cho phép đăng thẳng — đường "Đăng ngay" của §7.11 đòi đúng role này.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService.RoleFounder">
            <summary>Founder đi qua bypass của <c>ServerRoleAuthorizationHandler</c> nên có mọi quyền (§7.4b).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService.MuiGioVn">
            <summary>Múi giờ ghi mốc đăng — tường minh, không lấy múi giờ của máy chạy job (§4.7 câu 3).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService.DungDuocKhiDang(Lada.Framework.Data.Domains.ContentStore.ContentImage)">
            <summary>
            Ảnh đưa được sang CMS: <b>đã có file</b> và không bị từ chối.
            <para>
            <b>Vì sao không đòi <c>Approved</c> (sửa 2026-09-12).</b> Luật cũ "chỉ ảnh đã duyệt mới lên CMS"
            đúng khi đứng một mình, nhưng ghép với hai luật khác thì thành bẫy: cổng đăng (5) cho bỏ qua
            "ảnh chưa duyệt" bằng cờ <c>PublishWithoutImages</c>, còn <c>SetImageStatus</c> khoá cả bộ ảnh
            ngay khi bài sang <c>Approved</c>. Quên bấm duyệt ảnh <b>trước</b> khi duyệt bài là hết đường sửa;
            người duyệt bật cờ để đi tiếp và ảnh đã nộp file <b>bị vứt im lặng</b> — đúng việc đã xảy ra với
            bài W2-25 (Post #64) ngày 12/09/2026: hai ảnh có file trên media.ladaexpress.vn, Post ra đời
            không ảnh đại diện, thân bài không ảnh nào.
            </para>
            <para>
            Ảnh <c>Rejected</c> vẫn bị loại — đó mới là câu "không dùng ảnh này". <c>Spec</c>/<c>Generating</c>
            rụng theo điều kiện có file, nên không cần kể tên.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService.HtmlGiongNhau(System.String,System.String)">
            <summary>
            Hai chuỗi HTML có phải cùng một bản không. Chuẩn hoá xuống dòng và cắt khoảng trắng hai đầu — hai
            thứ duy nhất đổi được trên đường đi qua EF/SQL mà không đổi nghĩa. <b>Cố ý không</b> chuẩn hoá sâu
            hơn: bài bị sửa tay trong CMS phải bị nhận ra là đã sửa, kể cả khi chỉ khác vài khoảng trắng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService.ChonAnhDaiDien(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.ContentStore.ContentImage})">
            <summary>Ảnh đại diện / OG dùng được, hoặc null khi bài không có.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService.ChonAnhTrongBai(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.ContentStore.ContentImage})">
            <summary>Ảnh chèn vào thân bài, đã dọn ô chờ khỏi chú thích.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService.ResolveCategory(System.Nullable{System.Int32},System.String)">
            <summary>
            Tìm danh mục CMS đích theo ba bậc, dừng ở bậc đầu tiên cho kết quả:
            <list type="number">
            <item>Id chọn tường minh (tham số lượt đăng, hoặc <c>ContentArticle.CmsCategoryId</c>) — người bấm
            nói rõ thì nghe người bấm.</item>
            <item><b>Mã nhánh nội dung</b> của bài (<c>CategoryL2</c>) khớp <c>Category.ContentCategoryCode</c>.</item>
            <item><c>AppConfig ContentStore.DefaultCategoryId</c>.</item>
            </list>
            <para>
            <b>Vì sao bậc 2 phải có.</b> Trước khi có nó, không đường nào điền <c>CmsCategoryId</c> trước lúc
            đăng — cột ấy chỉ được GHI ở cuối hàm <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService.Publish(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentPublishModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)"/>, tức là ghi lại kết quả chứ không phải
            đầu vào. Nên bậc 1 luôn trống và mọi bài rơi thẳng xuống bậc 3: đo trên production 2026-09-14,
            10/10 bài đã đăng nằm sai danh mục, 8 trong số đó dồn vào đúng một danh mục mặc định. Kế hoạch
            nội dung vốn đã xếp từng bài vào một nhánh (A1…F4); bậc 2 chỉ là đọc lại điều bài đã tự khai.
            </para>
            <para>
            Bậc 2 <b>không</b> lọc theo <c>ContentType</c>: mã nhánh là duy nhất toàn bảng (chỉ số
            <c>UX_Category_ContentCategoryCode</c>), nên khớp được mã là khớp đúng danh mục. Lọc thêm chỉ
            tạo ra cảnh "gắn mã rồi mà vẫn đăng vào danh mục mặc định" không ai giải thích nổi.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService.GomTenTag(Lada.Framework.Data.Domains.ContentStore.ContentArticle)">
            <summary>
            Tên tag của bài: từ khoá chính trước, rồi các từ khoá phụ theo đúng thứ tự bài khai.
            <para>
            Chuẩn hoá y hệt <c>TagService</c> của CMS — <c>ToLower().Trim()</c> — để bài do kho nội dung đăng
            và bài biên tập viên gõ tay dùng CHUNG một dòng <c>Tag</c>, không đẻ ra hai bản ghi "cod hàng nặng"
            và "COD hàng nặng" nằm cạnh nhau trên trang tag.
            </para>
            <para>
            Cắt theo <see cref="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService.TagNameMax"/> và bỏ tên rỗng: <c>Tag.Name</c> là nvarchar(256), và một từ khoá
            dài quá cột sẽ làm cả lượt đăng vỡ ở lệnh INSERT sau khi Post đã ghi xong.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService.GhiTag(System.Int32,System.Collections.Generic.List{System.String},Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor,System.DateTimeOffset)">
            <summary>
            Ghi <c>PostTag</c> cho bài vừa tạo, tạo <c>Tag</c> mới cho tên chưa có.
            <para>
            <b>Dùng lại dòng <c>Tag</c> sẵn có thay vì luôn tạo mới</b>, và tra bằng đúng tên đã chuẩn hoá.
            Tag trùng tên là hai trang tag rời nhau trên website, mỗi trang một nửa số bài.
            </para>
            <para>
            <b>Tag mới kèm <c>UrlRecord</c></b> dựng theo cùng nếp <c>TagService.CreateAsync</c>: slug bỏ dấu
            tiếng Việt, đụng slug thì nối hậu tố đếm. Tag không có <c>UrlRecord</c> là một tag không bấm vào
            được — hiện ra trên bài mà dẫn tới 404.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishService.SlugTagChuaDung(System.String)">
            <summary>
            Slug chưa ai dùng cho một tên tag. <c>QueryAll</c> chứ không <c>Query</c>: <c>UrlRecord</c> xoá mềm
            vẫn giữ chỗ ở chỉ số của DB, nhìn bằng <c>Query</c> là kết luận "còn trống" rồi vỡ ở lệnh INSERT —
            cùng cái bẫy mà đường kiểm slug bài viết đã cắn phải.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentRunLogService">
            <summary>
            Nhật ký lượt chạy nháp bài (đặc tả §5.1 <c>append_run_log</c>). Một dòng cho mỗi lượt trợ lý AI
            chạy, để đối chiếu về sau: hôm đó nháp mấy bài, điểm trung bình bao nhiêu, còn bao nhiêu ô phải điền.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentRunLogService.Recent(System.Int32)">
            <summary>Các lượt gần nhất, mới trước — màn quản trị và trợ lý AI cùng đọc.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentRunLogService.ToItem(Lada.Framework.Data.Domains.ContentStore.ContentRunLog)">
            <summary>Ánh xạ tay (không qua AutoMapper) vì 4 cột là JSON phải parse — profile không nên giấu lỗi JSON.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentServicePageService">
            <summary>
            Danh sách trang dịch vụ đang chạy trên website (đặc tả §5.3 <c>list_service_pages</c>).
            Trợ lý AI đặt link nội bộ theo danh sách này thay vì bịa URL — đây là toàn bộ lý do tool tồn tại.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentServicePageService">
            <summary>
            Đọc thẳng <c>Product</c> + <c>UrlRecord</c> nên số trang luôn đúng thực tế (Việc 0 GĐ A đo được 25,
            không phải 24 như đặc tả ghi) và tự đúng khi marketing thêm trang mới.
            <para>
            <b>Không suy loại trang từ enum <see cref="T:Lada.Framework.Data.Enums.ProductType"/>.</b> Dữ liệu thật có giá trị <c>0</c> —
            13/25 trang — mà enum không khai (General = 1, Bike = 2, Household = 3, Fulltrip = 6), nên
            <c>GetDescription()</c> trên giá trị 0 trả về chuỗi rỗng. Item trả cả số thô lẫn nhãn đọc được.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentServicePageService.ServiceSlugPrefix">
            <summary>Tiền tố slug của trang dịch vụ trên website.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentServicePageService.LoadProvinceNames">
            <summary>
            Tên tỉnh của <b>cả hai</b> bộ địa giới đang sống song song trong bảng Location (bộ 34 tỉnh sau
            sáp nhập và bộ 63 tỉnh cũ): tiêu đề trang dịch vụ viết từ trước sáp nhập nên còn tên tỉnh cũ.
            Luật lọc/sắp nằm ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ServiceRouteGuesser.BuildProvinceKeys(System.Collections.Generic.IEnumerable{System.String})"/>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes">
            <summary>
            Mã lỗi nghiệp vụ của kho nội dung AI — dùng chung cho REST (GĐ A) và MCP (GĐ C).
            Chuỗi mã là hợp đồng với trợ lý AI, không đổi.
            </summary>
            <remarks>
            <b>Bảng này là bảng thật, không phải bảng §5.4 của đặc tả 0.1.</b> Bốn mã của cơ chế ô chờ và cụm dữ liệu
            (<c>PLACEHOLDER_NOT_FOUND</c>, <c>PLACEHOLDER_NOT_OPEN</c>, <c>CLUSTER_NOT_FOUND</c>,
            <c>CLUSTER_NOT_CONFIRMED</c>) đã bỏ cùng cơ chế 2026-09-12 — giữ lại mã chết chỉ khiến trợ lý AI tin là
            đường đó còn sống. Thêm mã mới thì thêm cả nhánh trong <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.ToHttpStatus(System.String)"/>.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.TopicNotFound">
            <summary>topic_code không tồn tại.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.TopicNotQueued">
            <summary>Đề bài không ở trạng thái chờ nháp (blocked/dropped).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.AlreadyExists">
            <summary>Đã có bài cho topic_code này (kèm ArticleId cũ trong Extra).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.SlugTaken">
            <summary>Slug trùng (kèm gợi ý slug mới trong Extra).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.ContentGateFailed">
            <summary>Vi phạm cổng chặn nội dung cứng (kèm danh sách vi phạm có vị trí).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.VersionConflict">
            <summary>expected_version lệch bản hiện tại.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.InvalidTransition">
            <summary>Đổi trạng thái sai máy trạng thái.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.PublishPreconditionFailed">
            <summary>Duyệt/đăng khi chưa đủ điều kiện (kèm danh sách thiếu).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.PayloadTooLarge">
            <summary>Quá giới hạn kích thước (512 KB payload, 200 KB thân bài).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.ScoreInconsistent">
            <summary>Phiếu tự chấm không nhất quán (total ≠ Σ, điểm > max, thiếu mục, todo ≠ 3…).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.ImageSpecInvalid">
            <summary>Bộ ảnh vi phạm quy tắc cứng §7.4 đặc tả (bổ sung ngoài bảng §5.4 — đặc tả ghi 422 nhưng không đặt mã).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.ValidationError">
            <summary>Payload thiếu trường bắt buộc hoặc sai định dạng (bổ sung ngoài bảng §5.4).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.ArticleNotFound">
            <summary>Không có bài với article_id / topic_code / slug đã gửi (bổ sung ngoài bảng §5.4, GĐ B).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.TokenNotFound">
            <summary>Token truy cập cá nhân (PAT) không tồn tại — GĐ C.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.ImageNotFound">
            <summary>Dòng ảnh không tồn tại (set_image_status — GĐ D).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.PostNotFound">
            <summary>Bài khai <c>PostId</c> nhưng bài viết CMS đó không còn (bị xoá trong CMS sau khi đăng).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.PublishDisabled">
            <summary>Công tắc <c>AppConfig ContentStore.PublishEnabled</c> đang tắt (GĐ F). Chỉ chặn đường ghi — soát thử vẫn chạy.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.CategoryNotResolved">
            <summary>Không xác định được danh mục CMS: bài chưa chọn và <c>ContentStore.DefaultCategoryId</c> sai hoặc trỏ vào danh mục đã xoá (GĐ F, §7.10).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.Forbidden">
            <summary>Thiếu quyền cho chính thao tác đang gọi, dù đã qua cổng <c>[Authorize]</c> của controller — hiện chỉ dùng cho "Đăng ngay" đòi <c>Post.Publish</c> (GĐ F, §7.11).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.BodyMarkdownMaxChars">
            <summary>Giới hạn thân bài Markdown (ký tự) — đặc tả §9: 200 KB.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.PayloadMaxBytes">
            <summary>Giới hạn toàn payload (byte) — đặc tả §9: 512 KB.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreErrorCodes.ToHttpStatus(System.String)">
            <summary>Ánh xạ mã lỗi → HTTP status cho REST. MCP (GĐ C) dùng JSON-RPC error, không dùng hàm này.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreJson">
            <summary>
            JSON cho các cột *Json của bảng Content*: Newtonsoft, tên thuộc tính PascalCase như DTO (nội bộ,
            không phải hợp đồng MCP — GĐ C chuyển snake_case ở lớp tool). Null-safe hai chiều.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreJson.FlattenStrings(System.Object)">
            <summary>
            Trải phẳng mọi giá trị chuỗi trong một object JSON theo thứ tự khai báo thuộc tính (depth-first).
            Đường dẫn dạng <c>EditorialNotes</c>, <c>DataNeeded[1]</c>, <c>Branch.Address</c>.
            Dùng chung cho trích placeholder và cổng chặn để hai bên đếm cùng một danh sách văn bản.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreJson.StringNodes(Newtonsoft.Json.Linq.JToken)">
            <summary>
            Mọi nút chuỗi của một object, <b>đúng thứ tự</b> mà <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreJson.FlattenStrings(System.Object)"/> duyệt. Trả về nút
            <see cref="T:Newtonsoft.Json.Linq.JValue"/> sống trong <paramref name="token"/> nên sửa <c>Value</c> là sửa luôn cây —
            đây là cách thay ngược giá trị vào đúng ô của Brief/Footer mà không phải viết lại đường dẫn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreJson.ToToken(System.Object)">
            <summary>Chuyển object thành cây JSON bằng đúng <see cref="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreJson.Settings"/> — để cây khớp chuỗi sẽ lưu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreText">
            <summary>
            Chuẩn hoá văn bản dùng chung cho so khớp từ khoá cụm dữ liệu và nhãn ô:
            FormKC (gấp ký tự tương thích: "m³" → "m3", chữ toàn chiều rộng → thường), bỏ dấu tiếng Việt
            (StringHelper.Unsigned), chữ thường, gộp khoảng trắng. Từ khoá seed trong DB đã ở dạng này;
            collation SQL_Latin1_General_CP1_CI_AS cũng coi "gia/m3" = "gia/m³" nên seed chỉ giữ dạng đã gấp.
            Regex gộp khoảng trắng chỉ khai báo ở đây — renderer và extractor gọi <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreText.CollapseWhitespace(System.String)"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreText.CollapseWhitespace(System.String)">
            <summary>
            Gộp mọi chuỗi khoảng trắng (kể cả tab, xuống dòng) thành một dấu cách rồi Trim; null/rỗng → chuỗi rỗng.
            Không đổi hoa thường, không bỏ dấu — muốn cả hai thì dùng <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreText.NormalizeForKeyword(System.String)"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreText.LineNumberAt(System.String,System.Int32)">
            <summary>Số dòng (1-based) của vị trí ký tự trong văn bản.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreText.ExcerptAround(System.String,System.Int32,System.Int32,System.Int32)">
            <summary>Đoạn trích ≤ maxLen ký tự quanh [index, index+length), thay xuống dòng bằng khoảng trắng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreNavPermissions">
            <summary>
            Nút và mục điều hướng nào của kho nội dung AI được hiện cho một người (rule <c>quyen-hien-thi</c>).
            </summary>
            <remarks>
            <para>
            <b>Hàm thuần</b> — không chạm database, không đọc <c>HttpContext</c>: nhận danh sách role đã phân giải,
            trả các cờ. Cùng khuôn với <c>ChatNavPermissions</c> của miền chat, và vì cùng một lý do: luật quyết định
            ai thấy gì phải có ca test gọi thẳng vào nó, chứ không nằm rải trong controller.
            </para>
            <para>
            <b>Vì sao cần cờ từ máy chủ.</b> SPA cố ý không nhận danh sách role vào router (<c>beforeEach</c> chỉ kiểm
            đăng nhập), nên <c>meta.roles</c> là tài liệu chứ không phải hàng rào. Menu thì đã được
            <c>MenuService</c> lọc theo <c>Menu.AllowRoles</c>, nhưng <b>nút bên trong trang</b> — Đổi trạng
            thái, Nộp ảnh, Tạo token — không có ai lọc hộ. Chép danh sách role sang JavaScript là dựng nguồn sự thật
            thứ hai, và cái lệch chỉ lộ ra khi người duyệt bấm vào rồi ăn 403.
            </para>
            <para>
            Mỗi cờ đọc đúng bó quyền của <b>thứ nó gác</b>, không phải bó quyền của lời gọi nạp dữ liệu:
            ví dụ <c>CanEdit</c> lấy đúng <c>ContentStore.Edit</c> của <c>SetStatus</c>/
            <c>SetPeople</c>/<c>SetImageStatus</c>, không lấy <c>ContentStore.GetById</c> vốn rộng hơn.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreNavPermissions.Founder">
            <summary>Vai bỏ qua mọi kiểm tra role của hệ thống (<c>ServerRoleAuthorizationHandler</c>).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreNavPermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c>; <c>null</c> hoặc rỗng = không có quyền nào.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreNavFlags">
            <summary>Cờ ẩn/hiện của kho nội dung AI — FE đọc bằng <c>=== true</c>, mặc định false, và ẩn hẳn phần tử.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreNavFlags.#ctor(System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
            <summary>Cờ ẩn/hiện của kho nội dung AI — FE đọc bằng <c>=== true</c>, mặc định false, và ẩn hẳn phần tử.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreIssue">
            <summary>
            Một phát hiện của luật nghiệp vụ (lỗi cứng hoặc cảnh báo mềm). Luôn kèm trường và vị trí
            để người duyệt / trợ lý AI sửa đúng chỗ — đặc tả §5.4 yêu cầu "kèm vị trí".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreIssue.Code">
            <summary>Mã lỗi nghiệp vụ (ContentStoreErrorCodes) — với cảnh báo mềm có thể null.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreIssue.Rule">
            <summary>Mã luật cụ thể, ví dụ GATE_01_HOTLINE_CU, IMG_LANE_A_UNBRANDED, SCORE_TOTAL_MISMATCH.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreIssue.Field">
            <summary>Trường bị vi phạm theo tên PascalCase của DTO: BodyMarkdown, MetaDescription, Title, Faq[2].A, Brief.EditorialNotes, Images[3].PromptEn, SelfScore.Sections.A_facts…</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreIssue.Position">
            <summary>Vị trí trong trường: "dòng 12", "h2:cuoc-tinh-the-nao", "faq:2"… null nếu không áp dụng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreIssue.Excerpt">
            <summary>Đoạn văn bản quanh chỗ vi phạm (≤ 80 ký tự) để nhận ra ngay.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreIssue.Message">
            <summary>Thông điệp tiếng Việt cho người đọc.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreValidationResult">
            <summary>Kết quả kiểm tra của một lớp luật thuần: lỗi cứng chặn lưu, cảnh báo mềm chỉ trả về.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreValidationResult.Merge(Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreValidationResult)">
            <summary>Gộp kết quả của lớp luật khác vào (dùng trong service tổng hợp).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreResult`1">
            <summary>
            Kết quả trả về của service kho nội dung. Khác BaseResult của repo ở chỗ có mã lỗi nghiệp vụ,
            danh sách vi phạm có vị trí và dữ liệu phụ (ArticleId cũ, gợi ý slug…) — vì REST của miền này
            trả 201/404/409/413/422 theo mã (prompt GĐ A), và MCP cần cùng cấu trúc cho JSON-RPC error.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreResult`1.ErrorCode">
            <summary>Mã lỗi từ ContentStoreErrorCodes; null khi Success.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreResult`1.Errors">
            <summary>Vi phạm cứng kèm vị trí (gate, ảnh, phiếu chấm, validation).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreResult`1.Warnings">
            <summary>Cảnh báo mềm — chỉ trả về, không chặn. Nguồn duy nhất: Data không lặp lại danh sách này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreResult`1.Extra">
            <summary>Dữ liệu phụ theo mã lỗi: ArticleId (ALREADY_EXISTS), SlugSuggestion (SLUG_TAKEN), CurrentVersion (VERSION_CONFLICT)…</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreResult`1.FromValidation(Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreValidationResult,System.String,System.String)">
            <summary>Tạo lỗi từ kết quả kiểm tra luật (lấy mã của lỗi đầu tiên nếu không truyền).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor">
            <summary>Người/ứng dụng thực hiện thao tác — ghi vào audit và cột audit của entity.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor.Client">
            <summary>"admin" cho REST/FE; "mcp:&lt;client_id&gt;" cho MCP (GĐ C).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor.RequestId">
            <summary>Request-id để lần vết; REST GĐ A để null, MCP GĐ C sinh Guid mỗi request.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActorExtensions">
            <summary>Đóng dấu cột audit của BaseEntity theo actor — dùng chung cho mọi entity kho nội dung ghi mới.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentAuditActions">
            <summary>Tên hành động ghi vào ContentAuditLog.Action — một nơi để FE/MCP lọc đúng chuỗi.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentAuditLogFactory">
            <summary>Dựng dòng ContentAuditLog đã đóng dấu audit — hai service dùng chung để không lệch cột.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentTopicCode">
            <summary>
            Mã đề bài dạng W2-01 / W12-05 (đặc tả §5.1). Một regex duy nhất cho cả service đề lẫn service bài —
            trước đây mỗi bên giữ một bản riêng, sửa một nơi là lệch nơi kia.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentTopicCode.Pattern">
            <summary>Nhóm 1 = tuần (1–2 chữ số), nhóm 2 = số thứ tự trong tuần (đúng 2 chữ số).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentTopicCode.IsValid(System.String)">
            <summary>Đúng định dạng W{tuần}-{stt}; null/rỗng → false. Không tự Trim — bên gọi quyết định.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentTopicCode.ParseWeek(System.String)">
            <summary>W2-03 → 2, W12-05 → 12; null nếu mã không đúng định dạng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentTopicService">
            <summary>Hàng đợi đề bài của kho nội dung AI (đặc tả §5.1 list_topics / create_topics).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentTopicService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Danh sách đề cho màn quản trị theo SmartTableParam (Keyword, Status, CategoryL2, WeekNo, PageType).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentTopicService.List(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicListRequest)">
            <summary>Danh sách đề cho trợ lý AI: lọc Status / WeekNo / loại trừ L2, theo SortOrder tăng dần, tối đa 100.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentTopicService.Create(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicModel},Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)">
            <summary>
            Tạo nhiều đề một lần. Dòng sai định dạng / trùng mã bị từ chối riêng (Rejected là dữ liệu, không phải lỗi);
            các dòng hợp lệ ghi trong một transaction kèm một dòng audit.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentTopicService.UpdateStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentTopicStatusModel,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentActor)">
            <summary>
            <c>update_topic_status</c> (đặc tả §5.1): đổi trạng thái một đề trong hàng đợi.
            <c>Drafted</c> bắt buộc kèm <c>ArticleId</c> — đề "đã nháp" mà không trỏ tới bài nào là dữ liệu sai.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentTopicService.SimilarTitleThreshold">
            <summary>Ngưỡng cảnh báo tiêu đề trùng (đặc tả §5.1: "cảnh báo nếu title trùng ≥ 85%").</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentTopicService.SimilarTitleWarnings(System.Collections.Generic.List{Lada.Framework.Data.Domains.ContentStore.ContentTopic})">
            <summary>
            Cảnh báo đề mới trùng ý với đề / bài đã có (đặc tả §5.1: ≥ 85%). So bằng hệ số Dice trên tập
            trigram của tiêu đề đã bỏ dấu — đủ để bắt "Gửi tủ đông đi Thanh Hoá" ~ "Gửi tủ đông đi Thanh Hóa"
            và không cần extension nào của SQL Server.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentTopicService.Trigrams(System.String)">
            <summary>Tập trigram của tiêu đề đã chuẩn hoá (bỏ dấu, thường, gộp khoảng trắng).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentTopicService.DiceCoefficient(System.Collections.Generic.HashSet{System.String},System.Collections.Generic.HashSet{System.String})">
            <summary>Hệ số Dice: 2·|giao| / (|A| + |B|) — 1 là hai chuỗi giống hệt sau chuẩn hoá.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ImageSpecInput.H2Slugs">
            <summary>Slug các H2 trong thân bài (từ IMarkdownRenderer) — để cảnh báo H2 chưa khai báo ảnh.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IImageSpecValidator">
            <summary>
            Kiểm bộ ảnh (đặc tả §7.4, Phụ lục A, plan §3.3f). Field báo lỗi dạng <c>Images[i].PromptEn</c> (i = chỉ số trong mảng gửi lên),
            Position = "OrderNo n". Lỗi cứng có Code = IMAGE_SPEC_INVALID:
            IMG_THUMBNAIL_COUNT (≠ 1 ThumbnailOg) · IMG_ORDER_DUP (OrderNo trùng hoặc &lt; 1) · IMG_ROLE_DECISION_MISSING ·
            IMG_SIZE_NOT_16 (Tool ∈ {GptImage2, NanoBanana} mà thiếu kích thước hoặc không chia hết 16) ·
            IMG_LANE_A_UNBRANDED (Lane = "A" mà PromptEn chứa "unbranded" / "no logos" / "no text of any kind" / "render no text", không phân biệt hoa thường — nêu đúng cụm) ·
            IMG_PROMPT_NOT_ALLOWED (ManualCanva/RealPhoto mà PromptEn không rỗng) · IMG_NONE_REASON (None mà thiếu NoneReason) ·
            IMG_AIPROMPT_MISSING (AiPrompt thiếu FrameCode/Lane/Tool/WidthPx/HeightPx/BriefVi/CaptionAlt/PromptEn) · IMG_FRAME_CODE (không khớp ^[A-E][1-6][a-d]?$) ·
            IMG_LANE (khác "A"/"B").
            Cảnh báo mềm: IMG_THUMB_SPEC (thumbnail không phải E1 1200×800) · IMG_REAL_PHOTO_EXPECTED (PageType BranchNews/Feature/CaseStudy mà ảnh Inline là AiPrompt) ·
            IMG_TEXT_PHONE (TextOnImage chứa số điện thoại) · IMG_H2_NO_IMAGE (H2 không có dòng ảnh nào) · IMG_H2_UNKNOWN (H2Key không khớp H2 nào).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ImageSpecValidator">
            <summary>
            Cài đặt <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IImageSpecValidator"/> — luật thuần trên payload ảnh, không chạm DB. Mã rule và ngữ nghĩa
            theo XML-doc của interface; mọi issue cấp dòng ảnh có Position = "OrderNo n", issue cấp bộ ảnh có Field = "Images".
            Ảnh None có H2Key vẫn tính là "H2 đã có dòng ảnh" — quyết định không dùng ảnh (kèm lý do) cũng là một quyết định.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ImageSpecValidator.LaneAForbiddenPhrases">
            <summary>Cụm cấm trong prompt làn A: làn A là brand kit (có logo/chữ thương hiệu), các cụm này mâu thuẫn với nó.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ImageSpecValidator.PhonePattern">
            <summary>
            Số điện thoại VN trong chữ trên ảnh: 0 hoặc +84 rồi 9–10 chữ số, hoặc 1900 rồi 4–6 chữ số; giữa các chữ số cho phép
            một khoảng trắng / dấu chấm nên bắt được mọi cách nhóm ("0912 345 678", "091 234 5678", "1900.633.658"); không được nằm
            giữa dãy số dài hơn (mã đơn, số tiền) nhờ lookaround.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ImageSpecValidator.RealPhotoPageTypes">
            <summary>Loại trang mà ảnh trong bài nên là ảnh chụp thật (tin bưu cục, phóng sự, case study).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ImageSpecValidator.KiemMotDong(Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreValidationResult,Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageModel,System.Int32,Lada.Framework.Data.Enums.ContentPageType,System.Collections.Generic.HashSet{System.Int32})">
            <summary>Toàn bộ luật cấp một dòng ảnh — lỗi cứng trước, cảnh báo mềm sau.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ImageSpecValidator.KiemPhuH2(Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreValidationResult,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageModel},System.Collections.Generic.IReadOnlyList{System.String})">
            <summary>H2 nào cũng phải có một dòng ảnh (kể cả None kèm lý do); H2Key lạ báo để sửa slug. Không có H2 thì bỏ qua.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftHeader">
            <summary>Dòng 1 của file nháp: mã đề, nhánh L2, loại trang, ngày nháp, số ảnh khai báo, trạng thái.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftHeader.RawLine">
            <summary>Nguyên văn dòng 1 (đã gỡ ký hiệu Markdown) — để đưa vào thông báo lỗi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftHeader.PageTypeText">
            <summary>Tên loại trang tiếng Việt nguyên văn trong file ("trang loại hàng").</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftHeader.DraftDate">
            <summary>Ngày nháp ghi ở dòng 1 — vào <c>ContentTopic.DraftedAt</c> khi tạo đề.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftHeader.DeclaredImageCount">
            <summary>Số ảnh khai báo ("6 ảnh") — chỉ để đối chiếu với số khối đọc được ở phần (c).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParseOptions">
            <summary>Tuỳ chọn đọc file nháp — không có gì bắt buộc, mặc định đủ chạy.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParseOptions.DraftedBy">
            <summary>Giá trị <c>DraftedBy</c> của bài tạo ra (đặc tả: "claude-routine" hoặc tên người).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParseOptions.SlugOverride">
            <summary>Ép slug thay vì suy từ tiêu đề — người nhập tự đặt khi slug suy ra bị trùng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParseResult">
            <summary>Kết quả đọc một file nháp: payload tạo bài + thông tin đề bài + đối chiếu số lượng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParseResult.DeclaredPlaceholderCount">
            <summary>Số ô ghi ở dòng cuối "Danh sách ô cần điền" — chỉ để đối chiếu, không lưu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParseResult.ParsedPlaceholderCount">
            <summary>Số ô <c>[[CẦN …]]</c> đếm được trên toàn bộ payload đã đọc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParseResult.Validation">
            <summary>Lỗi cấu trúc (chặn) và cảnh báo (không chặn), đều kèm số dòng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IMarkdownDraftParser">
            <summary>
            Đọc file bài nháp Markdown 4 phần thành payload tạo bài (Phụ lục C đặc tả). Thuần, không chạm DB.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IMarkdownDraftParser.Parse(System.String,System.String,Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParseOptions)">
            <param name="fileName">Tên file — chỉ để ghi vào thông báo lỗi.</param>
            <param name="content">Toàn bộ nội dung file.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser">
            <summary>
            Cài đặt <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IMarkdownDraftParser"/>.
            <para>
            <b>Nguyên tắc.</b> File do trợ lý AI viết tay nên hình thức luôn lệch đôi chút: parser chấp nhận biến thể
            (nhãn có/không in đậm, dấu hai chấm trong/ngoài cặp <c>**</c>, gạch đầu dòng khác nhau, tiêu đề phần ghi
            <c># (a) BRIEF</c> hay <c># a) Brief</c>) và chỉ báo <b>lỗi cứng</b> khi thiếu thứ không suy ra được:
            dòng 1, một trong 4 phần, tiêu đề, meta, thân bài, bộ ảnh. Mọi lệch còn lại là cảnh báo kèm số dòng —
            mất dữ liệu im lặng nguy hiểm hơn một file bị từ chối.
            </para>
            <para>
            <b>Tiêu đề trong file khác tiêu đề trong CSDL.</b> File viết <c>## H1: …</c> / <c>## H2: …</c> (quy ước
            của người viết), còn <c>BodyMarkdown</c> lưu Markdown thật (<c># …</c> / <c>## …</c>) vì slug H2 do
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IMarkdownRenderer"/> sinh phải khớp <c>ContentImage.H2Key</c> và <c>PositionKey</c> của ô dữ liệu.
            Parser bỏ tiền tố <c>Hn:</c> và hạ/nâng đúng cấp.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.SlugMaxLength">
            <summary>Độ dài cột <c>ContentArticle.Slug</c> — slug suy từ tiêu đề phải nằm trong khoảng này.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.ImageBlockStart">
            <summary>Khối ảnh mở đầu bằng "Ảnh 3 — …" (có thể bọc <c>**</c> hoặc là tiêu đề <c>###</c>).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.IsoDate">
            <summary>Ngày ở dòng 1: 2026-09-03 hoặc 03/09/2026.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.DeclaredBreakdown">
            <summary>Một mục của bảng kê ô: số, từ đếm tuỳ chọn ("ô", "×", "khối", "hạng mục"), rồi tên ô.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.TextOnImageLine">
            <summary>Một dòng chữ trên ảnh: <c>khu vực dưới: "GỬI TỦ ĐÔNG" (≤ 24 ký tự)</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.Range">
            <summary>Khoảng dòng nửa mở [Start, End) — Start là dòng ngay sau tiêu đề phần.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.SplitSections(System.String[],System.Int32)">
            <summary>
            Cắt file theo tiêu đề cấp 1. Nhận cả "# (a) BRIEF" lẫn "# a) Brief" / "# BRIEF"; phần nào không
            nhận ra thì bỏ qua (và sẽ báo thiếu ở cuối). Mọi thứ từ dòng "Danh sách ô cần điền" trở đi không
            thuộc phần nào — nó là bảng đối chiếu, không phải nội dung.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.FindChecklistLine(System.String[])">
            <summary>Chỉ số dòng "**Danh sách ô cần điền:**"; -1 nếu file không có.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.BriefLabels">
            <summary>Nhãn của phần brief → khoá nội bộ. Một khoá nhiều cách viết vì file mỗi tuần một khác.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.SplitBodyFaqFooter(Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParseResult,System.String[],System.Int32,System.Int32)">
            <summary>
            Chia phần thân thành thân bài / FAQ / chân trang theo tiêu đề cấp 2, giữ nguyên thứ tự các khối
            không phải FAQ hay chân trang. Tiêu đề <c>## Hn: X</c> viết lại thành đúng cấp <c>n</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.ParseFaq(System.Collections.Generic.List{System.ValueTuple{System.Int32,System.String}})">
            <summary>Mỗi câu hỏi mở đầu bằng <c>**Câu hỏi?**</c> hoặc một tiêu đề con; dòng sau nối vào câu trả lời.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.NormalizeFrameCode(System.String)">
            <summary>"e2D" / "E2d" / "E2D" → "E2d": chữ khuôn hoa, hậu tố biến thể thường.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.IsThumbnailText(System.String)">
            <summary>
            Có phải mô tả ảnh đại diện / OG không. "og" phải đứng trọn từ: dò <c>Contains("og")</c> thì
            một khối tên "ảnh logo đối tác" cũng thành ảnh đại diện, và bài sẽ có hai thumbnail → 422.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.DecideImage(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentImageModel,System.String,System.Boolean)">
            <summary>Quyết định ảnh suy từ từ khoá viết hoa trong khối (Phụ lục C), xét theo thứ tự ưu tiên cố định.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.ExtractNoneReason(System.String)">
            <summary>Câu sau "KHÔNG ẢNH" trên cùng dòng là lý do (Phụ lục C viết liền: "KHÔNG ẢNH — khối lập luận ngắn").</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.ScoreSections">
            <summary>Mỗi mục điểm nhận theo từ khoá trong ô đầu của dòng bảng; khoá trả về đúng tên đặc tả.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.ScoreColumns">
            <summary>Vị trí cột điểm / tối đa trong bảng điểm, đọc từ hàng tiêu đề (chỉ số tính từ ô sau tên mục).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.ReadScoreRow(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentSelfScoreModel,System.String,Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.ScoreColumns)">
            <summary>
            Một dòng bảng điểm. Ô đầu là tên mục; các ô số đọc theo hàng tiêu đề nếu có.
            </summary>
            <remarks>
            Đo 30 file nháp thật (04/09/2026): 20 file kẻ bảng <c>| Mục | Tối đa | Chấm |</c> — số đầu là ĐIỂM TỐI ĐA,
            số sau mới là điểm; 10 file kẻ <c>| Mục | Điểm |</c> và ghi tối đa trong ngoặc ở tên mục
            (<c>A. Dữ kiện thật (35)</c>). Đọc theo thứ tự số như đặc tả gợi ý ("30 | 35") thì 20 file bị chấm
            ngược: B = 15/20 thành 20/15 và validator báo "tối đa mục B phải là 20". Hàng tiêu đề nói rõ cột nào
            là gì — tin nó trước, thứ tự số chỉ là đường lùi.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.ParseGateResult(System.String)">
            <summary>"QUA (…)" / "đạt" / "pass" / "có" → true; "KHÔNG QUA" / "trượt" / "fail" / "chưa" → false; còn lại null.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.CountPlaceholders(Ladaer.BackEnd.Infrastructures.DTO.Models.ContentStore.ContentArticleModel)">
            <summary>Đếm ô <c>[[CẦN …]]</c> trong mọi trường sẽ được trích (thân bài, meta, FAQ, brief, chân trang).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.LabeledEntry.LineNos">
            <summary>Mọi dòng đã gộp vào giá trị này (kể cả dòng nối tiếp) — số dòng thật trong file.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.LabeledBlock">
            <summary>Kết quả đọc khối nhãn: cặp nhãn/giá trị và những dòng không thuộc nhãn nào.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.ReadLabeledBlock(System.Collections.Generic.IReadOnlyList{System.ValueTuple{System.Int32,System.String}},System.Collections.Generic.Dictionary{System.String,System.String})">
            <summary>
            Đọc khối "nhãn: giá trị". Dòng không mở đầu bằng nhãn đã biết được nối vào giá trị của nhãn trước đó —
            prompt ảnh và ghi chú biên tập đều dài hơn một dòng. Dòng đứng trước mọi nhãn trả về trong
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.LabeledBlock.Orphans"/> để bên gọi quyết định: brief/ảnh thì cảnh báo, chân trang thì
            đọc tiếp theo luật riêng (ô hồ sơ tác giả và link trần đứng một mình là đúng mẫu).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.IsTopLevelBullet(System.String)">
            <summary>Dòng mở đầu bằng gạch đầu dòng / số thứ tự và <b>không thụt lề</b>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.TableRowToLabelLine(System.String)">
            <summary>
            Hàng bảng Markdown <c>| Nhãn | Giá trị |</c> → <c>"Nhãn: Giá trị"</c>. Không phải hàng bảng thì trả
            nguyên dòng; hàng tiêu đề ("Hạng mục"/"Nội dung") và hàng gạch <c>| --- |</c> trả <c>null</c> để bỏ qua.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.ExtractLinks(System.String)">
            <summary>
            Rút các đường dẫn nội bộ <c>/…</c> và mã đề <c>W2-01</c> khỏi một giá trị brief đầy chữ.
            </summary>
            <remarks>
            Đo 30 file nháp thật (04/09/2026): link trang trụ và link ngang hiếm khi đứng trần. Chúng nằm
            trong dấu backtick, kèm ghi chú trong ngoặc, và với bài mà trang trụ **chưa đăng** thì người viết
            ghi <c>"bài W1-01 — trang trụ …"</c> — tức tham chiếu mã đề, không có URL nào cả. Tách theo dấu phẩy
            rồi lấy từ đầu tiên là ra chữ "bài".
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.WarnOrphans(Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.LabeledBlock,Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreValidationResult,System.String)">
            <summary>Cảnh báo cho mọi dòng lạc — dùng ở brief, đầu phần (b) và trong khối ảnh.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.SplitList(System.String)">
            <summary>Tách danh sách: xuống dòng, dấu phẩy hoặc "·" — link và từ khoá đều viết kiểu này.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.FirstLine(System.String)">
            <summary>Dòng đầu tiên của một giá trị nhiều dòng — cho các trường vốn chỉ có một dòng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.FirstToken(System.String)">
            <summary>Từ đầu tiên (đến khoảng trắng) — dùng cho mã khuôn, làn, slug H2, link trang trụ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.BuildSlug(System.String)">
            <summary>
            Slug suy từ tiêu đề khi file không ghi — trùng thì import báo và gợi ý, <b>không tự đổi</b>.
            <c>NormalizeUrl</c> đổi mọi cụm ký tự lạ thành "-" nhưng không cắt dấu gạch ở hai đầu, mà slug
            có gạch đầu/cuối thì trượt regex của <c>CreateDraft</c> — cắt ở đây cho gọn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.TryResolvePageType(System.String,Lada.Framework.Data.Enums.ContentPageType@)">
            <summary>
            Tra loại trang từ chữ người viết gõ ở dòng 1.
            </summary>
            <remarks>
            Đo trên 30 file nháp thật (04/09/2026): tên loại trang gần như không bao giờ đứng trần. Nó luôn
            kéo theo một cái đuôi giải thích — <c>"blog how-to (dạng giải đáp)"</c>,
            <c>"trang trụ (pillar) — cụm C2 Hàng cồng kềnh"</c>, <c>"vệ tinh tuyến (chiều ngược)"</c>.
            Khớp chuỗi tuyệt đối bắt 9/30 file; cắt đuôi rồi khớp tiền tố bắt hết. Cái đuôi là ghi chú cho
            người đọc, không phải một phần của tên loại — bắt người viết bỏ nó đi thì họ sẽ quên, và
            một file hỏng vì dấu ngoặc là kiểu lỗi làm người ta bỏ luôn công cụ.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser.BuildImageTools">
            <summary>Khoá là dạng đã bỏ khoảng trắng/gạch (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.TightKey(System.String)"/>) để so <c>Contains</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText">
            <summary>
            Tiện ích đọc văn bản Markdown của file bài nháp: gỡ ký hiệu Markdown quanh nhãn, tách cặp
            <c>Nhãn: giá trị</c>, và tra tên tiếng Việt trong file về enum.
            <para>
            Tách riêng khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftParser"/> vì cả parser lẫn test ma trận ánh xạ tên loại trang
            đều dùng; và vì tra enum theo <c>[Description]</c> là luật chung, không phải chi tiết của một file.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.LeadingMarkers">
            <summary>Ký hiệu mở đầu dòng cần gỡ trước khi đọc nhãn: gạch đầu dòng, số thứ tự, dấu thăng tiêu đề.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.Emphasis">
            <summary>Nhấn mạnh Markdown quanh nhãn: <c>**Nhãn:**</c>, <c>__Nhãn__</c>, <c>*Nhãn*</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.LongHeadLabel">
            <summary>Nhãn được phép có phần đầu dài (xem <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.TrySplitLabel(System.String,System.String@,System.String@,System.String@)"/>).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.Heading">
            <summary>Dòng tiêu đề Markdown — nhóm 1 là dấu thăng, nhóm 2 là nội dung.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.HeadingLevelPrefix">
            <summary>Tiền tố <c>H1:</c> / <c>H2:</c> trong tiêu đề của file nháp — quy ước viết, không phải cấp thật.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.Size">
            <summary>Kích thước ảnh: 1200×800, 1200x800, 1200 X 800.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.StripMarkers(System.String)">
            <summary>Gỡ gạch đầu dòng / dấu thăng / số thứ tự rồi gỡ nhấn mạnh; giữ nguyên dấu tiếng Việt.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.TrySplitLabel(System.String,System.String@,System.String@,System.String@)">
            <summary>
            Tách <c>- **Nhãn (ghi chú):** giá trị</c> thành nhãn, phần trong ngoặc và giá trị.
            Dấu hai chấm của URL (<c>https://</c>) và của khung giờ (<c>08:00</c>) không tính là dấu tách:
            chỉ nhận dấu hai chấm đầu tiên nằm trong 60 ký tự đầu và không dính ngay ký tự <c>/</c> hoặc chữ số.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.Key(System.String)">
            <summary>Khoá tra nhãn: bỏ dấu, thường, gộp khoảng trắng (dùng chung <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreText"/>).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.TightKey(System.String)">
            <summary>Khoá tra tên công cụ / mã: bỏ luôn khoảng trắng, gạch, gạch dưới — "GPT Image 2" = "gpt_image_2".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.FirstInt(System.String)">
            <summary>Số nguyên đầu tiên trong chuỗi; null nếu không có.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.DescriptionMap``1">
            <summary>
            Bảng tra tên → giá trị enum: nhận <c>[Description]</c> tiếng Việt ("Trang loại hàng"), tên C#
            ("GoodsPage") và tên snake_case của đặc tả ("goods_page"). Nhãn trong file so bằng <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.Key(System.String)"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownDraftText.ToSnakeCase(System.String)">
            <summary>GoodsPage → goods_page; BlogB2b → blog_b2b (tên snake_case đặc tả dùng).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownHeading">
            <summary>Một tiêu đề trong thân bài Markdown.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownHeading.Level">
            <summary>1 = H1, 2 = H2…</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownHeading.Text">
            <summary>Văn bản tiêu đề đã bỏ ký hiệu Markdown inline (giữ nguyên ô [[…]] nếu có).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownHeading.Slug">
            <summary>Slug sinh bằng StringHelper.NormalizeUrl — dùng chung cho PositionKey h2:&lt;slug&gt; và ContentImage.H2Key.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownHeading.LineNumber">
            <summary>Dòng (1-based) trong Markdown.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownHeading.CharIndex">
            <summary>Vị trí ký tự bắt đầu dòng tiêu đề trong chuỗi gốc.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IMarkdownRenderer">
            <summary>
            Markdown → HTML bằng Markdig. Ba lớp phòng thủ ở tầng render: DisableHtml (HTML thô thành văn bản đã escape),
            danh sách extension tường minh (KHÔNG có GenericAttributes — thứ cho tác giả gắn onerror/onclick/style qua
            {name=value} — cũng không có MediaLinks/Diagrams/CustomContainers sinh iframe/div), và
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.SafeUrl(System.String)"/> gắn vào HtmlRenderer.LinkRewriter để href/src chỉ còn scheme an toàn.
            Đây KHÔNG phải sanitizer đầu ra: GĐ F phải thêm sanitizer allowlist (thẻ + thuộc tính) trước khi ghi
            Post.Description, vì HTML này rồi sẽ ra trang công khai. Là nguồn duy nhất sinh slug H2 để PositionKey và H2Key khớp nhau.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IMarkdownRenderer.RenderHtml(System.String)">
            <summary>Render Markdown thành HTML.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IMarkdownRenderer.GetHeadings(System.String)">
            <summary>Danh sách tiêu đề theo thứ tự xuất hiện (mọi cấp); lọc Level == 2 để lấy H2.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IMarkdownRenderer.GetH2Headings(System.String)">
            <summary>Chỉ H2 — tiện cho ImageSpecValidator.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IMarkdownRenderer.Slugify(System.String)">
            <summary>Slug của một tiêu đề = StringHelper.NormalizeUrl(text đã bỏ ký hiệu Markdown và bỏ ô [[…]]).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IMarkdownRenderer.CountWords(System.String)">
            <summary>Đếm từ thân bài: bỏ ký hiệu Markdown và ô [[…]], tách theo khoảng trắng, đếm token có chữ/số.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer">
            <summary>
            Cài đặt <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IMarkdownRenderer"/> bằng Markdig. Pipeline dựng một lần (bất biến, dùng chung giữa các luồng).
            Tiêu đề và đếm từ tự quét theo dòng thay vì qua AST của Markdig — để giữ được số dòng và vị trí ký tự
            trong chuỗi gốc, thứ mà PositionKey của ô dữ liệu và thông báo lỗi cần tới.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.Pipeline">
            <summary>
            Danh sách extension tường minh thay cho UseAdvancedExtensions — cái sau bật cả GenericAttributes
            ({onerror=…} lên img/a/heading, HtmlRenderer ghi tên thuộc tính nguyên), MediaLinks (iframe), Diagrams,
            CustomContainers, Mathematics, YAML… DisableHtml chỉ gỡ parser HTML thô, không phải sanitizer,
            nên phần còn lại phải tự chọn. Thêm extension mới vào đây là mở thêm bề mặt tấn công — cân nhắc kỹ.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.SafeUrlPrefixes">
            <summary>Scheme/tiền tố URL được phép đi thẳng ra href/src (so không phân biệt hoa thường).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.SchemeDelimiters">
            <summary>Ký tự kết thúc phần scheme theo cú pháp URL — có ':' sau một trong số này thì không còn là scheme.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.TokenPrefix">
            <summary>Token thế chỗ ô [[…]] trước khi render — chỉ chữ và số nên không trùng cú pháp Markdown nào.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.TokenInIdAttr">
            <summary>
            AutoIdentifier của Markdig sinh id heading từ văn bản đã tokenize (ví dụ id="gia-ldph0ldphend").
            Dọn đuôi đó (không phân biệt hoa thường) TRƯỚC khi thay token bằng span, để không bao giờ chèn span vào trong thuộc tính.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.HeadingLine">
            <summary>Dòng tiêu đề ATX: ≤ 3 khoảng trắng đầu, 1–6 dấu #, khoảng trắng, nội dung, tuỳ chọn dấu # đóng.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.FenceLine">
            <summary>Dòng mở/đóng khối code rào (``` hoặc ~~~, ≥ 3 ký tự).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.LinkOrImage">
            <summary>Link / ảnh Markdown: [text](url), ![alt](url) → giữ lại text.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.InlineMarks">
            <summary>Ký hiệu inline dính vào từ (nhấn mạnh, code, gạch ngang) — bỏ hẳn, không thay bằng khoảng trắng.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.BlockMarks">
            <summary>Ký hiệu khối / bảng đứng tách từ (#, >, |, -) — thay bằng khoảng trắng.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.OrderedListMarker">
            <summary>Số thứ tự danh sách đầu dòng ("1. ", "2) ") — không phải từ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.SafeUrl(System.String)">
            <summary>
            Lọc scheme cho mọi URL Markdig ghi ra href/src (link, ảnh, autolink &lt;…&gt;, link tự nhận dạng) — gắn vào
            <see cref="P:Markdig.Renderers.HtmlRenderer.LinkRewriter"/>, được gọi trước khi URL được escape. Bỏ ký tự điều khiển và khoảng
            trắng trước khi so, vì trình duyệt cũng bỏ chúng khi đọc scheme ("java\tscript:" vẫn chạy). Cho phép
            http(s), mailto, tel, đường dẫn tuyệt đối/tương đối và neo; mọi scheme khác (javascript:, data:, vbscript:,
            file:, scheme lạ) trả "#" — giữ link nhưng vô hại. public static để test và để GĐ F (sanitizer allowlist) dùng lại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.Render(System.String)">
            <summary>
            Không dùng Markdown.ToHtml vì cần gắn <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.SafeUrl(System.String)"/> vào LinkRewriter của HtmlRenderer —
            Markdig không tự lọc scheme URL. Renderer tạo mới mỗi lần (không thread-safe); Pipeline dùng chung.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.CleanInline(System.String)">
            <summary>Bỏ link/ảnh (giữ text) và ký hiệu inline, gộp khoảng trắng. Không đụng tới ô [[…]].</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.HtmlEncodeMinimal(System.String)">
            <summary>
            Escape tối thiểu cho text node (&amp; &lt; &gt; "). Không dùng WebUtility.HtmlEncode vì nó đổi chữ Latin-1
            (á, é, ô…) thành &amp;#225; — vô hại nhưng làm phần này khác kiểu với HTML Markdig sinh ra quanh nó.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.MdLine.InFence">
            <summary>Dòng nằm trong (hoặc là dòng rào của) một khối code rào.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.MarkdownRenderer.SplitLines(System.String)">
            <summary>Tách dòng, giữ vị trí ký tự đầu dòng trong chuỗi gốc và đánh dấu dòng thuộc khối code rào.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishCheckInput">
            <summary>Ảnh chụp bài đủ để chạy tám điều kiện đăng — dựng từ DB ở service, không dính EF.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishCheckInput.AuthorProfileUrl">
            <summary>Hồ sơ công khai của tác giả — điều kiện (1) đòi không rỗng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentPublishCheckInput.GateResult">
            <summary>Kết quả chạy lại cổng chặn §3.3b trên bản đã thay ô — điều kiện (6).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentImageItemSnapshot">
            <summary>Phần của một dòng ảnh mà điều kiện (5) cần biết.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IPublishPreconditionChecker">
            <summary>
            Tám điều kiện chuyển <c>Approved</c> (đặc tả §7.2, plan §3.3d). Trả <b>danh sách thiếu</b>, không chỉ
            true/false — người duyệt cần biết còn phải làm gì, không phải chỉ biết "chưa được".
            </summary>
            <remarks>
            <b>Hàm thuần</b>: không DB, không HttpContext — nhận ảnh chụp bài, trả kết quả. Test không cần DB.
            <para>
            <b>Phạm vi GĐ D</b>: lớp này mới chỉ được gọi ở đường <b>chỉ đọc</b>
            <c>GET /api/ContentArticle/PublishCheck/{id}</c> để màn chi tiết hiện danh sách còn thiếu.
            <b>GĐ E</b> nối chính lớp này vào <c>SetArticleStatus(Approved)</c> — người gọi là ai cũng đi qua đúng
            một hàm (Nguyên tắc 1.4: không có đường tắt kể cả admin), và bổ sung chỗ sửa
            <c>PublishWithoutImages</c>/<c>OverrideNote</c>. Đừng nhân bản luật này ở nơi khác.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.PublishPreconditionChecker">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IPublishPreconditionChecker"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.PublishPreconditionChecker.MinSelfScore">
            <summary>Ngưỡng điểm tự chấm để đăng mà không cần ghi chú bỏ qua (§3.3d(8)).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.PublishPreconditionChecker.CanNguoiKiemTra">
            <summary>Loại trang bắt buộc có người kiểm tra khác tác giả (§3.3d(3)).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.SelfScoreValidationResult">
            <summary>Kết quả kiểm phiếu tự chấm: lỗi cứng + trạng thái bị ép (nếu có).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.SelfScoreValidationResult.Total">
            <summary>Tổng điểm đã kiểm (= Total khi hợp lệ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.SelfScoreValidationResult.ForcedStatus">
            <summary>NeedsRewrite khi total &lt; 70 hoặc GatePassed = false; Hold khi Verdict = Hold; null = giữ PendingReview.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.ContentStore.SelfScoreValidationResult.ForcedReason">
            <summary>Lý do ép trạng thái — ghi vào ContentArticle.StatusReason.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ISelfScoreValidator">
            <summary>
            Kiểm phiếu tự chấm (đặc tả §4.7, plan §3.3c). Điểm tối đa cố định A_facts 35 · B_operations 20 · C_structure 15 ·
            D_conversion 15 · E_seo 10 · F_language 5. Lỗi cứng (Code = SCORE_INCONSISTENT): thiếu mục, max sai, score &lt; 0 hoặc &gt; max,
            Total ≠ Σ score, thiếu GatePassed/Verdict/Total, ReviewerTodos ≠ 3. Không lỗi thì tính ForcedStatus:
            GatePassed = false hoặc Total &lt; 70 → NeedsRewrite (ưu tiên); Verdict = Hold → Hold.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.SelfScoreSections">
            <summary>Hằng điểm tối đa từng mục — một nơi duy nhất.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.SelfScoreSections.RewriteThreshold">
            <summary>Ngưỡng ép NeedsRewrite.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.SelfScoreSections.ApproveThreshold">
            <summary>Ngưỡng điều kiện đăng §3.3d(8) — dùng ở GĐ E.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.SelfScoreValidator">
            <summary>
            Cài đặt <see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ISelfScoreValidator"/> — luật thuần trên DTO, không chạm DB. Mọi lỗi cứng dùng chung
            Code = SCORE_INCONSISTENT và phân biệt bằng Rule; Field theo tên PascalCase của DTO
            (<c>SelfScore.Sections.A_facts.Score</c>…) để trợ lý AI sửa đúng chỗ. Khoá mục so khớp nguyên văn
            ("A_facts", không bỏ qua hoa thường) vì khoá là dữ liệu hợp đồng với trợ lý, không phải tên thuộc tính.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ServiceRouteGuesser">
            <summary>
            Đoán tuyến "tỉnh đi → tỉnh đến" từ tên một trang dịch vụ, dùng chung cho kho nội dung AI
            (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentServicePageService"/>, <c>list_service_pages</c>) và form Dịch vụ của CMS
            (<c>ProductService.RouteCityOptions</c>) — một bộ luật, hai nơi dùng, không trôi dạt.
            </summary>
            <remarks>
            Hàm thuần: nơi gọi tự nạp tên tỉnh từ bảng <c>Location</c> rồi đưa vào đây, nên luật test được không cần DB.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ServiceRouteGuesser.ProvinceNames(System.Linq.IQueryable{Lada.Framework.Data.Domains.Categories.Location})">
            <summary>
            Nguồn tên để dò: tên tỉnh Level 1 của <b>cả hai</b> bộ (34 tỉnh sau sáp nhập + 63 tỉnh cũ) — tiêu đề trang dịch vụ
            phần lớn viết trước sáp nhập. Một truy vấn cho mọi nơi đoán tuyến; xoá mềm do <c>IRepository.Query()</c> lọc.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ServiceRouteGuesser.MinProvinceNameLength">
            <summary>Tên tỉnh ngắn hơn ngần này không đem đi dò trong tiêu đề (tránh khớp bừa).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ServiceRouteGuesser.AdminPrefixes">
            <summary>
            Tiền tố hành chính đứng đầu tên tỉnh, ở dạng đã chuẩn hoá (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreText.NormalizeForKeyword(System.String)"/>).
            Bộ 2 cấp ghi tên kèm tiền tố ("Thành phố Hà Nội", "Tỉnh Quảng Ninh") còn bộ 3 cấp để tiền tố ở cột riêng
            ("Hà Nội") — so tên hai bộ phải bỏ tiền tố ở cả hai vế. Dạng có dấu chấm đứng trước dạng không chấm.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ServiceRouteGuesser.BuildProvinceKeys(System.Collections.Generic.IEnumerable{System.String})">
            <summary>
            Chuẩn bị danh sách tỉnh để dò: bỏ tên rỗng/quá ngắn, kèm khoá chuẩn hoá, <b>tên dài xếp trước</b> —
            "Bà Rịa - Vũng Tàu" phải thắng "Vũng Tàu" khi cả hai cùng khớp.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ServiceRouteGuesser.GuessRoute(System.String,System.Collections.Generic.IReadOnlyList{System.ValueTuple{System.String,System.String}})">
            <summary>
            Hai tỉnh xuất hiện đầu tiên trong tên trang, theo thứ tự xuất hiện: "Xe tải ghép Hà Nội - Thanh Hóa"
            → (Hà Nội, Thanh Hóa). Không đủ hai tỉnh thì trả (null, null) — thà bỏ trống còn hơn đoán sai tuyến.
            </summary>
            <param name="productName">Tên trang dịch vụ.</param>
            <param name="provinces">Kết quả của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ServiceRouteGuesser.BuildProvinceKeys(System.Collections.Generic.IEnumerable{System.String})"/> (tên dài trước).</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ServiceRouteGuesser.MatchTwoLevel(System.String,System.Collections.Generic.IReadOnlyList{System.ValueTuple{System.Int32,System.String}})">
            <summary>
            Map một tên tỉnh đoán được (có thể thuộc bộ 3 cấp cũ) sang Id tỉnh bộ 2 cấp cùng tên, so khoá chuẩn hoá
            sau khi bỏ tiền tố hành chính đứng đầu ở cả hai vế. Không khớp — tỉnh cũ đã sáp nhập như "Hải Dương" —
            hoặc khớp hơn một tỉnh thì trả null: gợi ý sai tệ hơn không gợi ý.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ServiceRouteGuesser.BareKey(System.String)">
            <summary>Khoá chuẩn hoá đã bỏ một tiền tố hành chính đứng đầu ("Thành phố", "Tỉnh", "TP", "TP.").</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ServiceRouteGuesser.IndexOfWord(System.String,System.String)">
            <summary>Vị trí của <paramref name="needle"/> khi nó đứng trọn từ (hai đầu không dính chữ/số); -1 nếu không có.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Crm.ICallLogService">
            <summary>
            Interface cho CallLog Service
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICallLogService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm call log
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Kết quả tìm kiếm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICallLogService.GetById(System.Int32)">
            <summary>
            Lấy call log theo ID
            </summary>
            <param name="id">ID của call log</param>
            <returns>Thông tin call log</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICallLogService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel)">
            <summary>
            Tạo/cập nhật call log
            </summary>
            <param name="model">Thông tin call log</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICallLogService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel)">
            <summary>
            Tạo call log mới
            </summary>
            <param name="model">Thông tin call log</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICallLogService.Update(Lada.Framework.Data.Domains.Crm.CallLog)">
            <summary>
            Cập nhật call log
            </summary>
            <param name="callLog">Thông tin call log</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICallLogService.Delete(System.Int32)">
            <summary>
            Xóa call log
            </summary>
            <param name="id">ID của call log</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Crm.CallLogService">
            <summary>
            CallLog Service Implementation
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CallLogService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm call log với phân trang
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CallLogService.GetById(System.Int32)">
            <summary>
            Lấy call log theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CallLogService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel)">
            <summary>
            Tạo hoặc cập nhật call log
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CallLogService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CallLogModel)">
            <summary>
            Tạo call log mới
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CallLogService.Update(Lada.Framework.Data.Domains.Crm.CallLog)">
            <summary>
            Cập nhật call log
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CallLogService.Delete(System.Int32)">
            <summary>
            Xóa call log (soft delete)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerActivityService">
            <summary>
            Trạng thái hoạt động của khách hàng theo sale phụ trách (plan §7.4).
            </summary>
            <remarks>
            Hai đường đọc dùng **chung một stored procedure**: chỉ số KPI
            <c>sales.active-customers</c> và danh sách khách không hoạt động mà người quản lý xem để
            nhắc sale chăm sóc. Cố ý không tách hai query — con số trên thẻ KPI và số dòng trong danh
            sách phải luôn khớp, hai query riêng sẽ trôi khỏi nhau ngay lần sửa đầu tiên.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerActivityService.GetByActivityAsync(System.DateTimeOffset,System.Collections.Generic.IReadOnlyList{System.Int32},System.Nullable{System.Boolean})">
            <summary>
            Đọc thô theo danh sách sale — **không kiểm quyền**, chỉ dùng cho provider KPI đã được
            lớp trên ép phạm vi.
            </summary>
            <param name="asOfDate">Thời điểm chốt; cửa sổ hoạt động là 3 tháng lùi từ mốc này</param>
            <param name="saleIds">Giới hạn ở các sale này; rỗng/null = mọi sale</param>
            <param name="isActive">true = chỉ khách hoạt động, false = chỉ khách không hoạt động, null = cả hai</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerActivityService.GetInactiveInScopeAsync(System.Nullable{System.DateTimeOffset},System.Nullable{System.Int32},Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Danh sách khách **không hoạt động**, đã ép phạm vi theo quyền của người đang đăng nhập.
            </summary>
            <remarks>
            Hai tầng quyền: <c>Kpi.ViewAll</c> quyết định xem được KPI của ai, còn <c>Customer.Search</c>
            (hoặc Founder) mới quyết định đọc được **danh bạ khách hàng** ngoài đội của mình. Thiếu vế
            thứ hai thì kết quả luôn bị bó về cấp dưới trực tiếp, dù có <c>Kpi.ViewAll</c>.
            </remarks>
            <param name="asOfDate">Thời điểm chốt; bỏ trống lấy hiện tại</param>
            <param name="saleId">Lọc thêm về một sale; chỉ thu hẹp kết quả, không mở thêm quyền</param>
            <param name="currentUser">Người đang đăng nhập</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerActivityService.ResolveInactiveScopeAsync(System.Nullable{System.Int32},Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Phân giải phạm vi được phép đọc, **chưa** chạm dữ liệu.
            </summary>
            <remarks>
            Tách riêng để luật phân quyền kiểm được bằng test đơn vị, không phải dựng cả SQL Server.
            Đây là luật đã có một lỗ hổng bị bắt ở review GĐ C nên nó xứng đáng có test ghim.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerActivityScope">
            <summary>
            Phạm vi sale được phép đọc của một lần gọi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerActivityScope.Allowed">
            <summary>Có được đọc gì không; false thì trả danh sách rỗng, không chạm DB</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerActivityScope.SaleIds">
            <summary>
            Giới hạn ở các sale này; <c>null</c> nghĩa là **mọi sale** — chỉ hợp lệ khi
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerActivityScope.Allowed"/> và người gọi đã qua được cửa quyền CRM.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerActivityService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerActivityService" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerActivityService.RoleCustomerSearch">
            <summary>
            Role CRM quyết định được xem danh bạ khách hàng ngoài phạm vi đội của mình
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerActivityService.CanReadCrmDirectoryAsync(System.Int32)">
            <summary>
            Có được đọc danh bạ khách hàng hay không — Founder hoặc role CRM <c>Customer.Search</c>.
            </summary>
            <remarks>
            Đây là điều kiện CẦN cho mọi nhánh, không phải chỉ cho nhánh "xem tất cả": endpoint này
            trả tên và số điện thoại khách hàng, đúng thứ mà <c>/api/Customer/Search</c> gác bằng role
            <c>Customer.Search</c>. Thiếu chốt này thì một tài khoản chỉ có role KPI vẫn đọc được
            danh bạ của cấp dưới mình, tức role KPI tự nó mở được dữ liệu miền CRM.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerAddressService">
            <summary>
            Giao diện cho dịch vụ quản lý địa chỉ khách hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerAddressService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm địa chỉ khách hàng.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm địa chỉ khách hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerAddressService.Suggest(System.String,System.Int32,Lada.Framework.Data.Enums.AddressType)">
            <summary>
            Gợi ý địa chỉ khách hàng.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="customerId">Id của khách hàng.</param>
            <param name="addressType">Loại địa chỉ.</param>
            <returns>Danh sách địa chỉ khách hàng gợi ý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerAddressService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel)">
            <summary>
            Tạo hoặc cập nhật địa chỉ khách hàng.
            </summary>
            <param name="model">Thông tin địa chỉ khách hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerAddressService.GetById(System.Int32)">
            <summary>
            Lấy thông tin địa chỉ khách hàng theo Id.
            </summary>
            <param name="id">Id của địa chỉ khách hàng.</param>
            <returns>Thông tin địa chỉ khách hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerAddressService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa địa chỉ khách hàng.
            </summary>
            <param name="id">Id của địa chỉ khách hàng.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerAddressService.UpdateCustomerAddress(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel)">
            <summary>
            Cập nhật địa chỉ khách hàng.
            </summary>
            <param name="id">Id của địa chỉ khách hàng.</param>
            <param name="model">Thông tin địa chỉ khách hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerAddressService.UpdateCoord(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.UpdateCustomerAddressCoordModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Cập nhật riêng định vị (Lat/Long) của một địa chỉ khách hàng.
            </summary>
            <param name="model">Toạ độ cần ghi; để null cả hai nghĩa là xoá định vị.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerAddressService">
            <summary>
            Triển khai dịch vụ quản lý địa chỉ khách hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerAddressService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Crm.CustomerAddress},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Categories.Location},Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerAddressService"/>.
            </summary>
            <param name="customerAddressRepository">Đối tượng IRepository của CustomerAddress.</param>
            <param name="locationRepository">Đối tượng IRepository của Location.</param>
            <param name="locationService">Đối tượng ILocationService.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerAddressService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm địa chỉ khách hàng.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm địa chỉ khách hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerAddressService.Suggest(System.String,System.Int32,Lada.Framework.Data.Enums.AddressType)">
            <summary>
            Gợi ý địa chỉ khách hàng.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="customerId">Id của khách hàng.</param>
            <param name="addressType">Loại địa chỉ.</param>
            <returns>Danh sách địa chỉ khách hàng gợi ý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerAddressService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel)">
            <summary>
            Tạo hoặc cập nhật địa chỉ khách hàng.
            </summary>
            <param name="model">Thông tin địa chỉ khách hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerAddressService.Update(Lada.Framework.Data.Domains.Crm.CustomerAddress)">
            <summary>
            Cập nhật địa chỉ khách hàng.
            </summary>
            <param name="customerAddress">Thông tin địa chỉ khách hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerAddressService.Create(Lada.Framework.Data.Domains.Crm.CustomerAddress)">
            <summary>
            Thêm mới địa chỉ khách hàng.
            </summary>
            <param name="customerAddress">Thông tin địa chỉ khách hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerAddressService.GetById(System.Int32)">
            <summary>
            Lấy thông tin địa chỉ khách hàng theo Id.
            </summary>
            <param name="id">Id của địa chỉ khách hàng.</param>
            <returns>Thông tin địa chỉ khách hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerAddressService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa địa chỉ khách hàng.
            </summary>
            <param name="id">Id của địa chỉ khách hàng.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerAddressService.UpdateCustomerAddress(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerAddressModel)">
            <summary>
            Cập nhật địa chỉ khách hàng.
            </summary>
            <param name="id">Id của địa chỉ khách hàng.</param>
            <param name="model">Thông tin địa chỉ khách hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerAddressService.UpdateCoord(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.UpdateCustomerAddressCoordModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Cập nhật riêng định vị (Lat/Long) của một địa chỉ khách hàng.
            </summary>
            <param name="model">Toạ độ cần ghi; để null cả hai nghĩa là xoá định vị.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerBankAccountService">
            <summary>
            Giao diện cho dịch vụ quản lý tài khoản ngân hàng khách hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerBankAccountService.GetByCustomerId(System.Int32)">
            <summary>
            Lấy danh sách tài khoản ngân hàng của khách hàng.
            </summary>
            <param name="customerId">ID khách hàng.</param>
            <returns>Danh sách tài khoản ngân hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerBankAccountService.GetDefaultByCustomerId(System.Int32)">
            <summary>
            Lấy tài khoản ngân hàng mặc định của khách hàng.
            </summary>
            <param name="customerId">ID khách hàng.</param>
            <returns>Tài khoản ngân hàng mặc định.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerBankAccountService.GetById(System.Int32)">
            <summary>
            Lấy thông tin tài khoản ngân hàng theo ID.
            </summary>
            <param name="id">ID tài khoản.</param>
            <returns>Thông tin tài khoản ngân hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerBankAccountService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel)">
            <summary>
            Tạo hoặc cập nhật tài khoản ngân hàng.
            </summary>
            <param name="model">Thông tin tài khoản ngân hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerBankAccountService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa tài khoản ngân hàng.
            </summary>
            <param name="id">ID tài khoản.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerBankAccountService.SetDefault(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Đặt tài khoản làm mặc định.
            </summary>
            <param name="id">ID tài khoản.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerBankAccountService.Search(System.String,System.Nullable{System.Int32},System.String)">
            <summary>
            Tìm kiếm tài khoản ngân hàng.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="customerId">ID khách hàng (tùy chọn).</param>
            <param name="bankCode">Mã ngân hàng (tùy chọn).</param>
            <returns>Danh sách tài khoản ngân hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerBankAccountService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm tài khoản ngân hàng với SmartTable.
            </summary>
            <param name="param">Tham số SmartTable.</param>
            <returns>Kết quả tìm kiếm dưới dạng SmartTableResult.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerBankAccountService.Suggest(System.Int32,System.String)">
            <summary>
            Gợi ý tài khoản ngân hàng cho khách hàng.
            </summary>
            <param name="customerId">ID khách hàng.</param>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <returns>Danh sách gợi ý.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerBankAccountService">
            <summary>
            Dịch vụ quản lý tài khoản ngân hàng khách hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerBankAccountService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Crm.CustomerBankAccount},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Crm.Customer})">
            <summary>
            Khởi tạo dịch vụ quản lý tài khoản ngân hàng khách hàng.
            </summary>
            <param name="customerBankAccountRepository">Repository tài khoản ngân hàng.</param>
            <param name="customerRepository">Repository khách hàng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerBankAccountService.GetByCustomerId(System.Int32)">
            <summary>
            Lấy danh sách tài khoản ngân hàng của khách hàng.
            </summary>
            <param name="customerId">ID khách hàng.</param>
            <returns>Danh sách tài khoản ngân hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerBankAccountService.GetDefaultByCustomerId(System.Int32)">
            <summary>
            Lấy tài khoản ngân hàng mặc định của khách hàng.
            </summary>
            <param name="customerId">ID khách hàng.</param>
            <returns>Tài khoản ngân hàng mặc định.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerBankAccountService.GetById(System.Int32)">
            <summary>
            Lấy thông tin tài khoản ngân hàng theo ID.
            </summary>
            <param name="id">ID tài khoản.</param>
            <returns>Thông tin tài khoản ngân hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerBankAccountService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerBankAccountModel)">
            <summary>
            Tạo hoặc cập nhật tài khoản ngân hàng.
            </summary>
            <param name="model">Thông tin tài khoản ngân hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerBankAccountService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa tài khoản ngân hàng.
            </summary>
            <param name="id">ID tài khoản.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerBankAccountService.SetDefault(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Đặt tài khoản làm mặc định.
            </summary>
            <param name="id">ID tài khoản.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerBankAccountService.Search(System.String,System.Nullable{System.Int32},System.String)">
            <summary>
            Tìm kiếm tài khoản ngân hàng.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="customerId">ID khách hàng (tùy chọn).</param>
            <param name="bankCode">Mã ngân hàng (tùy chọn).</param>
            <returns>Danh sách tài khoản ngân hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerBankAccountService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm tài khoản ngân hàng với SmartTable.
            </summary>
            <param name="param">Tham số SmartTable.</param>
            <returns>Kết quả tìm kiếm dưới dạng SmartTableResult.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerBankAccountService.Suggest(System.Int32,System.String)">
            <summary>
            Gợi ý tài khoản ngân hàng cho khách hàng.
            </summary>
            <param name="customerId">ID khách hàng.</param>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <returns>Danh sách gợi ý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerBankAccountService.Create(Lada.Framework.Data.Domains.Crm.CustomerBankAccount)">
            <summary>
            Tạo tài khoản ngân hàng mới.
            </summary>
            <param name="bankAccount">Thông tin tài khoản ngân hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerBankAccountService.Update(Lada.Framework.Data.Domains.Crm.CustomerBankAccount)">
            <summary>
            Cập nhật tài khoản ngân hàng.
            </summary>
            <param name="bankAccount">Thông tin tài khoản ngân hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerComplaintManagementService">
            <summary>
            Dịch vụ xử lý ticket khiếu nại và yêu cầu đổi nhân viên phụ trách phía nhân viên
            (ticket do khách tạo từ app qua Lada.AppBackEnd).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerComplaintManagementService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm khiếu nại của khách hàng.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerComplaintManagementService.GetById(System.Int32)">
            <summary>
            Lấy chi tiết khiếu nại kèm ảnh đính kèm.
            </summary>
            <param name="id">Id khiếu nại.</param>
            <returns>Chi tiết khiếu nại, null nếu không tồn tại.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerComplaintManagementService.StartProcessing(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.ComplaintProcessModel)">
            <summary>
            Tiếp nhận khiếu nại (Draft → Processing).
            </summary>
            <param name="model">Thông tin thao tác.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerComplaintManagementService.Respond(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.ComplaintProcessModel)">
            <summary>
            Phản hồi khiếu nại cho khách (khách xem qua api/complaints).
            Khiếu nại đang Draft sẽ tự chuyển sang Processing.
            </summary>
            <param name="model">Thông tin phản hồi.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerComplaintManagementService.Resolve(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.ComplaintProcessModel)">
            <summary>
            Đóng khiếu nại (Processing → Resolved). Yêu cầu đã có phản hồi cho khách.
            </summary>
            <param name="model">Thông tin thao tác (StaffResponse truyền kèm sẽ cập nhật phản hồi).</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerComplaintManagementService.SearchChangeRequests(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm yêu cầu đổi nhân viên phụ trách.
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerComplaintManagementService.ApproveChangeRequest(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.ManagerChangeRequestProcessModel)">
            <summary>
            Duyệt yêu cầu đổi nhân viên: gán nhân viên mới cho khách qua luồng AssignManager sẵn có.
            </summary>
            <param name="model">Thông tin duyệt (NewManagerId bắt buộc).</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerComplaintManagementService.RejectChangeRequest(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.ManagerChangeRequestProcessModel)">
            <summary>
            Từ chối yêu cầu đổi nhân viên (ProcessedNote bắt buộc để khách biết lý do).
            </summary>
            <param name="model">Thông tin từ chối.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService">
            <summary>
            Giao diện cho dịch vụ quản lý khách hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm khách hàng.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm khách hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.SugManagers(System.String,System.Int32)">
            <summary>
            Gợi ý danh sách sale quản lý mà người dùng được phép lọc theo.
            Founder thấy toàn bộ nhân viên; người dùng thường chỉ thấy bản thân và cấp dưới trực tiếp.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="userId">Id người dùng đang đăng nhập.</param>
            <returns>Danh sách nhân viên gợi ý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.Suggest(System.String,System.Int32)">
            <summary>
            Gợi ý danh sách khách hàng trong phạm vi người dùng được phép xem.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="userId">Id người dùng đang đăng nhập.</param>
            <returns>Danh sách khách hàng gợi ý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerModel)">
            <summary>
            Tạo hoặc cập nhật khách hàng.
            </summary>
            <param name="model">Thông tin khách hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.GetById(System.Int32)">
            <summary>
            Lấy thông tin khách hàng theo Id.
            </summary>
            <param name="id">Id của khách hàng.</param>
            <returns>Thông tin khách hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa khách hàng.
            </summary>
            <param name="id">Id của khách hàng.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.Lock(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Khóa khách hàng.
            </summary>
            <param name="id">Id của khách hàng.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.UnLock(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Mở khóa khách hàng.
            </summary>
            <param name="id">Id của khách hàng.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.SetPassword(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerSetPasswordModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Đặt lại mật khẩu cho tài khoản đăng nhập của khách hàng.
            </summary>
            <param name="model">Thông tin đặt lại mật khẩu (Id khách hàng + mật khẩu mới).</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác, kèm <c>ErrorList</c> khi mật khẩu không đạt chính sách.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.RegisterAccount(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.RegisterCustomerAccountModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo tài khoản đăng nhập cho một khách hàng đã có hồ sơ.
            </summary>
            <param name="model">Id khách hàng, tên đăng nhập và mật khẩu.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác, kèm <c>ErrorList</c> khi Identity từ chối.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.AssignManager(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.AssignManagerModel,System.Boolean)">
            <summary>
            Gán người quản lý cho khách hàng.
            </summary>
            <param name="model">Thông tin người quản lý.</param>
            <returns>Kết quả của thao tác.</returns>
            <param name="cutChatReadAccess">
            <c>true</c> khi lần đổi này đến từ <b>yêu cầu của khách</b> (duyệt
            <c>CustomerManagerChangeRequest</c>): người đang giữ hội thoại chat của khách mất luôn
            quyền xem (§6.2). <c>false</c> cho lần gán hành chính bình thường.
            <para>
            Là THAM SỐ chứ không phải một trường trên <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.AssignManagerModel"/>, và đó là một
            bản vá bảo mật chứ không phải sở thích: model đi qua model binding, nên một trường ở đó
            là một trường client đặt được. Cắt quyền xem là hình phạt — nó phải do <b>đường gọi</b>
            quyết định, không do thân request.
            </para>
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.BulkAssignManager(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.BulkAssignManagerModel)">
            <summary>
            Gán người quản lý hàng loạt cho nhiều khách hàng.
            </summary>
            <param name="model">Thông tin gán hàng loạt.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.GetManagerById(System.Int32)">
            <summary>
            Lấy thông tin người quản lý theo Id khách hàng.
            </summary>
            <param name="id">Id của khách hàng.</param>
            <returns>Thông tin người quản lý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.UpdateCustomerProp(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerPropModel)">
            <summary>
            Cập nhật thuộc tính của khách hàng.
            </summary>
            <param name="model">Thông tin thuộc tính của khách hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.GetCustomerProp(System.Int32,Lada.Framework.Data.Enums.PropType)">
            <summary>
            Lấy thông tin thuộc tính của khách hàng.
            </summary>
            <param name="customerId">Id của khách hàng.</param>
            <param name="propType">Loại thuộc tính.</param>
            <returns>Thông tin thuộc tính của khách hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.UpdateCustomerStatus(System.Int32,Lada.Framework.Data.Domains.Crm.CustomerStatus)">
            <summary>
            Cập nhật trạng thái khách hàng.
            </summary>
            <param name="id">Id của khách hàng.</param>
            <param name="status">Trạng thái khách hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.ExportExcel(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Xuất danh sách khách hàng ra file Excel.
            </summary>
            <param name="param">Thông số tìm kiếm (dùng chung filter với Search).</param>
            <param name="userId">Id người thực hiện.</param>
            <returns>Kết quả xuất Excel.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.GetCoManagers(System.Int32)">
            <summary>
            Lấy danh sách đồng quản lý của khách hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.AddCoManager(System.Int32,System.Int32,System.String)">
            <summary>
            Thêm đồng quản lý cho khách hàng (tự động bỏ qua nếu đã tồn tại).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.RemoveCoManager(System.Int32,System.Int32)">
            <summary>
            Xóa đồng quản lý khỏi khách hàng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService">
            <summary>
            Triển khai dịch vụ quản lý khách hàng.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService._chatAlignmentService">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm khách hàng.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm khách hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm khách hàng.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm khách hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.GetVisibleManagerIdsAsync(System.Int32)">
            <summary>
            Lấy danh sách Id sale mà người dùng được phép xem khách hàng: bản thân + cấp dưới trực tiếp.
            </summary>
            <param name="userId">Id người dùng đang đăng nhập.</param>
            <returns>Danh sách Id sale trong phạm vi.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.SugManagers(System.String,System.Int32)">
            <summary>
            Gợi ý danh sách sale quản lý mà người dùng được phép lọc theo.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="userId">Id người dùng đang đăng nhập.</param>
            <returns>Danh sách nhân viên gợi ý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.Suggest(System.String,System.Int32)">
            <summary>
            Gợi ý danh sách khách hàng trong phạm vi người dùng được phép xem.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="userId">Id người dùng đang đăng nhập.</param>
            <returns>Danh sách khách hàng gợi ý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.TryGetFullPhoneNumber(System.String,System.String@)">
            <summary>
            Kiểm tra từ khóa có phải là một số điện thoại đầy đủ hay không.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="phoneNumber">Số điện thoại đã bỏ các ký tự phân cách.</param>
            <returns>True nếu từ khóa chỉ gồm chữ số cùng ký tự phân cách và có từ 10 chữ số trở lên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerModel)">
            <summary>
            Tạo hoặc cập nhật khách hàng.
            </summary>
            <param name="model">Thông tin khách hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.UpdateCustomerProp(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerPropModel)">
            <summary>
            Cập nhật thuộc tính của khách hàng.
            </summary>
            <param name="model">Thông tin thuộc tính của khách hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.GetCustomerProp(System.Int32,Lada.Framework.Data.Enums.PropType)">
            <summary>
            Lấy thông tin thuộc tính của khách hàng.
            </summary>
            <param name="customerId">Id của khách hàng.</param>
            <param name="propType">Loại thuộc tính.</param>
            <returns>Thông tin thuộc tính của khách hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.Create(Lada.Framework.Data.Domains.Crm.Customer)">
            <summary>
            Thêm mới khách hàng.
            </summary>
            <param name="customer">Thông tin khách hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.Update(Lada.Framework.Data.Domains.Crm.Customer)">
            <summary>
            Cập nhật khách hàng.
            </summary>
            <param name="customer">Thông tin khách hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.GetById(System.Int32)">
            <summary>
            Lấy thông tin khách hàng theo Id.
            </summary>
            <param name="id">Id của khách hàng.</param>
            <returns>Thông tin khách hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa khách hàng.
            </summary>
            <param name="id">Id của khách hàng.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.Lock(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Khóa khách hàng.
            </summary>
            <param name="id">Id của khách hàng.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.UnLock(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Mở khóa khách hàng.
            </summary>
            <param name="id">Id của khách hàng.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.SetPassword(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.CustomerSetPasswordModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Đặt lại mật khẩu cho tài khoản đăng nhập của khách hàng.
            </summary>
            <param name="model">Thông tin đặt lại mật khẩu (Id khách hàng + mật khẩu mới).</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác, kèm <c>ErrorList</c> khi mật khẩu không đạt chính sách.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.RegisterAccount(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.RegisterCustomerAccountModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo tài khoản đăng nhập cho một khách hàng đã có hồ sơ.
            </summary>
            <param name="model">Id khách hàng, tên đăng nhập và mật khẩu.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác, kèm <c>ErrorList</c> khi Identity từ chối.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.GetManagerById(System.Int32)">
            <summary>
            Lấy thông tin người quản lý theo Id khách hàng.
            </summary>
            <param name="id">Id của khách hàng.</param>
            <returns>Thông tin người quản lý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.AssignManager(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.AssignManagerModel,System.Boolean)">
            <summary>
            Gán người quản lý cho khách hàng.
            </summary>
            <param name="model">Thông tin người quản lý.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.BulkAssignManager(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.BulkAssignManagerModel)">
            <summary>
            Gán người quản lý hàng loạt cho nhiều khách hàng.
            </summary>
            <param name="model">Thông tin gán hàng loạt.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.UpdateCustomerStatus(System.Int32,Lada.Framework.Data.Domains.Crm.CustomerStatus)">
            <summary>
            Cập nhật trạng thái khách hàng.
            </summary>
            <param name="id">Id của khách hàng.</param>
            <param name="status">Trạng thái khách hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.GetCoManagers(System.Int32)">
            <summary>
            Lấy danh sách đồng quản lý của khách hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.AddCoManager(System.Int32,System.Int32,System.String)">
            <summary>
            Thêm đồng quản lý cho khách hàng.
            Tự động bỏ qua nếu đã tồn tại hoặc nếu user là ManagerId chính.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.CustomerService.RemoveCoManager(System.Int32,System.Int32)">
            <summary>
            Xóa đồng quản lý khỏi khách hàng (soft delete).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ILeadService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Nullable{System.Int32})">
            <summary>
            Tìm kiếm lead
            </summary>
            <param name="param">Các tham số tìm kiếm.</param>
            <param name="picUserId">
            Nếu có giá trị, chỉ trả về lead do người này phụ trách hoặc chưa có ai phụ trách.
            Truyền null để xem toàn bộ lead (dành cho role quản lý).
            </param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ILeadService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.LeadModel)">
            <summary>
            Tạo/cập nhật đại lý
            </summary>
            <param name="model"></param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ILeadService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.LeadModel)">
            <summary>
            Tạo lead.
            </summary>
            <param name="model">Thông tin lead.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ILeadService.UpdateLeadStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.LeadStatusModel)">
            <summary>
            Cập nhật trạng thái của Lead
            </summary>
            <param name="model"></param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ILeadService.GetReviewModelById(System.Int32)">
            <summary>
            Lấy thông tin đánh giá lead theo ID.
            </summary>
            <param name="id">ID của lead.</param>
            <returns>Thông tin đánh giá lead.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.LeadService.UpdateLeadStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.LeadStatusModel)">
            <summary>
            Cập nhật trạng thái lead.
            </summary>
            <param name="id">Id của lead.</param>
            <param name="status">Trạng thái lead.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.LeadService.GetReviewModelById(System.Int32)">
            <summary>
            Lấy thông tin đánh giá lead theo ID.
            </summary>
            <param name="id">ID của lead.</param>
            <returns>Thông tin đánh giá lead.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Crm.IVatInfoService">
            <summary>
            Interface service quản lý thông tin xuất hóa đơn VAT của khách hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.IVatInfoService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy danh sách thông tin xuất hóa đơn VAT theo điều kiện tìm kiếm
            </summary>
            <param name="searchModel">Model tìm kiếm</param>
            <returns>Danh sách thông tin xuất hóa đơn VAT</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.IVatInfoService.GetByIdAsync(System.Int32)">
            <summary>
            Lấy thông tin chi tiết xuất hóa đơn VAT theo ID
            </summary>
            <param name="id">ID thông tin xuất hóa đơn VAT</param>
            <returns>Thông tin chi tiết xuất hóa đơn VAT</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.IVatInfoService.GetDefaultByCustomerIdAsync(System.Int32)">
            <summary>
            Lấy thông tin xuất hóa đơn VAT mặc định của khách hàng
            </summary>
            <param name="customerId">ID khách hàng</param>
            <returns>Thông tin xuất hóa đơn VAT mặc định</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.IVatInfoService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.VatInfoModel)">
            <summary>
            Tạo mới hoặc cập nhật thông tin xuất hóa đơn VAT
            </summary>
            <param name="model">Model tạo mới hoặc cập nhật</param>
            <returns>Kết quả tạo mới hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.IVatInfoService.DeleteAsync(System.Int32)">
            <summary>
            Xóa thông tin xuất hóa đơn VAT
            </summary>
            <param name="id">ID thông tin xuất hóa đơn VAT</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.IVatInfoService.SetAsDefaultAsync(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Đặt thông tin xuất hóa đơn VAT làm mặc định
            </summary>
            <param name="id">ID thông tin xuất hóa đơn VAT</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Crm.VatInfoService">
            <summary>
            Service quản lý thông tin xuất hóa đơn VAT của khách hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.VatInfoService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.VatInfoModel)">
            <summary>
            Cập nhật thông tin xuất hóa đơn VAT
            </summary>
            <param name="model">Model cập nhật</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Crm.VatInfoService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Crm.VatInfoModel)">
            <summary>
            Tạo mới thông tin xuất hóa đơn VAT
            </summary>
            <param name="model">Model tạo mới</param>
            <returns>Kết quả tạo mới</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.IDashboardService.GetWidgetLibrary(System.Int32)">
            <summary>Thư viện widget user hiện tại được dùng (server lọc theo nhóm quyền, Founder thấy tất cả)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.IDashboardService.GetLayout(System.Int32,System.String)">
            <summary>Bố cục dashboard của user; lần đầu chưa có thì tự tạo bố cục mặc định</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.IDashboardService.SaveLayout(System.Int32,System.String,Ladaer.BackEnd.Infrastructures.DTO.Dashboards.SaveLayoutModel)">
            <summary>Lưu toàn bộ bố cục — zone/widget vắng mặt trong model bị xoá mềm (last-write-wins)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.IDashboardService.GetWidgetData(System.Int32,System.String,System.Int32)">
            <summary>Dispatcher trung tâm: kiểm tra quyền → gọi provider theo Code → cache TTL ngắn</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.DashboardService.FilterUserSettings(System.String,System.String)">
            <summary>
            Chỉ giữ các khoá được khai báo trong SettingsSchema với UserEditable != false —
            đây là chốt server-side cho việc admin khoá tuỳ chọn.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.IWidgetDataProvider">
            <summary>
            Hợp đồng cắm một widget vào dashboard: mỗi widget = một provider trả data đúng envelope theo Type.
            Đăng ký DI bằng services.AddTransient&lt;IWidgetDataProvider, XxxProvider&gt;() — dispatcher resolve theo Code.
            Provider KHÔNG tự kiểm tra quyền và KHÔNG tự cache — dispatcher đã làm cả hai.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Dashboards.IWidgetDataProvider.Code">
            <summary>
            Trùng DashboardWidget.Code trong catalog
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.IWidgetDataProvider.GetDataAsync(Ladaer.BackEnd.Infrastructures.Services.Dashboards.WidgetDataContext)">
            <summary>
            Trả object data đúng envelope theo Type của widget:
            kpi      → { Value, Unit, Delta, DeltaPercent, CompareLabel, Series }
            chart    → { ChartKind, Categories, Series[{ Name, Data }] }
            list     → { Columns[{ Key, Label, Format }], Rows, TotalCount, MoreUrl }
            progress → { Value, Target, Percent, Label }
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.WidgetDataContext">
            <summary>
            Ngữ cảnh gọi provider — Settings đã merge DefaultSettings + cài đặt user, quyền đã được dispatcher kiểm tra
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.WidgetSettings">
            <summary>
            Đọc settings JSON đã merge, getter có kiểu kèm fallback
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.WidgetSettings.Parse(System.String,System.String)">
            <summary>
            Merge DefaultSettings của catalog với Settings riêng của user (user đè default, JSON hỏng thì bỏ qua phần đó)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.DemoRandomKpiProvider">
            <summary>
            Provider demo để nghiệm thu khung — trả KPI ngẫu nhiên theo khoảng thời gian đã chọn.
            Xoá cùng widget 'demo.random-kpi' (qua trang quản trị) khi đã có widget thật.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.DriverProductivityProvider">
            <summary>
            Widget danh sách "Năng suất lái xe" (vai trò Điều phối) — tái dùng
            sp_GetDriverProductivityReportByDate qua IDriverReportService.
            Chú ý: service này đọc khoá FromDate/ToDate (khác StartDate/EndDate của các report khác).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.FuelDailyCostProvider">
            <summary>
            Widget biểu đồ "Chi phí nhiên liệu theo ngày" (vai trò Tài chính) — tái dùng
            sp_GetFuelRefillReportByDate qua IFuelRefillReportService (mặc định chỉ tính phiếu Approved).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.InternalNewsLatestProvider">
            <summary>
            Widget danh sách "Bảng tin mới" (plan bảng tin §3.17, GĐ D): mấy bài đầu bảng tin của chính người xem, kèm chấm
            chưa đọc và số bài chưa đọc.
            </summary>
            <remarks>
            <para>
            Không có truy vấn riêng: gọi lại <see cref="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsService.FeedAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)"/> và
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsService.UnreadCountAsync(System.Int32)"/> — cùng luật đối tượng + phạm vi LADA / nhượng quyền, cùng thứ tự
            (ghim còn hạn trước, rồi mới đăng) với trang <c>/bang-tin</c>, nên widget không bao giờ lộ bài ngoài đối tượng.
            </para>
            <para>
            Ai thấy widget là việc của catalog (<c>DashboardWidgetPermission</c> — migration seed mở cho mọi nhóm quyền), provider
            không kiểm quyền lại. Dispatcher đệm dữ liệu 60 giây — đọc bài xong quay lại trang chủ có thể còn chấm.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.InternalNewsLatestProvider.WidgetCode">
            <summary>Mã widget, trùng <c>DashboardWidget.Code</c> trong migration seed</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.InternalNewsLatestProvider.FeedUrl">
            <summary>Trang Bảng tin — nơi "Xem tất cả" trỏ tới; từng bài là <c>/bang-tin/{Id}</c></summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiMyProgressProvider">
            <summary>
            Widget "KPI của tôi" (plan §3.7 mục 5): chỉ tiêu của chính người đang xem trong một kỳ tháng,
            kèm điểm tổng và danh sách từng chỉ tiêu.
            </summary>
            <remarks>
            <para>
            <b>Không có truy vấn riêng.</b> Tái dùng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiProgressService"/> — cùng engine với
            màn "Theo dõi KPI trong kỳ", nên số trên widget luôn khớp số của màn đó. Kèm theo đó là hai
            tính chất quan trọng được thừa hưởng miễn phí: kỳ ĐÃ CHỐT đọc thẳng snapshot
            <c>KpiResult</c> (nợ <c>KPI-8</c>), và một chỉ số lỗi nguồn không làm hỏng cả widget.
            </para>
            <para>
            <b>Phạm vi ép ở máy chủ.</b> Chủ thể luôn là <c>context.UserId</c> — không nhận từ settings
            của client — và <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiProgressService"/> vẫn tự áp <c>IKpiVisibilityResolver</c> lên
            trên. Xem KPI của chính mình thì ai cũng được, nên widget này không cần thêm lớp gác nào.
            </para>
            <para>
            <b>"Chưa có số" KHÔNG BAO GIỜ thành 0</b> (plan §3.9d). Hai chỗ dễ tặc lưỡi nhất, cùng nằm ở
            đây: (a) chưa được giao chỉ tiêu nào ⇒ <c>Value = null</c> chứ không phải 0 điểm; (b) mọi
            chỉ tiêu đều chưa có số ⇒ điểm cũng <c>null</c>, vì lúc đó tổng điểm 0 chỉ phản ánh việc
            chưa ai nhập số. Còn thiếu một phần thì điểm là <b>tạm tính</b> (<c>IsProvisional</c>) —
            widget phải nói rõ, không được trưng ra như điểm cuối cùng.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiMyProgressProvider.DefaultTopN">
            <summary>Số chỉ tiêu hiển thị mặc định — diện tích widget hẹp, phần còn lại xem ở màn theo dõi</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiMyProgressProvider.ProgressPageUrl">
            <summary>Màn theo dõi trong kỳ — nơi xem đầy đủ, khớp <c>routers/kpi.js</c></summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiMyProgressProvider.NoAccess(System.Int32,System.Int32)">
            <summary>
            Envelope khi người xem không có quyền đọc KPI — nói thẳng lý do thay vì trưng ô rỗng.
            </summary>
            <remarks>
            Ô rỗng ở đây sẽ bị đọc nhầm thành "tháng này chưa được giao chỉ tiêu", mà hai chuyện đó
            khác hẳn nhau — cùng họ với luật "chưa có số không phải 0" của chính widget này.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiMyProgressProvider.SortForNarrowSpace(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressItem})">
            <summary>
            Xếp chỉ tiêu "cần chú ý" lên trước: chưa có số, rồi % hoàn thành thấp nhất.
            </summary>
            <remarks>
            Widget cắt bớt dòng nên thứ tự quyết định cái gì bị giấu. Xếp theo mã chỉ số như màn
            theo dõi thì đúng chỗ cần biết lại rơi xuống dưới lằn cắt — người ta mở dashboard chính
            là để thấy chỗ đang có vấn đề.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiTeamProgressProvider">
            <summary>
            Widget "KPI đội của tôi" (plan §3.7 mục 5): tiến độ KPI của những chủ thể mà người xem được
            phép xem — cấp dưới trực tiếp và đơn vị mình quản lý — trong một kỳ tháng.
            </summary>
            <remarks>
            <para>
            <b>Phạm vi hoàn toàn do máy chủ quyết.</b> Provider gọi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiProgressService"/>
            KHÔNG truyền chủ thể, để chính <c>IKpiVisibilityResolver</c> (§3.6) quyết định tập trả về:
            cấp dưới trực tiếp theo <c>UserPreference.ManagerId</c> + đơn vị mình quản lý và đơn vị con
            của chúng; người có <c>Kpi.ViewAll</c> thì cả công ty. Widget không tự lọc theo
            <c>AgencyId</c> và không nhận chủ thể nào từ settings của client.
            </para>
            <para>
            <b>Bỏ chính mình ra khỏi "đội".</b> Tập xem được luôn gồm bản thân người xem; phần đó đã có
            widget <c>kpi.my-progress</c> lo. Quản lý không có cấp dưới nào sẽ thấy widget rỗng — đúng,
            chứ không phải hỏng.
            </para>
            <para>
            <b>"Chưa có số" không thành 0</b> (plan §3.9d): chủ thể mà mọi chỉ tiêu đều chưa có số thì
            <c>TotalScore = null</c> ⇒ renderer hiện "—". Trưng 0 điểm cho một người chỉ vì stored
            procedure chưa trả số là biến trục trặc kỹ thuật thành kết luận về con người. Chủ thể còn
            thiếu một phần thì điểm là tạm tính, cột "chưa có số" nói rõ còn mấy dòng.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiTeamProgressProvider.SortByAttention">
            <summary>Xếp chủ thể cần chú ý lên trước (mặc định)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiTeamProgressProvider.SortByScore">
            <summary>Xếp điểm cao lên trước</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiTeamProgressProvider.NoAccess(System.Int32,System.Int32)">
            <summary>
            Envelope khi người xem không có quyền đọc KPI — nói thẳng thay vì trưng bảng rỗng, vì
            bảng rỗng ở đây đọc nhầm thành "bạn không quản lý ai".
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiTeamProgressProvider.TeamRow">
            <summary>Một dòng của widget — kiểu tường minh để sắp xếp được, thay cho object ẩn danh</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiWidgetPeriod">
            <summary>
            Phần dùng chung của hai widget KPI: chọn kỳ theo tuỳ chọn người dùng và đặt nhãn kỳ.
            </summary>
            <remarks>
            Tách ra để hai provider không mỗi nơi một cách suy kỳ. Kỳ KPI là kỳ theo <b>giờ Việt Nam</b>
            (plan §8) nên mọi đường đều đi qua <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriod"/>, không đọc thẳng
            <c>DateTimeOffset.Now.Month</c>.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiWidgetPeriod.SettingKey">
            <summary>Khoá tuỳ chọn chọn kỳ, dùng chung cho cả hai widget</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiWidgetPeriod.Current">
            <summary>Kỳ đang chạy</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiWidgetPeriod.Previous">
            <summary>Kỳ tháng liền trước</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiWidgetPeriod.Resolve(Ladaer.BackEnd.Infrastructures.Services.Dashboards.WidgetSettings,System.DateTimeOffset)">
            <summary>
            Suy kỳ từ tuỳ chọn. Giá trị lạ quy về kỳ hiện tại thay vì ném lỗi — widget hỏng vì một
            chuỗi settings cũ là mất cả ô trên dashboard.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.KpiWidgetPeriod.Label(System.Int32,System.Int32)">
            <summary>Nhãn kỳ hiển thị cho người dùng, ví dụ "tháng 8/2026"</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.PricingFeeLookupProvider">
            <summary>
            Provider cho widget "Tra cứu cước phí" (<c>pricing.fee-lookup</c>) — chỉ trả danh mục loại hàng
            để dựng form, KHÔNG tính tiền.
            </summary>
            <remarks>
            <para>
            Khác mọi provider còn lại: widget này là công cụ tương tác, mỗi lượt tra là một input mới của
            người dùng chứ không phải một lần làm mới theo settings — nên tiền do chính component gọi
            <c>POST api/Price/CheckFee</c>, cùng endpoint trang <c>/tra-cuu-cuoc-phi</c> dùng, để hai nơi
            không bao giờ lệch con số.
            </para>
            <para>
            Việc trả sẵn danh mục ở đây có mục đích: component khỏi gọi <c>Category/GetTree</c>, tức là
            widget không kéo thêm role <c>Category.GetTree</c> vào tập quyền cần có để dùng được.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.PricingFeeLookupProvider.#ctor(Ladaer.BackEnd.Infrastructures.Services.Cms.ICategoryService)">
            <summary>
            Khởi tạo provider.
            </summary>
            <param name="categoryService">Service danh mục, dùng để lấy cây loại hàng vận chuyển.</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.PricingFeeLookupProvider.Code">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.PricingFeeLookupProvider.GetDataAsync(Ladaer.BackEnd.Infrastructures.Services.Dashboards.WidgetDataContext)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SalesPersonalRevenueProvider">
            <summary>
            Widget KPI "Doanh số cá nhân" (vai trò Kinh doanh) — tái dùng sp_GetOrderRevenueStatisticsBySale
            qua ISaleReportService, rồi tự lọc lấy đúng dòng của người đang xem.
            </summary>
            <remarks>
            Từ 2026-09-07 báo cáo trả doanh số của cả nhân sự trong phạm vi quản lý (bản thân + cấp dưới
            + nhân sự chi nhánh mình quản lý), nên widget này KHÔNG được cộng thẳng mọi dòng trả về — với
            một quản lý thì "cá nhân" sẽ hoá thành doanh số cả đội.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchIndexSummaryProvider">
            <summary>
            Widget "Đồng bộ tìm kiếm" trên trang chủ — ba con số trả lời câu hỏi thường trực của người làm
            nội dung: Google đã index bao nhiêu trang, còn bao nhiêu chưa, và bao nhiêu trang vừa sửa mà
            Google chưa đọc lại.
            </summary>
            <remarks>
            <para>
            <b>Vì sao envelope là <c>list</c> chứ không phải <c>kpi</c>.</b> Kế hoạch ban đầu xếp widget này
            vào loại <c>kpi</c>, nhưng renderer <c>KpiWidget.vue</c> chỉ hiện được đúng <b>một</b> giá trị
            <c>Value</c>, trong khi widget cần ba. Ép ba số vào <c>kpi</c> thì phải đăng ký một renderer
            riêng theo mã widget — đúng thứ kế hoạch cấm ở cùng đoạn, vì nó phá luật "một loại một renderer"
            của cả khung dashboard. Chọn <c>list</c> giữ được đủ ba số mà vẫn dùng envelope chuẩn, không
            phải đụng vào registry của frontend.
            </para>
            <para>
            <b>Đếm theo <c>Verdict</c>, không theo <c>CoverageState</c>.</b> <c>Verdict</c> là mã ổn định
            (<c>PASS</c> / <c>NEUTRAL</c> / <c>FAIL</c>…), còn <c>CoverageState</c> là câu Google viết cho
            người đọc và đổi theo ngôn ngữ của tài khoản. Nhóm theo câu chữ thì một hôm Google đổi cách diễn
            đạt là con số trên trang chủ nhảy mà không ai sửa gì — <c>CoverageState</c> chỉ để <b>đọc</b>.
            </para>
            <para>
            <b>Hai dòng đầu chỉ đếm URL đã kiểm.</b> URL chưa từng kiểm không có <c>Verdict</c> nên không
            rơi vào dòng nào — cố ý, để số "Chưa index" ở đây bằng đúng <c>TotalCount</c> của widget
            <c>search.not-indexed</c> đứng cạnh nó trên cùng trang chủ; hai widget cạnh nhau mà lệch số là
            thứ người dùng phát hiện đầu tiên. Số "chưa kiểm" có ô riêng ở màn <c>/dong-bo-tim-kiem</c>.
            Hệ quả: tổng hai dòng đầu có thể nhỏ hơn <c>TotalCount</c> (tổng URL trong hàng tồn kho).
            </para>
            <para>
            <b>Không tự kiểm quyền và không tự cache</b> — catalog <c>DashboardWidgetPermission</c> đã gác
            trước khi dispatcher gọi tới đây, và dispatcher cũng là nơi cache (hợp đồng
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.IWidgetDataProvider"/>).
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchIndexSummaryProvider.WidgetCode">
            <summary>Mã widget, trùng <c>DashboardWidget.Code</c> trong migration seed</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchIndexSummaryProvider.SearchConsoleUrl">
            <summary>Đường dẫn màn "Đồng bộ tìm kiếm" — nơi liên kết "Xem tất cả" trỏ tới</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchIndexSummaryProvider.VerdictPass">
            <summary>
            Kết luận "đã index" theo Google. Giữ nguyên chuỗi Google trả thay vì quy về enum vì Google
            thêm giá trị mới mà không báo trước (xem <c>SearchIndexStatus.Verdict</c>).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchIndexSummaryProvider.TrackedEngine">
            <summary>
            Chỉ Google có dữ liệu ở giai đoạn này. Bảng trạng thái vốn trung lập với công cụ tìm kiếm
            nên thêm Bing/IndexNow về sau chỉ là đổi hằng này (hoặc đọc từ settings), không phải viết lại.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchIndexSummaryProvider.HistoryWindowDays">
            <summary>Bề rộng cửa sổ so sánh của cột "7 ngày"</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchIndexSummaryProvider.UnknownText">
            <summary>
            Giá trị hiện khi <b>không biết</b>, khác hẳn với số 0 nghĩa là "biết, và bằng không".
            Trùng ký tự mà <c>ListWidget.vue</c> dùng cho ô rỗng nên nhìn liền mạch với các cột khác.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchIndexSummaryProvider.BuildColumns">
            <summary>
            Dựng cột một chỗ duy nhất để nhánh "chưa có dữ liệu" và nhánh thường không bao giờ lệch nhau.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchIndexSummaryProvider.ReadWeeklyDeltasAsync(System.Nullable{System.Int32},System.Nullable{System.Int32})">
            <summary>
            Dựng lại số "đã index" / "chưa index" tại thời điểm <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchIndexSummaryProvider.HistoryWindowDays"/> ngày
            trước rồi trả về phần chênh lệch dưới dạng chuỗi có dấu.
            </summary>
            <remarks>
            <para>
            <b>Chưa đủ lịch sử thì trả <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchIndexSummaryProvider.UnknownText"/>, không trả 0.</b> Bảng
            <c>SearchIndexStatusHistory</c> chỉ ghi khi trạng thái thật sự đổi, nên trên một hệ mới chạy
            (dev hiện có đúng một ngày dữ liệu) không có dòng nào cũ hơn mốc cắt. Hiện "0" ở đó đọc ra
            thành "một tuần qua không có gì thay đổi" — một câu khẳng định mà mình không có cơ sở để nói.
            </para>
            <para>
            <b>Dòng "Vừa sửa chưa báo" không có số so sánh.</b> Cờ đó là phép so giữa
            <c>SearchUrl.SitemapLastmod</c> và <c>SearchIndexStatus.LastCrawlTime</c>, mà bảng lịch sử chỉ
            giữ mốc thu thập chứ không giữ mốc sitemap. Dựng lại bằng mốc sitemap của <b>hôm nay</b> sẽ
            cho kết quả sai ở đúng những URL vừa đổi lastmod trong tuần — tức đúng nhóm mà dòng này nói
            về. Một con số sai ở chỗ nhạy cảm nhất còn tệ hơn không có con số nào.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchIndexSummaryProvider.FormatDelta(System.Int32,System.Int32)">
            <summary>
            Chênh lệch có dấu: dấu cộng phải hiện rõ vì "+5 trang được index" và "-5 trang rơi khỏi
            index" là hai tin trái ngược nhau mà nếu thiếu dấu thì nhìn giống hệt.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchNotIndexedProvider">
            <summary>
            Widget "Trang chưa được index" trên trang chủ — vài URL Google chưa index kèm lý do Google đưa
            ra, để người làm nội dung biết phải mở trang nào trước.
            </summary>
            <remarks>
            <para>
            <b>Lỗi máy chủ đứng đầu danh sách.</b> Một URL có <c>PageFetchState = SERVER_ERROR</c> nghĩa là
            Google vào trang và nhận 5xx — hỏng nặng hơn hẳn "đã thu thập nhưng chưa index", và là loại hỏng
            duy nhất mà sửa được ngay. Đúng dấu hiệu này đã bắt được sự cố thật ngày 15/09/2026, nên nó được
            ghim lên đầu thay vì trộn lẫn theo thứ tự bảng chữ cái.
            </para>
            <para>
            <b>Chọn dòng theo <c>Verdict</c>, hiện lý do bằng <c>CoverageState</c>.</b> <c>Verdict</c> là mã
            ổn định nên lọc được; <c>CoverageState</c> là câu Google viết cho người đọc (bản tiếng Việt:
            "Đã thu thập dữ liệu…", "Lỗi máy chủ (5xx)"…) nên chỉ dùng để <b>hiển thị</b>, không bao giờ để
            nhóm hay đếm — Google đổi cách diễn đạt lúc nào cũng được.
            </para>
            <para>
            <b>URL chưa từng kiểm không nằm ở đây.</b> Không có dòng trạng thái thì không có <c>Verdict</c>,
            và "chưa biết" khác "biết là chưa index". Số đó có ô riêng ở màn <c>/dong-bo-tim-kiem</c>.
            </para>
            <para>
            <b>Không tự kiểm quyền và không tự cache</b> — catalog <c>DashboardWidgetPermission</c> đã gác
            trước khi dispatcher gọi tới đây, và dispatcher cũng là nơi cache (hợp đồng
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.IWidgetDataProvider"/>).
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchNotIndexedProvider.WidgetCode">
            <summary>Mã widget, trùng <c>DashboardWidget.Code</c> trong migration seed</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchNotIndexedProvider.SearchConsoleUrl">
            <summary>Đường dẫn màn "Đồng bộ tìm kiếm" — nơi liên kết "Xem tất cả" trỏ tới</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchNotIndexedProvider.VerdictPass">
            <summary>Kết luận "đã index" theo Google — mọi thứ khác nó là ứng viên của widget này</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchNotIndexedProvider.ServerErrorFetchState">
            <summary>Google vào được trang nhưng máy chủ trả 5xx — loại hỏng nặng nhất, ghim lên đầu</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.SearchNotIndexedProvider.TrackedEngine">
            <summary>
            Chỉ Google có dữ liệu ở giai đoạn này. Bảng trạng thái vốn trung lập với công cụ tìm kiếm
            nên thêm Bing/IndexNow về sau chỉ là đổi hằng này, không phải viết lại truy vấn.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.TruckMaintenanceDueProvider">
            <summary>
            Widget danh sách "Xe cần bảo dưỡng" (plan bảo dưỡng xe tải §3.5, Q7): những xe trong phạm vi
            chi nhánh của người xem đang có bộ phận quá hạn hoặc sắp đến hạn, xếp xe nặng nhất lên đầu.
            </summary>
            <remarks>
            <para>
            Không có truy vấn riêng: tái dùng <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckConditionService.SearchFleet(Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)"/> — cùng engine
            realtime với màn "Tình trạng đội xe", nên số trên widget luôn khớp số của màn đó (và cố ý
            có thể lệch với màn tra cứu cảnh báo do job ghi trong ngày đầu, xem plan §3.3).
            </para>
            <para>
            Phạm vi dữ liệu ép ở đây bằng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceAgencyScopeResolver"/> theo
            <c>UserId</c> mà dispatcher truyền vào — không nhận chi nhánh từ settings của client.
            Ai được thấy widget là việc của catalog (<c>DashboardWidgetPermission</c>), provider không
            kiểm quyền lại (hợp đồng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.IWidgetDataProvider"/>).
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.TruckMaintenanceDueProvider.WidgetCode">
            <summary>Mã widget, trùng <c>DashboardWidget.Code</c> trong migration seed</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.TruckMaintenanceDueProvider.FleetConditionUrl">
            <summary>Đường dẫn màn "Tình trạng đội xe" — nơi liên kết "Xem tất cả" trỏ tới</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Dashboards.Providers.TruckMaintenanceDueProvider.FleetPageSize">
            <summary>
            Số xe tối đa nạp một lượt để tính. Đội xe hiện 26 chiếc; nếu vượt ngưỡng này thì cờ
            <c>Truncated</c> trong data bật lên để widget nói rõ là số chưa đủ, thay vì im lặng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Dashboards.WidgetTimeRange">
            <summary>
            Preset khoảng thời gian chuẩn dùng chung cho mọi widget:
            today / yesterday / this_week / this_month / this_quarter / this_year / last_7d / last_30d.
            End là exclusive (nửa khoảng [Start, End)).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.DriverApp.IDriverAppOrderService">
            <summary>
            Interface for Driver App order service.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.IDriverAppOrderService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Searches for orders based on the provided parameters.
            </summary>
            <param name="param">Search parameters.</param>
            <param name="userId">User ID.</param>
            <returns>Search results.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.IDriverAppOrderService.SearchActiveOrders(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm đơn hàng đang hoạt động (đang lấy, lấy thất bại, đang giao, giao thất bại).
            </summary>
            <param name="param">Tham số tìm kiếm.</param>
            <param name="userId">ID người dùng.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.IDriverAppOrderService.GetById(System.Int32,System.Int32)">
            <summary>
            Gets an order by its ID.
            </summary>
            <param name="id">Order ID.</param>
            <param name="userId">User ID.</param>
            <returns>Order item.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.IDriverAppOrderService.Pickup(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppPickupModel)">
            <summary>
            Picks up an order.
            </summary>
            <param name="model">Pickup model.</param>
            <returns>Order track result.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.IDriverAppOrderService.PickupFail(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailModel)">
            <summary>
            Pickup failed.
            </summary>
            <param name="model">Fail model.</param>
            <returns>Order track result.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.IDriverAppOrderService.Delivery(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppDeliveryModel)">
            <summary>
            Delivery successful.
            </summary>
            <param name="model">Delivery model.</param>
            <returns>Order track result.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.IDriverAppOrderService.DeliveryFail(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailModel)">
            <summary>
            Delivery failed.
            </summary>
            <param name="model">Fail model.</param>
            <returns>Order track result.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.IDriverAppOrderService.Return(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppReturnModel)">
            <summary>
            Return successful.
            </summary>
            <param name="model">Return model.</param>
            <returns>Order track result.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.IDriverAppOrderService.ReturnFail(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailModel)">
            <summary>
            Return failed.
            </summary>
            <param name="model">Fail model.</param>
            <returns>Order track result.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.IDriverAppOrderService.ReorderOrders(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.ReorderModel,System.Int32)">
            <summary>
            Sắp xếp thứ tự hiển thị đơn hàng.
            </summary>
            <param name="model">Danh sách đơn hàng với thứ tự mới.</param>
            <param name="userId">ID người dùng.</param>
            <returns>Kết quả sắp xếp.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService">
            <summary>
            Implementation of the Driver App order service.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService._orderTrackRepository">
            <summary>
            Dùng để ghép ảnh của đơn với sự kiện sinh ra nó (chi tiết đơn trên app nhóm ảnh theo track).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService._locationRepository">
            <summary>
            Dùng để tra toạ độ tâm phường/xã cho địa chỉ chưa ghim (bản đồ đơn hàng của app).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService.#ctor(Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService,Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.OrderOps},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.OrderFin},Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderTrackService,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.Order},Lada.Framework.Infrastructures.Services.IUnifiedMediaService,System.Data.IDbConnection,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Medias.Media},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.OrderTrack},Microsoft.AspNetCore.Identity.UserManager{Lada.Framework.Data.Domains.Identity.User},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Categories.Location},Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService)">
            <summary>
            Initializes a new instance of the <see cref="T:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService"/> class.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Searches for orders based on the provided parameters.
            </summary>
            <param name="param">Search parameters.</param>
            <param name="userId">User ID.</param>
            <returns>Search results.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService.SearchActiveOrders(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm đơn hàng đang hoạt động của tài xế: đang lấy / lấy thất bại, đang giao / giao thất bại,
            đang trả hàng, và đơn trung chuyển (đã xuất kho, đang trên xe tới bưu cục kế tiếp).
            </summary>
            <param name="param">
            Tham số tìm kiếm. <c>PredicateObject.Group</c> (pickup / delivery / return / transit) thu hẹp về một
            nhóm; bỏ trống là tất cả. Xem <see cref="T:Ladaer.BackEnd.Infrastructures.Helpers.DriverActiveOrderFilter"/>.
            </param>
            <param name="userId">ID người dùng.</param>
            <returns>Kết quả tìm kiếm.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService.FillPickupCollectAsync(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Operations.OpsOrderItem},System.Int32)">
            <summary>
            Ví bưu cục v2 (plan §3.8.2): điền ô "Số tiền đã thu" cho đơn đang đi lấy — máy chủ quyết, app chỉ đọc cờ. Lái xe không thuộc
            bưu cục nhượng quyền bật ví → không đổi gì.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService.GetById(System.Int32,System.Int32)">
            <summary>
            Gets an order by its ID.
            </summary>
            <param name="id">Order ID.</param>
            <param name="userId">User ID.</param>
            <returns>Order item.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService.LoadMediasByOrderAsync(System.Collections.Generic.List{System.Int32})">
            <summary>
            Nạp ảnh của nhiều đơn trong một lượt (ba truy vấn cố định, không phải mỗi đơn một lượt), gom theo đơn.
            </summary>
            <remarks>
            Toàn bộ ảnh của đơn, KHÔNG lọc theo người chụp như Search(lịch sử): lái xe giao cần xem ảnh lúc lấy
            hàng của người khác, lái xe trung chuyển cần xem ảnh nhập/xuất kho. Id của OrderOps trùng Id của Order
            (khoá chia sẻ) nên nhận thẳng Id của <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Items.Business.Operations.OpsOrderItem"/>.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService.Pickup(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppPickupModel)">
            <summary>
            Picks up an order.
            </summary>
            <param name="model">Pickup model.</param>
            <returns>Order track result.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService.PickupFail(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailModel)">
            <summary>
            Pickup failed.
            </summary>
            <param name="model">Fail model.</param>
            <returns>Order track result.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService.Delivery(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppDeliveryModel)">
            <summary>
            Delivery successful.
            </summary>
            <param name="model">Delivery model.</param>
            <returns>Order track result.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService.DeliveryFail(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailModel)">
            <summary>
            Delivery failed.
            </summary>
            <param name="model">Fail model.</param>
            <returns>Order track result.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService.Return(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppReturnModel)">
            <summary>
            Return successful.
            </summary>
            <param name="model">Return model.</param>
            <returns>Order track result.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService.ReturnFail(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DriverAppFailModel)">
            <summary>
            Return failed.
            </summary>
            <param name="model">Fail model.</param>
            <returns>Order track result.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService.ReorderOrders(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.ReorderModel,System.Int32)">
            <summary>
            Sắp xếp thứ tự hiển thị đơn hàng.
            </summary>
            <param name="model">Danh sách đơn hàng với thứ tự mới.</param>
            <param name="userId">ID người dùng.</param>
            <returns>Kết quả sắp xếp.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppOrderService.ValidateUpdateStatus(Lada.Framework.Data.Enums.OrderStatus,Lada.Framework.Data.Enums.OrderPhysicalStatus,Lada.Framework.Data.Enums.OrderStatus,Lada.Framework.Data.Enums.OrderPhysicalStatus)">
            <summary>
            Validates the update status of an order.
            </summary>
            <param name="currentStatus">Current order status.</param>
            <param name="currentPhysicalStatus">Current physical status.</param>
            <param name="newStatus">New order status.</param>
            <param name="newPhysicalStatus">New physical status.</param>
            <returns>True if the update is valid, otherwise false.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppService.LoadAttendanceInfo(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DashboardModel,System.Int32)">
            <summary>
            Lấy thông tin chấm công của người dùng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppService.LoadCurrentTruckInfo(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.DashboardModel,System.Int32)">
            <summary>
            Lấy thông tin xe đang phụ trách
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverAppService.GetLatestTruckOdo(System.Int32,System.Int32)">
            <summary>
            Lấy ODO gần nhất của xe từ các hoạt động (chấm công hoặc bàn giao xe)
            </summary>
            <param name="truckId">ID xe tải</param>
            <param name="userId">ID người dùng</param>
            <returns>ODO gần nhất</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.DriverApp.IDriverFinService">
            <summary>
            Interface cho dịch vụ quản lý tài chính của lái xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.IDriverFinService.GetDriverFinancialInfo(System.Int32)">
            <summary>
            Lấy thông tin tài chính của lái xe
            </summary>
            <param name="userId">ID của lái xe</param>
            <returns>Thông tin tài chính của lái xe</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.IDriverFinService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm danh sách đơn hàng tài chính của lái xe có phân trang
            </summary>
            <param name="param">Tham số tìm kiếm và phân trang</param>
            <param name="userId">ID của lái xe</param>
            <returns>Kết quả tìm kiếm có phân trang</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverFinService">
            <summary>
            Dịch vụ quản lý tài chính của lái xe
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverFinService._franchiseLedger">
            <summary>
            Ví bưu cục v2 (V-40): lái xe bưu cục nhượng quyền bật ví không nộp LADA tiền của đơn Ví ghi — màn "tiền cần nộp" bỏ các đơn
            đó, cùng luật phiếu chuyển khoản (<c>DriverTransferSlipService</c>). Null khi dựng không có ví (test cũ).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverFinService.GetDriverFinancialInfo(System.Int32)">
            <summary>
            Lấy thông tin tài chính của lái xe
            </summary>
            <param name="userId">ID của lái xe</param>
            <returns>Thông tin tài chính của lái xe</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverFinService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm danh sách đơn hàng tài chính của lái xe có phân trang
            Bao gồm cả đơn hàng mà lái xe đã thu tiền nhưng đã nộp lại
            </summary>
            <param name="param">Tham số tìm kiếm và phân trang</param>
            <param name="userId">ID của lái xe</param>
            <returns>Kết quả tìm kiếm có phân trang</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverFinService.WalletHolderAsync(System.Int32)">
            <summary>Lái xe thuộc bưu cục nhượng quyền đang bật ví (V-05) — null khi không phải hoặc dựng không có ví.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverFinService.IsWalletOrder(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletHolder,System.Nullable{System.DateTimeOffset})">
            <summary>
            Đơn do Ví ghi với người cầm tiền này — cùng mốc SQL của <c>DriverTransferSlipService</c>: tạo từ 00:00 giờ VN ngày bắt đầu ghi Ví
            (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletHolder.Cutoff"/>), không có ngày bắt đầu = mọi đơn; người không thuộc bưu cục bật ví = không đơn nào.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.DriverApp.DriverFinService.EnrichAddressesAsync(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.DriverApp.DriverFinOrderItem})">
            <summary>
            Enrich thông tin địa chỉ đầy đủ (phường/quận/tỉnh) cho danh sách DriverFinOrderItem
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Email.IEmailAccountService">
            <summary>
            Service quản lý tài khoản gửi email (CRUD + đặt mặc định + gửi thử).
            Secret (Password/SecretKey) được mã hóa qua <see cref="T:Lada.Framework.Infrastructures.Services.ISecretProtector"/> trước khi lưu.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Email.EmailAccountService">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Email.EmailAccountService.ClearOtherDefaultsAsync(System.Int32,System.Int32,System.String,System.DateTimeOffset)">
            <summary>Bỏ cờ mặc định của tất cả tài khoản khác (chỉ 1 mặc định toàn hệ thống).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Email.IEmailLogService">
            <summary>
            Service đọc nhật ký gửi email + báo cáo tổng hợp (chỉ đọc, phục vụ trang giám sát).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Email.EmailLogService">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Email.EmailLogService.EnrichAccountNamesAsync(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.Email.EmailLogItem})">
            <summary>Điền tên tài khoản gửi cho danh sách log (1 truy vấn gộp).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ErrorReports.IErrorReportService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm báo lỗi
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Danh sách báo lỗi</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ErrorReports.IErrorReportService.SearchMine(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm báo lỗi do chính người dùng hiện tại gửi.
            Ai đăng nhập cũng gọi được, nên phạm vi dữ liệu phải bị chặn bằng <paramref name="userId"/>.
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <param name="userId">ID người dùng hiện tại</param>
            <returns>Danh sách báo lỗi của chính người dùng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ErrorReports.IErrorReportService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo mới báo lỗi
            </summary>
            <param name="model">Thông tin báo lỗi</param>
            <param name="currentUser">Thông tin người dùng hiện tại</param>
            <returns>Kết quả tạo báo lỗi</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ErrorReports.IErrorReportService.GetById(System.Int32)">
            <summary>
            Lấy chi tiết báo lỗi
            </summary>
            <param name="id">ID báo lỗi</param>
            <returns>Chi tiết báo lỗi</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ErrorReports.IErrorReportService.GetMineById(System.Int32,System.Int32)">
            <summary>
            Lấy chi tiết một báo lỗi do chính người dùng hiện tại gửi.
            Không tìm thấy hoặc không phải của mình đều trả cùng một thông báo.
            </summary>
            <param name="id">ID báo lỗi</param>
            <param name="userId">ID người dùng hiện tại</param>
            <returns>Chi tiết báo lỗi</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ErrorReports.IErrorReportService.UpdateStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.ErrorReports.ErrorReportUpdateModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Cập nhật trạng thái báo lỗi (dành cho admin)
            </summary>
            <param name="model">Thông tin cập nhật</param>
            <param name="currentUser">Thông tin người dùng hiện tại</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ErrorReports.IErrorReportService.Delete(System.Int32)">
            <summary>
            Xóa báo lỗi
            </summary>
            <param name="id">ID báo lỗi</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ErrorReports.IErrorReportService.GetByStatus(Lada.Framework.Data.Enums.ErrorReportStatus,System.Int32,System.Int32)">
            <summary>
            Lấy danh sách báo lỗi theo trạng thái
            </summary>
            <param name="status">Trạng thái</param>
            <param name="pageIndex">Trang hiện tại</param>
            <param name="pageSize">Kích thước trang</param>
            <returns>Danh sách báo lỗi</returns>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.ErrorReports.ErrorReportService.StatusChangedNotification">
            <summary>
            SystemName của nhóm thông báo báo cho người gửi biết báo lỗi đã đổi trạng thái.
            Seed bằng migration M202608161510 — đổi chuỗi này là thông báo im lặng ngừng gửi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ErrorReports.ErrorReportService.SearchInternal(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Nullable{System.Int32})">
            <summary>
            Thân chung của hai luồng tìm kiếm.
            <paramref name="ownerUserId"/> khác null thì chỉ trả báo lỗi do chính người đó gửi — đây là
            lớp chặn duy nhất của endpoint SearchMine (chỉ yêu cầu đăng nhập, không đòi role), nên
            điều kiện lọc này không được phép rơi ra ngoài phương thức.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ErrorReports.ErrorReportService.ToItem(Lada.Framework.Data.Domains.ErrorReports.ErrorReport)">
            <summary>
            Dựng item hiển thị từ entity. Dùng chung cho tìm kiếm, chi tiết và lọc theo trạng thái
            để bốn chỗ không trôi lệch nhau mỗi lần thêm trường.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ErrorReports.ErrorReportService.GetImageUrlSync(System.String)">
            <summary>
            Wrapper đồng bộ cho GetImageUrlAsync, dùng trong LINQ projection
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ErrorReports.ErrorReportService.NotifyReporterAsync(Lada.Framework.Data.Domains.ErrorReports.ErrorReport,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Báo cho người gửi biết báo lỗi của họ vừa đổi trạng thái.
            Lỗi gửi thông báo bị nuốt có chủ đích: trạng thái đã ghi xong, không được vì hỏng
            thông báo mà trả về lỗi cho người đang xử lý.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.ErrorReports.ErrorReportService.RutGonMoTa(System.String,System.Int32)">
            <summary>
            Cắt bớt mô tả để nhét vừa một dòng nội dung thông báo.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IBankAccountService">
            <summary>
            Interface cho service quản lý tài khoản ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IBankAccountService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm tài khoản ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IBankAccountService.GetById(System.Int32)">
            <summary>
            Lấy chi tiết tài khoản ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IBankAccountService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankAccountModel)">
            <summary>
            Tạo hoặc cập nhật tài khoản ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IBankAccountService.Delete(System.Int32)">
            <summary>
            Xóa tài khoản ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IBankAccountService.SearchTransactions(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm giao dịch ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IBankAccountService.ImportBankStatement(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BankStatementImportModel,System.Int32,System.String)">
            <summary>
            Import sao kê ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IBankAccountService.GetActiveAccounts">
            <summary>
            Lấy danh sách tài khoản ngân hàng đang hoạt động
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IBankAccountService.SearchImportHistory(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm lịch sử import
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IBankAccountService.UpdateBalance(System.Int32,System.Decimal)">
            <summary>
            Cập nhật số dư tài khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IBankAccountService.UpdateBalance(System.Int32,System.Decimal,System.Int32,System.String)">
            <summary>
            Cập nhật số dư tài khoản với thông tin user
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IBankAccountService.GetDepositBankAccountForDriver(System.Nullable{System.Decimal},System.String)">
            <summary>
            Lấy tài khoản ngân hàng thu COD để hiển thị QR code cho lái xe nộp tiền
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.BankAccountService">
            <summary>
            Service quản lý tài khoản ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.BankAccountService.GetFileBytesAsync(Microsoft.AspNetCore.Http.IFormFile)">
            <summary>
            Helper method để convert IFormFile thành byte array
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.BankAccountService.GetDepositBankAccountForDriver(System.Nullable{System.Decimal},System.String)">
            <summary>
            Lấy tài khoản ngân hàng thu COD (CanCollectCod = true) để hiển thị QR cho lái xe
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.DepositBankAccountResult">
            <summary>
            Kết quả trả về thông tin tài khoản ngân hàng thu COD + VietQR URL
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IBankStatementParser">
            <summary>
            Interface cho service parse sao kê ngân hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.BankStatementParser">
            <summary>
            Service parse sao kê ngân hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IBankSpecificParser">
            <summary>
            Interface cho parser riêng từng ngân hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.VPBankParser">
            <summary>
            Parser cho VPBank
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VPBankParser.TruncateString(System.String,System.Int32)">
            <summary>
            Truncate string to specified length
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.TechcombankParser">
            <summary>
            Parser cho Techcombank
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.TechcombankParser.TruncateString(System.String,System.Int32)">
            <summary>
            Truncate string to specified length
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.ShinhanBankParser">
            <summary>
            Parser cho Shinhan Bank
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.HDBankParser">
            <summary>
            Parser cho HDBank
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.HDBankParser.ParseTransactionText(System.String)">
            <summary>
            Parse multi-line transaction text từ HDBank
            Format: 
            "Loại giao dịch: TTOAN THE TD - ATM/POS/EBANK
             So giao dich: 93297
             Noi dung: THANH TOAN DU NO THE TIN DUNG HDBANK 9439, 7939"
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.HDBankParser.HDBankTransactionInfo">
            <summary>
            Class lưu thông tin giao dịch HDBank đã parse
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.VietinBankParser">
            <summary>
            Parser cho VietinBank
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.StringExtensions">
            <summary>
            Truncate string to specified length
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.HeldAmounts">
            <summary>
            Số tiền một người đang cầm trên một đơn, tách theo ba loại tiền.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.HeldAmounts.#ctor(System.Decimal,System.Decimal,System.Decimal)">
            <summary>
            Số tiền một người đang cầm trên một đơn, tách theo ba loại tiền.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.CashCollectPlan">
            <summary>
            Kết quả kiểm một lượt thu tiền ở màn Quỹ: hoặc một lỗi, hoặc danh sách đơn với số tiền
            <b>do máy chủ tính</b>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Finances.CashCollectPlan.Orders">
            <summary>Đơn sẽ thu, số tiền lấy từ <c>OrderFin</c> chứ không phải từ client.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.CashCollectRules">
            <summary>
            Luật "ai đang cầm khoản tiền nào" dùng chung cho màn Quỹ (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Finances.CashierService"/>) và
            phiếu chuyển khoản của lái xe (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Finances.DriverTransferSlipService"/>).
            </summary>
            <remarks>
            <para>
            Hàm thuần, tách khỏi hai service vì cả hai ghi tiền thẳng qua repository/Dapper, không có
            cách nào kiểm chứng luật bằng test nếu luật nằm lẫn trong đó.
            </para>
            <para>
            Trước bản này <c>CollectCashier</c> tin hoàn toàn vào request: nhận mọi mã đơn, lấy số tiền
            client gửi, ghi đè người cầm và mức tiền vô điều kiện. Đo trên DB dev (3.228 phiếu thu,
            20/08/2025 → 20/08/2026): 17 khoản bị thu hai lần, 10.880.000 đ ghi thừa vào ví — gồm 5 khoản
            phí giao ngày 10/07/2026 vừa thu tiền mặt ở màn Quỹ vừa được duyệt qua phiếu chuyển khoản.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Finances.CashCollectRules.MaxCodesInMessage">
            <summary>Số mã đơn tối đa nêu trong thông báo lỗi — đủ để người thu đối chiếu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.CashCollectRules.HeldBy(Lada.Framework.Data.Domains.Orders.OrderFin,System.Int32,Lada.Framework.Data.Enums.OrderFinEnum.OrderFeeStage,Lada.Framework.Data.Enums.OrderFinEnum.OrderCodStage)">
            <summary>
            Tiền <paramref name="holderUserId"/> đang cầm trên đơn mà một người thu ở mức
            <paramref name="collectorFeeStage"/>/<paramref name="collectorCodStage"/> được phép nhận.
            </summary>
            <remarks>
            Cùng điều kiện với cột "đang cầm" của <c>sp_GetCashierBalance</c> và
            <c>sp_GetCashierOrders</c> — thứ người thu nhìn thấy phải đúng là thứ máy chủ cho thu.
            Tiền <see cref="F:Lada.Framework.Data.Enums.OrderFinEnum.OrderCodStage.InTransit"/> (lái xe đã lập phiếu chuyển khoản, đang chờ duyệt)
            bị loại: nó đã thuộc về phiếu, thu thêm bằng tiền mặt là ghi hai lần.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.CashCollectRules.PlanCollect(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CollectCashierOrderModel},System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.Orders.OrderFin},System.Int32,Lada.Framework.Data.Enums.OrderFinEnum.OrderFeeStage,Lada.Framework.Data.Enums.OrderFinEnum.OrderCodStage,System.Decimal)">
            <summary>
            Kiểm một lượt thu tiền ở màn Quỹ trên trạng thái <c>OrderFin</c> hiện tại.
            </summary>
            <param name="requested">Danh sách đơn người thu nhìn thấy khi mở hộp thoại.</param>
            <param name="current">Bản <c>OrderFin</c> đọc lại trong transaction, sau khi đã giữ khoá.</param>
            <param name="fromUserId">Người nộp tiền.</param>
            <param name="collectorFeeStage">Mức phí của người thu (chi nhánh hay công ty).</param>
            <param name="collectorCodStage">Mức COD của người thu.</param>
            <param name="cashAmount">Phần tiền mặt người thu nhập; phần còn lại là chuyển khoản.</param>
            <remarks>
            <para>
            Mỗi khoản client gửi (lớn hơn 0) phải khớp <b>đúng</b> khoản người nộp đang cầm. Lệch một
            khoản là từ chối cả phiếu: người thu đã đếm tiền mặt theo tổng họ nhìn thấy, âm thầm thu một
            số khác là tạo chênh lệch két.
            </para>
            <para>
            Khoản client không gửi thì để nguyên ở người nộp — ví dụ đơn lái xe vừa thu thêm sau lúc mở
            hộp thoại. Thu thiếu không làm lệch sổ; thu thừa mới làm.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.CashCollectRules.VerifySlip(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Finance.DriverTransferSlipOrder},System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.Orders.OrderFin},System.Int32)">
            <summary>
            Mã các đơn của phiếu chuyển khoản không còn khớp với tiền lái xe đang giữ ở trạng thái chờ
            chuyển khoản. Rỗng nghĩa là duyệt được.
            </summary>
            <remarks>
            Phiếu chụp số tiền lúc lái xe tạo. Trong lúc phiếu chờ duyệt, đơn có thể đã bị thu bằng
            đường khác hoặc bị sửa tiền — duyệt mà không kiểm lại là ghi vào ví một khoản không còn ở
            tay lái xe (đúng ca ngày 10/07/2026).
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.ICashHolderLock">
            <summary>
            Khoá độc quyền trên tiền đang cầm, giữ tới khi transaction kết thúc. Hai tầng: theo
            <b>người cầm</b> và theo <b>đơn</b>.
            </summary>
            <remarks>
            <para>
            Mọi đường chuyển tiền khỏi tay một người — thu ở màn Quỹ, lái xe tạo phiếu chuyển khoản, kế
            toán duyệt / từ chối, lái xe huỷ phiếu — giữ khoá <b>người cầm</b> trước, rồi khoá <b>từng đơn</b>
            sẽ đụng tới, rồi mới đọc lại <c>OrderFin</c>. Lượt sau đọc được kết quả của lượt trước và bị từ
            chối thay vì ghi vào ví lần hai.
            </para>
            <para>
            Khoá người cầm không đủ: một đơn thường có nhiều người cầm cùng lúc (phí lấy ở chi nhánh, phí
            giao và COD ở lái xe giao). Mọi đường ghi dùng <c>DbSet.Update</c> — ghi đè CẢ DÒNG
            <c>OrderFin</c> từ bản đã đọc — nên hai lượt khác người cầm trên cùng một đơn mà chạy song song thì
            lượt commit sau đè mất thay đổi của lượt trước, khoản tiền "quay lại" tay người cũ và thu được lần
            hai. Khoá đơn chặn đúng chỗ đó.
            </para>
            <para>
            Thứ tự cố định để không khoá chéo: người cầm trước (mỗi lượt đúng một người), rồi đơn theo Id tăng
            dần. <c>Wallet.RowVersion</c> chỉ chặn hai lượt ghi vào <b>cùng một ví</b>; <c>OrderFin</c> không
            có cột chống ghi đè nên các đường ghi <c>OrderFin</c> KHÔNG đi qua khoá này (thu tiền từ khách ở
            <c>OrderFinService.Collect</c>, đối soát, sửa đơn) vẫn có thể đè — rủi ro có từ trước.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ICashHolderLock.TryAcquireHolderAsync(Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction,System.Int32)">
            <summary>
            Giữ khoá của người đang cầm tiền <paramref name="holderUserId"/>.
            </summary>
            <returns><c>false</c> khi chờ quá hạn — bên gọi rollback và báo người dùng thử lại.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ICashHolderLock.TryAcquireOrdersAsync(Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction,System.Collections.Generic.IEnumerable{System.Int32})">
            <summary>
            Giữ khoá của từng đơn trong <paramref name="orderIds"/>, theo Id tăng dần. Gọi SAU khoá người cầm.
            </summary>
            <returns><c>false</c> khi một khoá chờ quá hạn — bên gọi rollback và báo người dùng thử lại.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.SqlCashHolderLock">
            <summary>
            Khoá bằng <c>sp_getapplock</c> của SQL Server, chủ sở hữu là transaction — commit hay rollback
            là nhả, không có đường nào quên nhả.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Finances.SqlCashHolderLock.DefaultTimeoutMilliseconds">
            <summary>
            Thời gian chờ mặc định cho mỗi khoá. Một lượt thu giữ khoá dưới một giây; quá mười giây là có
            gì đó treo, để người dùng thử lại tốt hơn là giữ request mãi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Finances.SqlCashHolderLock.TimeoutMilliseconds">
            <summary>Thời gian chờ khoá; test đặt ngắn để không phải chờ đủ mười giây.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.SqlCashHolderLock.HolderResourceName(System.Int32)">
            <summary>Tên tài nguyên khoá người cầm — một người một khoá.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Finances.SqlCashHolderLock.OrderResourcePrefix">
            <summary>Tiền tố tên tài nguyên khoá đơn; SQL nối thêm Id.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ICashierService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Danh sách nhân sự đang cầm / sắp thu tiền, giới hạn theo phạm vi xem của
            <paramref name="userId"/> — chỉ Founder và kế toán thấy toàn mạng lưới.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ICashierService.GetOrders(System.Int32,System.Int32)">
            <summary>
            Đơn đang cầm tiền của một nhân sự. Nhân sự ngoài phạm vi xem của
            <paramref name="currentUserId"/> thì trả danh sách rỗng, như thể họ không cầm đơn nào.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.CashierScope">
            <summary>
            Dịch phạm vi xem của người dùng thành hàng rào của màn Quỹ.
            </summary>
            <remarks>
            <para>
            Hàm thuần, tách khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Finances.CashierService"/> vì service gọi Dapper thẳng nên không có
            cách nào kiểm chứng luật phạm vi bằng test nếu luật nằm lẫn trong đó.
            </para>
            <para>
            Nguồn luật vẫn là <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Finance.IReconciliationVisibilityResolver"/> — Founder và kế toán không
            giới hạn; người khác chỉ thấy bản thân, cấp dưới theo <c>UserPreference.ManagerId</c> và nhân
            sự các chi nhánh mình đứng tên quản lý (kể cả chi nhánh con). Cố ý dùng lại thay vì dựng cây
            phân cấp thứ ba, cùng lý do với <c>OrderRevenueSaleScope</c>.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.CashierScope.TryGetUserIdsParameter(Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibility,System.String@)">
            <summary>
            Tham số <c>@UserIds</c> cho <c>sp_GetCashierBalance</c>.
            </summary>
            <param name="visibility">Phạm vi nhân sự của người đang đăng nhập.</param>
            <param name="userIds">NULL = không giới hạn; ngược lại là danh sách UserId ngăn cách dấu phẩy.</param>
            <returns>
            <c>false</c> khi người này không thấy ai — bên gọi trả rỗng luôn, không gọi SP.
            </returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.CashierScope.CanSee(Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibility,System.Int32)">
            <summary>
            Người đang đăng nhập có được xem tiền đang cầm của <paramref name="cashierUserId"/> không.
            </summary>
            <remarks>
            Canh đường đọc thứ hai của màn Quỹ: <c>GetOrders</c> nhận <c>userId</c> từ body, nên chỉ lọc
            danh sách thôi thì đổi id là vẫn đọc được đơn, địa chỉ và số điện thoại khách của lái xe chi
            nhánh khác.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Finances.CashierService._franchiseLedger">
            <summary>Ví bưu cục v2 (V-05) — null khi dựng không có ví (giữ hành vi cũ).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.CashierService.WalletHeldOrderCodesAsync(System.Int32,System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>Mã các đơn trong <paramref name="orderIds"/> mà tiền người nộp đang cầm thuộc Ví bưu cục (V-05) — rỗng khi không phải người bưu cục có ví.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.CashierService.UpdateLastPaymentTime(System.Int32,System.DateTimeOffset)">
            <summary>
            Enrich danh sách cashier với thông tin vi phạm nộp tiền
            </summary>
            <summary>
            Cập nhật UserPreference.LastPaymentTime khi thu tiền từ lái xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.CashierService.UpdateOrderTimeTrackFinancialTimes(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CollectCashierModel,Lada.Framework.Data.Enums.OrderFinEnum.OrderFeeStage,Lada.Framework.Data.Enums.OrderFinEnum.OrderCodStage)">
            <summary>
            Cập nhật OrderTimeTrack với thời gian nhận tiền (chỉ khi Stage = Head)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.CashierService.CreateOrderTracksForCollectedOrders(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CollectCashierModel)">
            <summary>
            Tạo hành trình cho các đơn hàng đã thu tiền
            </summary>
            <param name="model">Model thu tiền</param>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Finances.DriverTransferSlipService._franchiseLedger">
            <summary>Ví bưu cục v2 (V-05 / V-40) — null khi dựng không có ví (giữ hành vi cũ).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.DriverTransferSlipService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateDriverTransferSlipModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lái xe tạo phiếu chuyển tiền
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.DriverTransferSlipService.Cancel(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lái xe hủy phiếu (chỉ khi Pending)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.DriverTransferSlipService.GetMyPendingSlip(System.Int32)">
            <summary>
            Lái xe xem phiếu đang chờ duyệt
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.DriverTransferSlipService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tìm kiếm phiếu chuyển tiền (kế toán)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.DriverTransferSlipService.GetById(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Chi tiết phiếu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.DriverTransferSlipService.Approve(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Kế toán duyệt phiếu → logic giống CollectCashier
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.DriverTransferSlipService.Reject(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.RejectDriverTransferSlipModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Kế toán từ chối phiếu → rollback Stage về Driver
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.DriverTransferSlipService.HeldByDriverQuery(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletHolder)">
            <summary>
            Đơn lái xe đang cầm tiền ở mức Driver — nguồn của phiếu chuyển tiền. Lái xe của bưu cục nhượng quyền đã bật ví
            (<paramref name="walletHolder"/>): bỏ đơn Ví ghi (tạo từ ngày bắt đầu ghi Ví) — cùng luật SP màn Quỹ và <c>CollectCashier</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.DriverTransferSlipService.WalletHolderAsync(System.Int32)">
            <summary>Lái xe thuộc bưu cục nhượng quyền đang bật ví (V-05) — null khi không phải hoặc dựng không có ví.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.DriverTransferSlipService.LockAndRecheckPendingAsync(Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction,Lada.Framework.Data.Domains.Finance.DriverTransferSlip)">
            <summary>
            Giữ khoá tiền đang cầm của lái xe rồi đọc lại trạng thái phiếu ngay trong khoá.
            </summary>
            <returns>Thông báo lỗi, hoặc <c>null</c> khi phiếu vẫn đang chờ duyệt.</returns>
            <remarks>
            Trạng thái kiểm ở đầu Approve/Reject/Cancel là đọc TRƯỚC khoá — hai lượt song song đều thấy
            "Pending". Phải đọc lại sau khoá, bằng phép chiếu để lấy giá trị trong DB chứ không phải bản
            EF đang giữ trong bộ nhớ.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.DriverTransferSlipService.CloseSlipAsync(Lada.Framework.Data.Domains.Finance.DriverTransferSlip,Lada.Framework.Data.Domains.Finance.DriverTransferSlipStatus,System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Đóng một phiếu đang chờ (từ chối hoặc huỷ): trả tiền về mức Driver rồi đổi trạng thái, trong
            một transaction giữ khoá.
            </summary>
            <returns>Thông báo lỗi, hoặc <c>null</c> khi đã đóng xong.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.DriverTransferSlipService.RollbackOrderStages(System.Collections.Generic.List{System.Int32},System.Int32)">
            <summary>
            Rollback Stage từ InTransit về Driver cho các đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.DriverTransferSlipService.GenerateSlipCode">
            <summary>
            Generate mã phiếu (DTS260704001)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IExpenseService">
            <summary>
            Interface cho service quản lý chi phí
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IExpenseService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tìm kiếm chi phí
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả tìm kiếm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IExpenseService.GetById(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy thông tin chi tiết của chi phí
            </summary>
            <param name="id">ID chi phí</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Thông tin chi tiết chi phí</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IExpenseService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo mới hoặc cập nhật chi phí
            </summary>
            <param name="model">Thông tin chi phí</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả tạo hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IExpenseService.Approve(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Duyệt chi phí
            </summary>
            <param name="id">ID chi phí</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả duyệt</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IExpenseService.Unapprove(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Bỏ duyệt chi phí (chuyển về trạng thái chờ duyệt)
            </summary>
            <param name="id">ID chi phí</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả bỏ duyệt</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IExpenseService.Reject(System.Guid,System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Từ chối chi phí
            </summary>
            <param name="id">ID chi phí</param>
            <param name="rejectReason">Lý do từ chối</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả từ chối</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IExpenseService.MarkAsPaid(System.Guid,Lada.Framework.Infrastructures.CurrentUser,System.String)">
            <summary>
            Đánh dấu chi phí đã chuyển tiền
            </summary>
            <param name="id">ID chi phí</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <param name="note">Ghi chú</param>
            <returns>Kết quả đánh dấu chuyển tiền</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IExpenseService.Delete(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa chi phí
            </summary>
            <param name="id">ID chi phí</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IExpenseService.BatchApprove(System.Collections.Generic.List{System.Guid},Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Duyệt hàng loạt chi phí (chỉ dành cho Founder)
            </summary>
            <param name="ids">Danh sách ID chi phí cần duyệt</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả duyệt hàng loạt</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService">
            <summary>
            Service quản lý chi phí
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.Expense},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.ExpenseCategory},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.ExpenseHistory},Lada.Framework.Data.Repositories.IUserRepository{Lada.Framework.Data.Domains.Identity.User},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.Wallets.Wallet},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.Wallets.Transaction},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.UserBankAccount},Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Hr.EmployeePayrollRecord},Ladaer.BackEnd.Infrastructures.Services.IAppConfigService,Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositService)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService"/>.
            </summary>
            <param name="expenseRepository">Đối tượng IRepository của Expense.</param>
            <param name="expenseCategoryRepository">Đối tượng IRepository của ExpenseCategory.</param>
            <param name="userRepository">Đối tượng IUserRepository của User.</param>
            <param name="walletRepository">Đối tượng IRepository của Wallet.</param>
            <param name="transactionRepository">Đối tượng IRepository của Transaction.</param>
            <param name="userBankAccountRepository">Đối tượng IRepository của UserBankAccount.</param>
            <param name="permissionService">Service quản lý quyền.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tìm kiếm chi phí
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả tìm kiếm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.GetById(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy thông tin chi tiết của chi phí
            </summary>
            <param name="id">ID chi phí</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Thông tin chi tiết chi phí</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.ExpenseModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo mới hoặc cập nhật chi phí
            </summary>
            <param name="model">Thông tin chi phí</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.CopyBankAccountInfo(Lada.Framework.Data.Domains.Finance.Expense,System.Nullable{System.Int32})">
            <summary>
            Copy thông tin ngân hàng từ UserBankAccount vào Expense (Copy-on-Reference Pattern)
            </summary>
            <param name="expense">Expense entity cần cập nhật</param>
            <param name="userBankAccountId">ID tài khoản ngân hàng</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.Create(Lada.Framework.Data.Domains.Finance.Expense)">
            <summary>
            Tạo chi phí mới
            </summary>
            <param name="expense">Thông tin chi phí</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.Update(Lada.Framework.Data.Domains.Finance.Expense)">
            <summary>
            Cập nhật chi phí (không thay đổi Status và RejectReason)
            </summary>
            <param name="expense">Thông tin chi phí</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.Approve(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Duyệt chi phí
            </summary>
            <param name="id">ID chi phí</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.Unapprove(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Bỏ duyệt chi phí (chuyển về trạng thái chờ duyệt)
            </summary>
            <param name="id">ID chi phí</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.Reject(System.Guid,System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Từ chối chi phí
            </summary>
            <param name="id">ID chi phí</param>
            <param name="rejectReason">Lý do từ chối</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.MarkAsPaid(System.Guid,Lada.Framework.Infrastructures.CurrentUser,System.String)">
            <summary>
            Đánh dấu chi phí đã chuyển tiền
            </summary>
            <param name="id">ID chi phí</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <param name="note">Ghi chú</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.ApplyDepositExpenseHookAsync(Lada.Framework.Data.Domains.Finance.Expense,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Ghi sổ cọc/tạm ứng khi chi phiếu có DepositUserId.
            Trả null nếu category của expense không thuộc hai danh mục cọc (không làm gì);
            trả BaseResult Failed nếu ghi sổ thất bại — caller phải rollback.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.BatchApprove(System.Collections.Generic.List{System.Guid},Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Duyệt hàng loạt chi phí (chỉ dành cho Founder)
            </summary>
            <param name="ids">Danh sách ID chi phí cần duyệt</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả duyệt hàng loạt</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.Delete(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa chi phí
            </summary>
            <param name="id">ID chi phí</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.CalculatePermissions(Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.ExpenseItem,Lada.Framework.Data.Domains.Finance.Expense,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tính toán các quyền cho ExpenseItem
            </summary>
            <param name="expenseItem">ExpenseItem cần tính toán quyền</param>
            <param name="expense">Expense entity</param>
            <param name="currentUser">Người dùng hiện tại</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.ApplyViewPermissionsFilter(System.Linq.IQueryable{Lada.Framework.Data.Domains.Finance.Expense},Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Áp dụng filter quyền xem cho query
            </summary>
            <param name="query">Query gốc</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Query đã được filter theo quyền xem</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.HasViewPermission(Lada.Framework.Data.Domains.Finance.Expense,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Kiểm tra quyền xem một chi phí cụ thể
            </summary>
            <param name="expense">Chi phí cần kiểm tra</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>True nếu có quyền xem</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ExpenseService.CreateHistoryAsync(System.Guid,System.Nullable{Lada.Framework.Data.Enums.ExpenseStatus},Lada.Framework.Data.Enums.ExpenseStatus,Lada.Framework.Infrastructures.CurrentUser,System.String,System.String)">
            <summary>
            Tạo lịch sử thay đổi trạng thái chi phí
            </summary>
            <param name="expenseId">ID của chi phí</param>
            <param name="oldStatus">Trạng thái trước khi thay đổi</param>
            <param name="newStatus">Trạng thái sau khi thay đổi</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <param name="note">Ghi chú</param>
            <param name="reason">Lý do (dùng cho từ chối)</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.BatchApproveResult">
            <summary>
            Kết quả duyệt hàng loạt chi phí
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Finances.BatchApproveResult.SuccessCount">
            <summary>
            Số lượng chi phí duyệt thành công
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Finances.BatchApproveResult.FailedCount">
            <summary>
            Số lượng chi phí duyệt thất bại
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Finances.BatchApproveResult.FailedItems">
            <summary>
            Danh sách chi phí duyệt thất bại (kèm lý do)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.BatchApproveFailedItem">
            <summary>
            Thông tin chi phí duyệt thất bại
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IFuelCardStatementService.InitializeDebt(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.InitializeDebtModel)">
            <summary>
            Khởi tạo dư nợ hiện tại cho thẻ — dùng khi thêm thẻ mới vào hệ thống
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IFuelCardStatementService.ReconcileTransactions(System.Int32,System.Collections.Generic.List{System.Guid})">
            <summary>
            Gắn danh sách giao dịch vào 1 kỳ sao kê
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IFuelCardStatementService.GetUnlinkedTransactions(System.Int32)">
            <summary>
            Lấy danh sách giao dịch chưa gắn kỳ sao kê của thẻ
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.FuelCardStatementService.PayStatement(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PayStatementModel)">
            <summary>
            Xác nhận thanh toán kỳ sao kê
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.FuelCardStatementService.GenerateStatement(System.Int32,System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Auto-generate kỳ sao kê: gom các giao dịch chưa gắn kỳ trong khoảng thời gian
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.FuelCardStatementService.InitializeDebt(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.InitializeDebtModel)">
            <summary>
            Khởi tạo dư nợ cho thẻ mới thêm vào hệ thống
            Tạo 1 statement "snapshot" chứa dư nợ hiện tại
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.FuelCardStatementService.ReconcileTransactions(System.Int32,System.Collections.Generic.List{System.Guid})">
            <summary>
            Gắn danh sách giao dịch vào 1 kỳ sao kê, tính lại TotalCharges
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.FuelCardStatementService.GetUnlinkedTransactions(System.Int32)">
            <summary>
            Lấy danh sách giao dịch chưa gắn kỳ sao kê
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IGoodsCategoryPriceService">
            <summary>
            Quản trị MA TRẬN giá theo loại hàng: tuyến × lựa chọn thuộc tính trục.
            </summary>
            <remarks>
            <para>
            <b>Vì sao tách khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IPriceService"/>.</b> Hai bảng khác hình dạng — bảng chung là
            tuyến × khoảng trọng lượng, bảng riêng là tuyến × option trục — nên gộp vào một service nghĩa là
            mọi phương thức phải rẽ nhánh theo "đang làm bảng nào". Đường bảng giá chung đã chứng minh hậu quả:
            một câu truy vấn thiếu vế <c>GoodsCategoryId == null</c> làm 13 ô giá theo loại hàng bị xoá oan mỗi
            lần bấm Lưu (nợ PSVC). Tách hẳn thì hai đường không thể vô tình chạm vào dữ liệu của nhau.
            </para>
            <para>
            <b>Luật thuần nằm ở <c>PriceMatrixRule</c></b> (project <c>Lada.Framework</c>) để test với tới —
            service này chỉ lo đọc/ghi DB và dựng <see cref="T:Lada.Framework.DTO.BaseResult"/>.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IGoodsCategoryPriceService.GetMatrix(System.Int32,Lada.Framework.Data.Enums.PriceType,System.Int32)">
            <summary>
            Đọc ma trận giá của một danh mục — lưới đầy đủ, phân biệt được ô có giá và ô trống.
            </summary>
            <param name="goodsCategoryId">Danh mục cần đọc.</param>
            <param name="priceType">Loại giá.</param>
            <param name="customerId">Khách sở hữu bảng giá. <c>0</c> = khách mặc định (mặc định cũ).</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IGoodsCategoryPriceService.UpdateMatrix(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceListModel)">
            <summary>
            Ghi một lô ô giá (tạo / sửa / xoá mềm).
            </summary>
            <remarks>
            Ô vắng mặt trong payload là ô KHÔNG ĐỤNG TỚI. Xoá phải mang cờ
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceCellModel.Xoa"/>.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IGoodsCategoryPriceService.InitMatrix(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.InitGoodsCategoryPriceMatrixModel)">
            <summary>
            Khởi tạo ma trận cho một danh mục: sinh đủ ô theo option của trục × tuyến.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IGoodsCategoryPriceService.DeleteMatrix(System.Int32,System.Int32,System.String,System.Int32)">
            <summary>
            Xoá bảng giá riêng của một danh mục ⇒ danh mục quay về tính theo TRỌNG LƯỢNG.
            </summary>
            <param name="goodsCategoryId">Danh mục cần xoá bảng giá riêng.</param>
            <param name="updatedBy">Người thực hiện.</param>
            <param name="updatedByUserName">Tên người thực hiện.</param>
            <param name="customerId">
            Khách sở hữu bảng giá cần xoá. <c>0</c> = <b>mọi khách</b>, giữ đúng hành vi cũ.
            </param>
            <remarks>
            ⚠️ <paramref name="customerId"/> = <c>0</c> KHÔNG có nghĩa "khách mặc định" ở riêng phương thức
            này — nó nghĩa là <b>mọi khách</b>. Đó là hành vi vốn có và nó đúng với mục đích của thao tác:
            đưa danh mục về nhánh trọng lượng, mà luật chọn trục hỏi trên TOÀN BỘ dòng giá không phân biệt
            khách. Quy nó về khách mặc định sẽ để sót ô của khách riêng, và danh mục vẫn ở nhánh bảng giá
            riêng trong khi UI báo đã xoá xong.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IGoodsCategoryPriceService.GetCategoriesWithPriceTable(System.Int32)">
            <summary>
            Liệt kê các danh mục ĐÃ có bảng giá riêng, để FE đánh dấu.
            </summary>
            <param name="customerId">
            Lọc theo khách sở hữu ô giá. <c>0</c> = mọi khách, giữ đúng hành vi cũ.
            </param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.GoodsCategoryPriceService">
            <summary>
            Triển khai quản trị ma trận giá theo loại hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.GoodsCategoryPriceService.GetMatrix(System.Int32,Lada.Framework.Data.Enums.PriceType,System.Int32)">
            <summary>
            Đọc ma trận giá của một danh mục.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.GoodsCategoryPriceService.UpdateMatrix(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.GoodsCategoryPriceListModel)">
            <summary>
            Ghi một lô ô giá.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.GoodsCategoryPriceService.InitMatrix(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.InitGoodsCategoryPriceMatrixModel)">
            <summary>
            Khởi tạo ma trận cho một danh mục.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.GoodsCategoryPriceService.DeleteMatrix(System.Int32,System.Int32,System.String,System.Int32)">
            <summary>
            Xoá bảng giá riêng của một danh mục.
            </summary>
            <remarks>
            ⚠️ Đây là thao tác ĐỔI CÁCH TÍNH TIỀN: danh mục quay về nhánh trọng lượng ngay sau khi ô cuối
            cùng biến mất. Xoá mềm nên dữ liệu còn đó, nhưng cước của mọi đơn sau đó đổi ngay.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.GoodsCategoryPriceService.GetCategoriesWithPriceTable(System.Int32)">
            <summary>
            Liệt kê các danh mục đã có bảng giá riêng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.GoodsCategoryPriceService.LoadConfig(System.Int32)">
            <summary>
            Nạp cấu hình danh mục kèm thuộc tính và lựa chọn (đã lọc xoá mềm).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.GoodsCategoryPriceService.ChonThuocTinhTruc(Lada.Framework.Data.Domains.Cms.GoodsCategoryConfig)">
            <summary>
            Chọn thuộc tính trục — PHẢI cùng luật với <c>GoodsCategoryPricingService.ResolveAsync</c>.
            </summary>
            <remarks>
            Lọc đúng <c>SingleSelect</c> rồi <c>DisplayOrder</c> nhỏ nhất, rồi <c>Id</c> nhỏ nhất. Chọn khác
            engine nghĩa là người quản trị khai giá vào cột này còn đơn tra cột kia — bảng giá trông đầy đủ
            mà đơn vẫn báo "chưa có giá".
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.GoodsCategoryPriceService.ResolveScopeCustomerId(System.Int32)">
            <summary>
            Quy <c>customerId = 0</c> về khách mặc định. Trả <c>0</c> khi hệ thống chưa khai khách mặc định.
            </summary>
            <remarks>
            Chỉ dùng cho các thao tác ĐỌC/GHI một bảng giá cụ thể. <c>DeleteMatrix</c> và
            <c>GetCategoriesWithPriceTable</c> cố tình KHÔNG gọi hàm này: ở đó <c>0</c> nghĩa là
            <b>mọi khách</b>, xem chú thích trên interface.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IIncomeService">
            <summary>
            Interface cho service quản lý doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IIncomeService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tìm kiếm doanh thu
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả tìm kiếm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IIncomeService.GetById(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy thông tin chi tiết của doanh thu
            </summary>
            <param name="id">ID doanh thu</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Thông tin chi tiết doanh thu</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IIncomeService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.IncomeModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo mới hoặc cập nhật doanh thu
            </summary>
            <param name="model">Thông tin doanh thu</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả tạo hoặc cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IIncomeService.Approve(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Duyệt doanh thu
            </summary>
            <param name="id">ID doanh thu</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả duyệt</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IIncomeService.Reject(System.Guid,System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Từ chối doanh thu
            </summary>
            <param name="id">ID doanh thu</param>
            <param name="rejectReason">Lý do từ chối</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả từ chối</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IIncomeService.MarkAsReceived(System.Guid,Lada.Framework.Infrastructures.CurrentUser,System.String)">
            <summary>
            Đánh dấu doanh thu đã nhận tiền
            </summary>
            <param name="id">ID doanh thu</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <param name="note">Ghi chú</param>
            <returns>Kết quả đánh dấu nhận tiền</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IIncomeService.Delete(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa doanh thu
            </summary>
            <param name="id">ID doanh thu</param>
            <param name="currentUser">Người dùng hiện tại</param>
            <returns>Kết quả xóa</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IIncomeService.SubmitDeposit(System.Int32,System.Decimal,System.DateTime,System.String,Microsoft.AspNetCore.Http.IFormFile,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Nộp cọc trách nhiệm — tạo Income loại cọc lái xe
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService">
            <summary>
            Service quản lý doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.Income},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.IncomeCategory},Lada.Framework.Data.Repositories.IUserRepository{Lada.Framework.Data.Domains.Identity.User},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.Wallets.Wallet},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.Wallets.Transaction},Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService,Ladaer.BackEnd.Infrastructures.Services.IAppConfigService,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Identity.UserPreference},Ladaer.BackEnd.Infrastructures.Services.Identity.IUserTrackService,Lada.Framework.Infrastructures.Services.IUnifiedMediaService,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Medias.Media},Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositService)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService"/>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tìm kiếm doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService.GetById(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy thông tin chi tiết của doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.IncomeModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo mới hoặc cập nhật doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService.Approve(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Duyệt doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService.Reject(System.Guid,System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Từ chối doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService.MarkAsReceived(System.Guid,Lada.Framework.Infrastructures.CurrentUser,System.String)">
            <summary>
            Đánh dấu doanh thu đã nhận tiền
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService.Delete(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService.SubmitDeposit(System.Int32,System.Decimal,System.DateTime,System.String,Microsoft.AspNetCore.Http.IFormFile,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Nộp cọc trách nhiệm — tạo Income loại cọc lái xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService.ApplyViewPermissionsFilter(System.Linq.IQueryable{Lada.Framework.Data.Domains.Finance.Income},Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Áp dụng filter theo quyền xem
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService.HasViewPermission(Lada.Framework.Data.Domains.Finance.Income,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Kiểm tra quyền xem doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService.HasApprovePermission(Lada.Framework.Data.Domains.Finance.Income,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Kiểm tra quyền duyệt doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService.HasRejectPermission(Lada.Framework.Data.Domains.Finance.Income,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Kiểm tra quyền từ chối doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService.CalculatePermissions(Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.IncomeItem,Lada.Framework.Data.Domains.Finance.Income,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tính toán permissions cho từng item
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IncomeService.CreateIncomeHistory(System.Guid,Lada.Framework.Data.Enums.IncomeStatus,Lada.Framework.Infrastructures.CurrentUser,System.String)">
            <summary>
            Tạo lịch sử doanh thu
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IVatInvoiceService">
            <summary>
            Service quản lý hóa đơn VAT nội bộ (CRUD)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IVatInvoiceService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm hóa đơn VAT
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IVatInvoiceSyncService">
            <summary>
            Service đồng bộ hóa đơn VAT từ API Tổng cục Thuế
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IVatInvoiceSyncService.SyncInvoicesFromAPI(System.DateTimeOffset,System.DateTimeOffset,System.String,System.Nullable{System.Int32},System.Int32)">
            <summary>
            Đồng bộ hóa đơn từ API Tổng cục Thuế cho một khoảng thời gian
            </summary>
            <param name="fromDate">Ngày bắt đầu</param>
            <param name="toDate">Ngày kết thúc</param>
            <param name="syncType">Loại đồng bộ: Manual hoặc Auto</param>
            <param name="userId">User ID nếu là manual sync</param>
            <param name="invoiceDirection">Chiều hóa đơn: 1=Bán ra, 2=Mua vào</param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IVatInvoiceSyncService.SyncYesterdayInvoices">
            <summary>
            Đồng bộ hóa đơn bán ra của ngày hôm qua (dùng cho Hangfire job)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IVatInvoiceSyncService.SyncYesterdayPurchaseInvoices">
            <summary>
            Đồng bộ hóa đơn mua vào của ngày hôm qua (dùng cho Hangfire job)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IVatInvoiceSyncService.GetLastSyncInfo">
            <summary>
            Lấy thông tin đồng bộ gần nhất
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IOrderTimeTrackService">
            <summary>
            Interface cho service quản lý thời gian nhận tiền trong OrderTimeTrack
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IOrderTimeTrackService.UpdateFinancialTimesAsync(System.Int32,System.Nullable{Lada.Framework.Data.Enums.OrderFinEnum.OrderFeeStage},System.Nullable{Lada.Framework.Data.Enums.OrderFinEnum.OrderFeeStage},System.Nullable{Lada.Framework.Data.Enums.OrderFinEnum.OrderFeeStage},System.Nullable{Lada.Framework.Data.Enums.OrderFinEnum.OrderCodStage},System.Nullable{Lada.Framework.Data.Enums.OrderFinEnum.OrderFeeStage},System.Nullable{System.Int32},System.String,System.Nullable{System.DateTimeOffset})">
            <summary>
            Cập nhật thời gian nhận tiền trong OrderTimeTrack
            </summary>
            <param name="orderId">ID đơn hàng</param>
            <param name="sourceFeeStage">Stage của SourceFee (3=Branch, 9=Head)</param>
            <param name="destFeeStage">Stage của DestFee (3=Branch, 9=Head)</param>
            <param name="transferFeeStage">Stage của TransferFee (3=Branch, 9=Head)</param>
            <param name="codStage">Stage của COD (3=Branch, 9=Head)</param>
            <param name="deductCodFeeStage">Stage của DeductCodFee (3=Branch, 9=Head) - chỉ khi PayFeeType = COD</param>
            <param name="updatedBy">ID người cập nhật</param>
            <param name="updatedByUserName">Tên người cập nhật</param>
            <param name="currentTime">Thời gian hiện tại (null = SYSDATETIMEOFFSET())</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IOrderTimeTrackService.UpdateFinancialTimesBatchAsync(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Finances.OrderTimeTrackUpdateModel},System.Int32,System.String,System.Nullable{System.DateTimeOffset})">
            <summary>
            Cập nhật thời gian nhận tiền cho nhiều đơn hàng
            </summary>
            <param name="orderUpdates">Danh sách cập nhật cho các đơn hàng</param>
            <param name="updatedBy">ID người cập nhật</param>
            <param name="updatedByUserName">Tên người cập nhật</param>
            <param name="currentTime">Thời gian hiện tại (null = SYSDATETIMEOFFSET())</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.OrderTimeTrackUpdateModel">
            <summary>
            Model cho việc cập nhật thời gian nhận tiền của một đơn hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.OrderTimeTrackService">
            <summary>
            Service quản lý thời gian nhận tiền trong OrderTimeTrack
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.OrderTimeTrackService.#ctor(System.Data.IDbConnection)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Finances.OrderTimeTrackService"/>.
            </summary>
            <param name="dbConnection">Database connection.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.OrderTimeTrackService.UpdateFinancialTimesAsync(System.Int32,System.Nullable{Lada.Framework.Data.Enums.OrderFinEnum.OrderFeeStage},System.Nullable{Lada.Framework.Data.Enums.OrderFinEnum.OrderFeeStage},System.Nullable{Lada.Framework.Data.Enums.OrderFinEnum.OrderFeeStage},System.Nullable{Lada.Framework.Data.Enums.OrderFinEnum.OrderCodStage},System.Nullable{Lada.Framework.Data.Enums.OrderFinEnum.OrderFeeStage},System.Nullable{System.Int32},System.String,System.Nullable{System.DateTimeOffset})">
            <summary>
            Cập nhật thời gian nhận tiền trong OrderTimeTrack
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.OrderTimeTrackService.UpdateFinancialTimesBatchAsync(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Finances.OrderTimeTrackUpdateModel},System.Int32,System.String,System.Nullable{System.DateTimeOffset})">
            <summary>
            Cập nhật thời gian nhận tiền cho nhiều đơn hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IPriceService">
            <summary>
            Giao diện cho dịch vụ quản lý giá.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IPriceService.GetPriceList(System.Int32,System.Nullable{System.Int32},Lada.Framework.Data.Enums.PriceType)">
            <summary>
            Lấy bảng giá của một PHẠM VI bất kỳ — bộ ba <c>(customerId, goodsCategoryId, priceType)</c>.
            </summary>
            <param name="customerId">Khách sở hữu bảng giá. <c>0</c> = khách mặc định.</param>
            <param name="goodsCategoryId">Loại hàng. <c>null</c> = bảng giá chung theo khoảng trọng lượng.</param>
            <param name="priceType">Loại giá.</param>
            <returns>Bảng giá của phạm vi, kèm danh sách tuyến để dựng lưới.</returns>
            <remarks>
            Bản tổng quát của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IPriceService.GetDefaultPriceList(Lada.Framework.Data.Enums.PriceType)"/>. Hai đường dùng CHUNG một biểu thức phạm vi
            (<see cref="M:Lada.Framework.Infrastructures.Services.PriceListScope.Of(System.Int32,System.Nullable{System.Int32},Lada.Framework.Data.Enums.PriceType)"/>) nên không thể trôi khác nhau.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IPriceService.UpdatePriceList(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceListModel)">
            <summary>
            Cập nhật bảng giá của một PHẠM VI bất kỳ.
            </summary>
            <param name="model">Bảng giá, mang trọn bộ ba định danh phạm vi.</param>
            <returns>Kết quả của thao tác.</returns>
            <remarks>
            ⚠️ Dòng đã có trong database mà không còn Id trong payload sẽ bị <b>xoá mềm</b>. Nên phạm vi
            trong <paramref name="model"/> phải đúng bằng phạm vi mà trang đang hiển thị — nạp rộng hơn
            những gì người dùng nhìn thấy là xoá mất dữ liệu họ không hề đụng tới.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IPriceService.GetPriceScopes(System.Int32)">
            <summary>
            Liệt kê mọi phạm vi bảng giá của một khách, kèm cờ "đang mượn bảng mặc định".
            </summary>
            <param name="customerId">Khách cần xem. <c>0</c> = khách mặc định.</param>
            <returns>Danh sách phạm vi.</returns>
            <remarks>
            Đây là màn hình trả lời câu "khách này đang tính tiền bằng bảng giá của ai" — xem
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceScopeItem.IsInherited"/>.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IPriceService.GetDefaultPriceList(Lada.Framework.Data.Enums.PriceType)">
            <summary>
            Lấy danh sách giá mặc định theo loại giá.
            </summary>
            <param name="priceType">Loại giá.</param>
            <returns>Danh sách giá mặc định.</returns>
            <remarks>
            Lớp bọc mỏng của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IPriceService.GetPriceList(System.Int32,System.Nullable{System.Int32},Lada.Framework.Data.Enums.PriceType)"/> với phạm vi (khách mặc định, bảng chung). Giữ lại
            để client hiện có không phải đổi cùng lúc với backend.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IPriceService.UpdateDefaultPriceList(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceListModel)">
            <summary>
            Cập nhật danh sách giá mặc định.
            </summary>
            <param name="model">Thông tin danh sách giá.</param>
            <returns>Kết quả của thao tác.</returns>
            <remarks>
            Lớp bọc mỏng của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IPriceService.UpdatePriceList(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceListModel)"/> — ép phạm vi về (khách mặc định, bảng chung)
            <b>bất kể</b> model mang gì, để một client cũ lỡ gửi <c>GoodsCategoryId</c> cũng không đổi được
            phạm vi qua đường này.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IPriceService.ExportDefaultPriceList(System.String,Lada.Framework.Data.Enums.PriceType)">
            <summary>
            Xuất danh sách giá mặc định ra file.
            </summary>
            <param name="filePath">Đường dẫn file.</param>
            <param name="priceType">Loại giá của bảng đang mở.</param>
            <returns>Kết quả của thao tác.</returns>
            <remarks>
            <paramref name="priceType"/> là tham số THÊM VÀO khi vá nợ N4: trước đó hàm này nạp mọi dòng
            giá của khách mặc định, không lọc loại giá cũng không lọc bảng giá chung, nên file Excel trộn
            cả ba loại giá lẫn ô giá theo loại hàng. Xem chú thích tại nơi truy vấn.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IPriceService.CopyPriceList(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CopyPriceListModel)">
            <summary>
            Sao chép bảng giá từ một phạm vi nguồn sang phạm vi đích.
            </summary>
            <param name="model">Nguồn, đích, loại giá và các tuỳ chọn copy.</param>
            <returns>Số ô đã tạo, bỏ qua, đè — và cảnh báo nếu có.</returns>
            <remarks>
            ⚠️ <b>Không đè im lặng</b> — mặc định <c>OverwriteExisting = false</c>. UI phải hiện đủ ba số
            và mọi <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Results.Finances.CopyPriceListResult.Warnings"/>.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService">
            <summary>
            Triển khai dịch vụ quản lý giá.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.Quotations.Price},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Crm.Customer},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.Quotations.Route},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Cms.Category},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Cms.GoodsCategoryConfig},Lada.Framework.Infrastructures.Services.Fees.IFeeConfigProvider)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService"/>.
            </summary>
            <param name="priceRepository">Đối tượng IRepository của Price.</param>
            <param name="customerRepository">Đối tượng IRepository của Customer.</param>
            <param name="routeRepository">Đối tượng IRepository của Route.</param>
            <param name="categoryRepository">Đối tượng IRepository của Category — lấy tên loại hàng cho danh sách phạm vi.</param>
            <param name="goodsCategoryConfigRepository">Cấu hình loại hàng — kiểm trục giá khi sao chép giữa hai loại hàng khác nhau.</param>
            <param name="feeConfigProvider">Nguồn tham số cấu hình cước — lấy bước trọng lượng mặc định.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService.GetPriceList(System.Int32,System.Nullable{System.Int32},Lada.Framework.Data.Enums.PriceType)">
            <summary>
            Lấy bảng giá của một phạm vi bất kỳ.
            </summary>
            <param name="customerId">Khách sở hữu bảng giá. <c>0</c> = khách mặc định.</param>
            <param name="goodsCategoryId">Loại hàng. <c>null</c> = bảng giá chung.</param>
            <param name="priceType">Loại giá.</param>
            <returns>Bảng giá của phạm vi.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService.GetDefaultPriceList(Lada.Framework.Data.Enums.PriceType)">
            <summary>
            Lấy danh sách giá mặc định theo loại giá.
            </summary>
            <param name="priceType">Loại giá.</param>
            <returns>Danh sách giá mặc định.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService.UpdatePriceList(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceListModel)">
            <summary>
            Cập nhật bảng giá của một phạm vi bất kỳ.
            </summary>
            <param name="model">Bảng giá, mang trọn bộ ba định danh phạm vi.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService.UpdateDefaultPriceList(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceListModel)">
            <summary>
            Cập nhật danh sách giá mặc định.
            </summary>
            <param name="model">Thông tin danh sách giá.</param>
            <returns>Kết quả của thao tác.</returns>
            <remarks>
            Ép phạm vi về (khách mặc định, bảng giá chung) rồi gọi <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService.UpdatePriceList(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PriceListModel)"/>. Ép chứ
            không tin model: endpoint cũ mang tên "DefaultPriceList" nên một payload lỡ kèm
            <c>CustomerId</c> hay <c>GoodsCategoryId</c> khác không được phép lái lần lưu này sang phạm vi
            khác — hậu quả là xoá mềm bảng giá của phạm vi đó.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService.GetPriceScopes(System.Int32)">
            <summary>
            Liệt kê mọi phạm vi bảng giá của một khách.
            </summary>
            <param name="customerId">Khách cần xem. <c>0</c> = khách mặc định.</param>
            <returns>Danh sách phạm vi, kèm cờ đang mượn bảng mặc định.</returns>
            <remarks>
            <para>
            Đếm theo <c>(GoodsCategoryId, PriceType)</c> ở phía C# sau khi đã kéo về tập tối thiểu: phép
            gom nhóm hai khoá kèm <c>Count</c> là chỗ EF hay bó tay lúc dịch câu truy vấn, và tập dòng giá
            của một khách vốn nhỏ.
            </para>
            <para>
            Phạm vi khách trống hẳn mà bảng mặc định có dòng thì vẫn được liệt kê với
            <c>IsInherited = true</c> — đó là phạm vi khách ĐANG tính tiền theo (QĐ-2), không hiện ra thì
            màn hình nói thiếu một nửa sự thật.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService.DemPhamVi(System.Int32)">
            <summary>
            Đếm số dòng giá của một khách, gom theo <c>(GoodsCategoryId, PriceType)</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService.DienTenLoaiHang(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.PriceScopeItem})">
            <summary>
            Điền tên loại hàng cho các phạm vi có <c>GoodsCategoryId</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService.ResolveScopeCustomerId(System.Int32)">
            <summary>
            Quy <c>customerId = 0</c> về khách mặc định; giá trị dương giữ nguyên.
            </summary>
            <returns>Id khách của phạm vi. <c>0</c> = chưa khai khách mặc định nào.</returns>
            <remarks>
            Quy ước "<c>0</c> nghĩa là khách mặc định" nằm ở hợp đồng API, nên nó phải được phân giải ở
            <b>đúng một chỗ</b>. Việc tra khách mặc định đi qua <see cref="T:Lada.Framework.Infrastructures.Services.DefaultCustomerResolver"/> —
            nó ném lỗi khi DB có nhiều hơn một khách mặc định, thay vì để đường đọc và đường lưu chọn ra
            hai khách khác nhau.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService.ExportDefaultPriceList(System.String,Lada.Framework.Data.Enums.PriceType)">
            <summary>
            Xuất danh sách giá mặc định ra file.
            </summary>
            <param name="filePath">Đường dẫn file.</param>
            <param name="priceType">Loại giá của bảng đang mở.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService.CopyPriceList(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CopyPriceListModel)">
            <summary>
            Sao chép bảng giá từ một phạm vi nguồn sang phạm vi đích.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService.BuildAxisOptionMap(System.Int32,System.Int32,System.Collections.Generic.List{Lada.Framework.Data.Domains.Finance.Quotations.Price},System.Collections.Generic.List{System.String})">
            <summary>
            Dựng ánh xạ lựa chọn trục nguồn → đích theo NHÃN, khi sao chép giữa hai loại hàng khác nhau.
            </summary>
            <param name="sourceCategoryId">Loại hàng nguồn.</param>
            <param name="targetCategoryId">Loại hàng đích.</param>
            <param name="sourceRows">Dòng giá nguồn — để bảo đảm mọi OptionId thật sự dùng đều ánh xạ được.</param>
            <param name="warnings">Nơi ghi cảnh báo không chặn (VD hai loại áp giá khác kiểu).</param>
            <returns><c>(map, null)</c> khi hợp lệ — <c>map</c> có thể null nếu cả hai loại không chia cột;
            <c>(null, câu lỗi)</c> khi hai loại không cùng thuộc tính trục.</returns>
            <remarks>
            "Cùng thuộc tính trục" nghĩa là: cùng có (hoặc cùng không có) thuộc tính
            <c>IsPriceAxis</c> kiểu chọn-một, TÊN thuộc tính trùng nhau, và mọi lựa chọn mà dòng giá
            nguồn đang dùng đều có lựa chọn cùng nhãn bên đích. Ánh xạ theo nhãn vì Id lựa chọn thuộc
            về từng loại hàng, không dùng chung được.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.PriceService.AxisOf(Lada.Framework.Data.Domains.Cms.GoodsCategoryConfig)">
            <summary>
            Thuộc tính trục giá của một cấu hình loại hàng — <c>IsPriceAxis</c> kiểu chọn-một, chưa xoá.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IReconciliationService">
            <summary>
            Giao diện cho dịch vụ quản lý đối soát.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IReconciliationService.SearchCustomersForReconciliation(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm khách hàng cần đối soát với phân trang.
            </summary>
            <param name="param">Tham số tìm kiếm.</param>
            <param name="userId">ID người dùng hiện tại.</param>
            <returns>Kết quả tìm kiếm khách hàng cần đối soát.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IReconciliationService.SearchReconciliableOrders(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32,System.Nullable{Lada.Framework.Data.Domains.Finance.ReconciliationType})">
            <summary>
            Tìm kiếm đơn hàng có thể đối soát với phân trang.
            </summary>
            <param name="param">Tham số tìm kiếm.</param>
            <param name="userId">Id người dùng hiện tại — dùng để ép phạm vi xem.</param>
            <param name="reconciliationType">Loại đối soát (tùy chọn).</param>
            <returns>Kết quả tìm kiếm đơn hàng có thể đối soát.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IReconciliationService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm đối soát.
            </summary>
            <param name="param">Tham số tìm kiếm.</param>
            <param name="userId">ID người dùng hiện tại.</param>
            <returns>Kết quả tìm kiếm đối soát.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IReconciliationService.GetById(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy chi tiết đối soát.
            </summary>
            <param name="id">ID đối soát.</param>
            <returns>Chi tiết đối soát.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IReconciliationService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel)">
            <summary>
            Tạo đối soát mới.
            </summary>
            <param name="model">Thông tin đối soát.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IReconciliationService.Confirm(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xác nhận đối soát.
            </summary>
            <param name="id">ID đối soát.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IReconciliationService.UpdateTransferred(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferReconciliationModel)">
            <summary>
            Cập nhật đã chuyển khoản.
            </summary>
            <param name="model">Thông tin chuyển khoản.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IReconciliationService.Cancel(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CancelReconciliationModel)">
            <summary>
            Hủy đối soát với thông tin chi tiết.
            </summary>
            <param name="model">Thông tin hủy đối soát.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IReconciliationService.Cancel(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Hủy đối soát (phương thức cũ - deprecated).
            </summary>
            <param name="id">ID đối soát.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.ReconciliationService">
            <summary>
            Dịch vụ quản lý đối soát.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Finances.ReconciliationService._franchiseDebts">
            <summary>Ví bưu cục v2: nhận ra đơn do bưu cục nhượng quyền bật ví bán — màn đối soát cũ không lập phiếu cho đơn này (§6 mục 21).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ReconciliationService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.Reconciliation},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.ReconciliationOrder},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.Order},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.OrderFin},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Crm.Customer},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.Wallets.Wallet},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.Wallets.Transaction},Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderTrackService,Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Crm.CustomerCoManager},Ladaer.BackEnd.Infrastructures.Services.Finance.IReconciliationVisibilityResolver,Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseReturnFeeDebtService)">
            <summary>
            Khởi tạo dịch vụ quản lý đối soát.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ReconciliationService.CoQuyenTruyCapKhachHangAsync(System.Int32,System.Int32,System.Int32)">
            <summary>
            Người này có được xem dữ liệu đối soát của một khách hàng hay không.
            </summary>
            <remarks>
            Cùng một nguồn luật với màn đối soát mới (<c>CustomerReconciliationSlipService</c>) — hai
            màn hình đọc gần như cùng một tập tiền, để chúng lệch luật là để lại đúng cái lỗ vừa vá.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ReconciliationService.SearchCustomersForReconciliation(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm khách hàng cần đối soát với phân trang.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ReconciliationService.SearchReconciliableOrders(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32,System.Nullable{Lada.Framework.Data.Domains.Finance.ReconciliationType})">
            <summary>
            Tìm kiếm đơn hàng có thể đối soát với phân trang.
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <param name="reconciliationType">Loại đối soát (tùy chọn)</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ReconciliationService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm đối soát.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ReconciliationService.GetById(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy chi tiết đối soát.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ReconciliationService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CreateReconciliationModel)">
            <summary>
            Tạo đối soát mới.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ReconciliationService.Confirm(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xác nhận đối soát.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ReconciliationService.UpdateTransferred(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferReconciliationModel)">
            <summary>
            Cập nhật đã chuyển khoản.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ReconciliationService.Cancel(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.CancelReconciliationModel)">
            <summary>
            Hủy đối soát với thông tin chi tiết.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ReconciliationService.Cancel(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Hủy đối soát (phương thức cũ - deprecated).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ReconciliationService.GenerateReconciliationCode">
            <summary>
            Tạo mã đối soát tự động
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.ReconciliationService.CreateReconciliationTransaction(Lada.Framework.Data.Domains.Finance.Reconciliation,Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferReconciliationModel)">
            <summary>
            Tạo giao dịch trừ tiền cho đối soát
            </summary>
            <param name="reconciliation">Thông tin đối soát</param>
            <param name="model">Model chuyển tiền</param>
            <returns></returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IRouteService">
            <summary>
            Giao diện cho dịch vụ quản lý tuyến vận tải.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IRouteService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm tuyến vận tải.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm tuyến vận tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IRouteService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.RouteModel)">
            <summary>
            Tạo mới hoặc cập nhật thông tin tuyến vận tải.
            </summary>
            <param name="model">Thông tin tuyến vận tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IRouteService.GetById(System.Int32)">
            <summary>
            Lấy thông tin tuyến vận tải theo ID.
            </summary>
            <param name="routeId">ID của tuyến vận tải.</param>
            <returns>Thông tin tuyến vận tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IRouteService.Delete(System.Int32)">
            <summary>
            Xóa tuyến vận tải theo ID.
            </summary>
            <param name="routeId">ID của tuyến vận tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.RouteService">
            <summary>
            Triển khai dịch vụ quản lý tuyến vận tải.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.RouteService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Finance.Quotations.Route})">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Finances.RouteService"/>.
            </summary>
            <param name="routeRepository">Đối tượng IRepository của Route.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.RouteService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm tuyến vận tải.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm tuyến vận tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.RouteService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.RouteModel)">
            <summary>
            Tạo mới hoặc cập nhật thông tin tuyến vận tải.
            </summary>
            <param name="model">Thông tin tuyến vận tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.RouteService.Create(Lada.Framework.Data.Domains.Finance.Quotations.Route)">
            <summary>
            Tạo mới tuyến vận tải.
            </summary>
            <param name="route">Thông tin tuyến vận tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.RouteService.Update(Lada.Framework.Data.Domains.Finance.Quotations.Route)">
            <summary>
            Cập nhật thông tin tuyến vận tải.
            </summary>
            <param name="route">Thông tin tuyến vận tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.RouteService.GetById(System.Int32)">
            <summary>
            Lấy thông tin tuyến vận tải theo ID.
            </summary>
            <param name="routeId">ID của tuyến vận tải.</param>
            <returns>Thông tin tuyến vận tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.RouteService.Delete(System.Int32)">
            <summary>
            Xóa tuyến vận tải theo ID.
            </summary>
            <param name="routeId">ID của tuyến vận tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.TransactionService.SearchWalletTransactions(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm giao dịch của ví.
            Chỉ Founder và Accountant mới được xem tất cả giao dịch, user khác chỉ xem ví của mình.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.TransactionService.GetTransactionDetail(System.Guid)">
            <summary>
            Lấy chi tiết giao dịch (chỉ cho TransactionType = 4)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.TransactionService.GetTransactionStatistics(System.Int32,System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset})">
            <summary>
            Lấy thống kê giao dịch theo loại
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.TransactionService.GetWalletBalanceHistory(System.Int32,System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset})">
            <summary>
            Lấy lịch sử số dư ví
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.TransactionService.GetTransactionIcon(Lada.Framework.Data.Enums.TransactionType)">
            <summary>
            Helper method để lấy icon cho loại giao dịch
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceService">
            <summary>
            Service quản lý hóa đơn VAT nội bộ (CRUD)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm hóa đơn VAT
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceSyncService">
            <summary>
            Service đồng bộ hóa đơn VAT từ API Tổng cục Thuế
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceSyncService.SyncInvoicesFromAPI(System.DateTimeOffset,System.DateTimeOffset,System.String,System.Nullable{System.Int32},System.Int32)">
            <summary>
            Đồng bộ hóa đơn từ API Tổng cục Thuế (tự động chia nhỏ nếu khoảng ngày > 30 ngày)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceSyncService.SyncInvoicesBatch(System.DateTimeOffset,System.DateTimeOffset,System.String,System.Nullable{System.Int32},System.Int32)">
            <summary>
            Đồng bộ hóa đơn cho một batch đơn lẻ (tối đa 30 ngày)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceSyncService.SyncYesterdayInvoices">
            <summary>
            Đồng bộ hóa đơn của ngày hôm qua
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceSyncService.SyncYesterdayPurchaseInvoices">
            <summary>
            Đồng bộ hóa đơn mua vào của ngày hôm qua
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceSyncService.GetLastSyncInfo">
            <summary>
            Lấy thông tin đồng bộ gần nhất
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceSyncService.RefreshBearerToken(System.String,System.Collections.Generic.List{Lada.Framework.Data.Domains.AppConfig})">
            <summary>
            Tự động lấy Bearer Token mới từ API GDT bằng cách giải captcha và đăng nhập
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceSyncService.SetCommonHeaders(System.Net.Http.HttpClient)">
            <summary>
            Set các header phổ biến giống browser cho request tới GDT
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceSyncService.FetchAndProcessInvoices(System.Net.Http.HttpClient,System.String,System.String,System.Int32,System.String,System.String,System.Int32,System.DateTimeOffset,System.Int32,System.Boolean)">
            <summary>
            Gọi API GDT và xử lý kết quả (insert/update hóa đơn) - hỗ trợ phân trang cursor-based
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceSyncService.MapToEntity(Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceSyncService.InvoiceData,System.String,System.DateTimeOffset,System.Int32,System.Int32)">
            <summary>
            Map dữ liệu từ API sang Entity
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceSyncService.UpdateEntity(Lada.Framework.Data.Domains.Finance.VatInvoice,Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceSyncService.InvoiceData,System.String,System.DateTimeOffset,System.Int32,System.Int32)">
            <summary>
            Cập nhật entity từ API data
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceSyncService.VietnamOffset">
            <summary>
            Parse date từ API (có thể là string hoặc long timestamp)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.VatInvoiceSyncService.TokenExpiredException">
            <summary>
            Exception đánh dấu token hết hạn để trigger retry logic
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VehicleLoanService.GetInterestRateForPeriod(Lada.Framework.Data.Domains.Finance.VehicleLoan,System.Int32)">
            <summary>
            Lấy lãi suất năm áp dụng cho kỳ (periodNumber) dựa trên bảng giai đoạn.
            Nếu không có giai đoạn nào khớp → fallback về InterestRate cố định trên VehicleLoan.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VehicleLoanService.RegenerateSchedule(System.Int32)">
            <summary>
            Xóa các kỳ chưa thanh toán (Pending) và tạo lại dựa trên lãi suất mới.
            Các kỳ đã thanh toán (Paid/PaidLate) sẽ không bị ảnh hưởng.
            Lưu ý: Sử dụng hard-delete cho pending schedules vì bảng có unique index
            trên (VehicleLoanId, PeriodNumber), soft-delete sẽ conflict với bản ghi mới.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VehicleLoanService.RegenerateScheduleForUpdate(Lada.Framework.Data.Domains.Finance.VehicleLoan,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.LoanInterestPeriodModel})">
            <summary>
            Regenerate lịch trả nợ khi cập nhật hợp đồng vay.
            Tránh reload loan entity (đã tracked) để không gây EF tracking conflict.
            Truy vấn schedules riêng, hard-delete pending, tạo lại với dữ liệu mới.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VehicleLoanService.UploadDocument(System.Int32,Microsoft.AspNetCore.Http.IFormFile,Lada.Framework.Data.Domains.Finance.VehicleLoanDocumentType,System.String)">
            <summary>
            Upload tài liệu cho hợp đồng vay
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VehicleLoanService.GetDocuments(System.Int32)">
            <summary>
            Lấy danh sách tài liệu của hợp đồng vay
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VehicleLoanService.DeleteDocument(System.Int32)">
            <summary>
            Xóa tài liệu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VehicleLoanService.GetDocumentTypeName(Lada.Framework.Data.Domains.Finance.VehicleLoanDocumentType)">
            <summary>
            Helper lấy tên loại tài liệu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VehicleLoanService.GetSettlement(System.Int32)">
            <summary>
            Lấy thông tin tất toán của khoản vay
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VehicleLoanService.CreateOrUpdateSettlement(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.LoanSettlementModel)">
            <summary>
            Tạo hoặc cập nhật tất toán (sync danh sách phí)
            Lưu ý: KHÔNG tạo Expense — Expense chỉ tạo khi duyệt phí
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VehicleLoanService.ApproveSettlementFee(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PaySettlementFeeModel)">
            <summary>
            Duyệt 1 khoản phí tất toán → Tạo Expense
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VehicleLoanService.UnapproveSettlementFee(Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.PaySettlementFeeModel)">
            <summary>
            Bỏ duyệt 1 khoản phí tất toán → Reject Expense liên kết
            Chỉ cho phép nếu Expense chưa thanh toán
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VehicleLoanService.DeleteSettlementFee(System.Int32)">
            <summary>
            Xóa 1 khoản phí tất toán (soft-delete)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VehicleLoanService.CompleteSettlement(System.Int32)">
            <summary>
            Hoàn tất tất toán: đánh dấu khoản vay Completed
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.VehicleLoanService.CancelSettlement(System.Int32)">
            <summary>
            Hủy tất toán
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IWalletService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm ví
            </summary>
            <param name="param"></param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IWalletService.BalanceAdjustment(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BalanceAdjustmentModel)">
            <summary>
            Điều chỉnh số dư ví (cân ví)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IWalletService.GetSuggestions(System.String)">
            <summary>
            Lấy danh sách ví cho suggestion (select control)
            </summary>
            <param name="keyword">Từ khóa tìm kiếm</param>
            <returns>Danh sách tối đa 20 ví</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.WalletService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm ví
            </summary>
            <param name="param"></param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.WalletService.SearchTransactions(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm giao dịch của ví
            </summary>
            <param name="param"></param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.WalletService.BalanceAdjustment(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.BalanceAdjustmentModel)">
            <summary>
            Điều chỉnh số dư ví bằng cách tạo giao dịch Income hoặc Outcome
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.WalletService.GetSuggestions(System.String)">
            <summary>
            Lấy danh sách ví cho suggestion (select control)
            </summary>
            <param name="keyword">Từ khóa tìm kiếm</param>
            <returns>Danh sách tối đa 20 ví</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.IWalletTransferService">
            <summary>
            Interface cho service chuyển tiền giữa các ví
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.IWalletTransferService.Transfer(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferWalletModel)">
            <summary>
            Chuyển tiền từ ví nguồn sang ví đích
            </summary>
            <param name="sourceWalletId">ID ví nguồn (ví của người dùng đang đăng nhập)</param>
            <param name="model">Thông tin chuyển tiền</param>
            <returns>Kết quả chuyển tiền</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.WalletTransferService">
            <summary>
            Service xử lý chuyển tiền giữa các ví với đảm bảo toàn vẹn giao dịch
            Sử dụng DB Transaction + Optimistic Concurrency (RowVersion)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.WalletTransferService.Transfer(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferWalletModel)">
            <summary>
            Chuyển tiền từ ví nguồn sang ví đích với đảm bảo toàn vẹn
            </summary>
            <param name="sourceWalletId">ID ví nguồn (ví của người dùng đang đăng nhập)</param>
            <param name="model">Thông tin chuyển tiền</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.WalletTransferService.ExecuteTransferAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferWalletModel,System.Guid)">
            <summary>
            Thực hiện giao dịch chuyển tiền trong DB Transaction
            </summary>
            <param name="sourceWalletId">ID ví nguồn</param>
            <param name="model">Thông tin chuyển tiền</param>
            <param name="transferGroupId">ID nhóm giao dịch</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finances.WalletTransferService.ValidateTransferRequest(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finances.TransferWalletModel)">
            <summary>
            Validate yêu cầu chuyển tiền
            </summary>
            <param name="sourceWalletId">ID ví nguồn</param>
            <param name="model">Thông tin chuyển tiền</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.WalletTransferService.ValidationResult">
            <summary>
            Kết quả validation
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finances.WalletTransferResult">
            <summary>
            Kết quả chuyển tiền
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Finances.WalletTransferResult.TransferGroupId">
            <summary>
            ID nhóm giao dịch (dùng để tra cứu 2 dòng transaction)
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Finances.WalletTransferResult.SourceTransactionId">
            <summary>
            ID giao dịch bên ví nguồn
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Finances.WalletTransferResult.DestTransactionId">
            <summary>
            ID giao dịch bên ví đích
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Finances.WalletTransferResult.SourceWalletNewBalance">
            <summary>
            Số dư mới của ví nguồn sau khi chuyển
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Finances.WalletTransferResult.DestWalletNewBalance">
            <summary>
            Số dư mới của ví đích sau khi chuyển
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.BankSeedService">
            <summary>
            Service để seed dữ liệu ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.BankSeedService.SeedBankDataAsync">
            <summary>
            Seed dữ liệu ngân hàng từ danh sách cung cấp
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.BankSeedService.GetBankData">
            <summary>
            Lấy dữ liệu ngân hàng từ danh sách được cung cấp
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.BankService">
            <summary>
            Service quản lý ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.BankService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm ngân hàng với phân trang
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.BankService.GetAll">
            <summary>
            Lấy tất cả ngân hàng đang hoạt động
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.BankService.GetById(System.Int32)">
            <summary>
            Lấy ngân hàng theo ID (trả về model để edit)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.BankService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.BankModel)">
            <summary>
            Tạo hoặc cập nhật ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.BankService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.BankModel)">
            <summary>
            Tạo ngân hàng mới
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.BankService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.BankModel)">
            <summary>
            Cập nhật ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.BankService.Delete(System.Int32)">
            <summary>
            Xóa ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.BankService.SugBank(System.String,System.Int32)">
            <summary>
            Gợi ý ngân hàng theo từ khóa (cho select option)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.ICustomerReconciliationSlipExcelService">
            <summary>
            Interface cho dịch vụ xuất Excel phiếu đối soát khách hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ICustomerReconciliationSlipExcelService.ExportCustomerReconciliationSlipsAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel)">
            <summary>
            Xuất Excel danh sách phiếu đối soát khách hàng
            </summary>
            <param name="userId">ID người dùng hiện tại — dùng để ép phạm vi xem</param>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ICustomerReconciliationSlipExcelService.ExportCustomerReconciliationSlipDetailAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel)">
            <summary>
            Xuất Excel chi tiết phiếu đối soát khách hàng
            </summary>
            <param name="slipId">ID phiếu đối soát</param>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ICustomerReconciliationSlipExcelService.ExportReconciliableOrdersAsync(System.Int32,System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel)">
            <summary>
            Xuất Excel danh sách đơn hàng cần đối soát của khách hàng
            </summary>
            <param name="customerId">ID khách hàng</param>
            <param name="userId">ID người dùng hiện tại</param>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService">
            <summary>
            Dịch vụ xuất Excel phiếu đối soát khách hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.ExportCustomerReconciliationSlipsAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel)">
            <summary>
            Xuất Excel danh sách phiếu đối soát khách hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.ExportCustomerReconciliationSlipDetailAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel)">
            <summary>
            Xuất Excel chi tiết phiếu đối soát khách hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.ExportReconciliableOrdersAsync(System.Int32,System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel)">
            <summary>
            Xuất Excel danh sách đơn hàng cần đối soát của khách hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.GetSlipsDataAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel)">
            <summary>
            Lấy dữ liệu phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.GetSlipDetailDataAsync(System.Int32)">
            <summary>
            Lấy dữ liệu chi tiết phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.CreateSlipsExcelPackageAsync(System.Collections.Generic.List{Lada.Framework.Data.Domains.Finance.CustomerReconciliationSlip},Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel)">
            <summary>
            Tạo ExcelPackage danh sách phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.CreateSlipDetailExcelPackageAsync(Lada.Framework.Data.Domains.Finance.CustomerReconciliationSlip,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel)">
            <summary>
            Tạo ExcelPackage chi tiết phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.AddCompanyHeader(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Thêm thông tin công ty vào đầu worksheet
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.AddSlipGeneralInfo(OfficeOpenXml.ExcelWorksheet,Lada.Framework.Data.Domains.Finance.CustomerReconciliationSlip)">
            <summary>
            Thêm thông tin chung phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.AddSlipOrdersDetail(OfficeOpenXml.ExcelWorksheet,Lada.Framework.Data.Domains.Finance.CustomerReconciliationSlip)">
            <summary>
            Thêm chi tiết đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.FormatSlipDetailWorksheet(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Định dạng worksheet chi tiết phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.SetupSlipsHeaders(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Thiết lập header cho danh sách phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.FillSlipsData(OfficeOpenXml.ExcelWorksheet,System.Collections.Generic.List{Lada.Framework.Data.Domains.Finance.CustomerReconciliationSlip})">
            <summary>
            Điền dữ liệu danh sách phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.FormatSlipsWorksheet(OfficeOpenXml.ExcelWorksheet,System.Int32)">
            <summary>
            Định dạng worksheet danh sách phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.GetStatusDescription(Lada.Framework.Data.Domains.Finance.CustomerReconciliationSlipStatus)">
            <summary>
            Lấy mô tả trạng thái
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.CreateReconciliableOrdersExcelPackageAsync(Lada.Framework.Data.Domains.Crm.Customer,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipDetailItem},Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerReconciliationSlipExcelExportModel)">
            <summary>
            Tạo ExcelPackage danh sách đơn hàng cần đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.AddReconciliableOrdersInfo(OfficeOpenXml.ExcelWorksheet,Lada.Framework.Data.Domains.Crm.Customer,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipDetailItem})">
            <summary>
            Thêm thông tin khách hàng và tổng hợp tài chính
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.AddReconciliableOrdersTable(OfficeOpenXml.ExcelWorksheet,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.CustomerReconciliationSlipDetailItem})">
            <summary>
            Thêm bảng đơn hàng cần đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipExcelService.FormatReconciliableOrdersWorksheet(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Định dạng worksheet danh sách đơn hàng cần đối soát
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipService._franchiseDebts">
            <summary>
            Ví bưu cục v2 (E8 / E13, plan §3.6 + §6 mục 21): đơn COD do bưu cục nhượng quyền bật ví bán trả khách = COD − cước chính thức − nợ
            cước đơn hoàn cùng khách; null = không móc ví (test cũ dựng service không có ví).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipService.CoQuyenTruyCapKhachHangAsync(System.Int32,System.Int32,System.Int32)">
            <summary>
            Người này có được xem dữ liệu đối soát của một khách hàng hay không.
            </summary>
            <remarks>
            Một chỗ duy nhất trả lời câu hỏi đó cho cả bốn đường đọc chạm tới một khách cụ thể
            (đơn có thể đối soát, chi tiết phiếu, nhật ký phiếu, tạo phiếu). Khách được coi là trong
            phạm vi khi sale phụ trách hoặc một người đồng quản lý nằm trong tập nhân sự mình xem được.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipService.ValidateSlipStatusForCompletion(Lada.Framework.Data.Domains.Finance.CustomerReconciliationSlip)">
            <summary>
            Validate trạng thái phiếu trước khi hoàn thành
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipService.GetOrCreateWalletAsync(Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy hoặc tạo ví Personal cho user
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipService.CreateWalletTransactionAsync(Lada.Framework.Data.Domains.Finance.CustomerReconciliationSlip,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CompleteCustomerReconciliationSlipModel,Lada.Framework.Infrastructures.CurrentUser,System.Boolean)">
            <summary>
            Tạo giao dịch ví cho phiếu đối soát (dùng chung cho cả Payable và Receivable)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipService.CompletePayableSlipAsync(Lada.Framework.Data.Domains.Finance.CustomerReconciliationSlip,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CompleteCustomerReconciliationSlipModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Hoàn thành phiếu Payable (thu tiền)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipService.UpdateOrdersForPayableSlipAsync(Lada.Framework.Data.Domains.Finance.CustomerReconciliationSlip,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Cập nhật đơn hàng cho phiếu Payable
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipService.CompleteReceivableSlipAsync(Lada.Framework.Data.Domains.Finance.CustomerReconciliationSlip,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CompleteCustomerReconciliationSlipModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Hoàn thành phiếu Receivable (chi tiền)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipService.UpdateOrdersForReceivableSlipAsync(Lada.Framework.Data.Domains.Finance.CustomerReconciliationSlip,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Cập nhật đơn hàng cho phiếu Receivable
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipService.CreateOrderTracksAsync(System.Collections.Generic.List{System.Int32},System.String,System.String,Lada.Framework.Data.Enums.TrackActionType,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo OrderTrack cho danh sách đơn hàng (dùng chung)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.CustomerReconciliationSlipService.ResolveProofImageUrlsAsync(System.String)">
            <summary>
            Resolve ProofImageUrl (có thể chứa nhiều system paths phân cách bởi ;) thành public URLs
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.IExpenseCategoryService">
            <summary>
            Interface cho service quản lý danh mục chi phí
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IExpenseCategoryService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh mục chi phí với phân trang
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IExpenseCategoryService.GetByIdAsync(System.Int32)">
            <summary>
            Lấy danh mục chi phí theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IExpenseCategoryService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExpenseCategoryModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo hoặc cập nhật danh mục chi phí
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IExpenseCategoryService.DeleteAsync(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa danh mục chi phí
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IExpenseCategoryService.GetAllAsync">
            <summary>
            Lấy danh sách tất cả danh mục chi phí (cho dropdown)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IExpenseCategoryService.IsNameExistsAsync(System.String,System.Int32)">
            <summary>
            Kiểm tra tên danh mục có trùng không
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IExpenseCategoryService.GetHierarchyAsync">
            <summary>
            Lấy danh sách danh mục chi phí theo cây phân cấp
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IExpenseCategoryService.GetRootCategoriesAsync">
            <summary>
            Lấy danh sách danh mục gốc (không có ParentId)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IExpenseCategoryService.GetChildrenAsync(System.Int32)">
            <summary>
            Lấy danh sách danh mục con theo ParentId
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IExpenseCategoryService.CanDeleteAsync(System.Int32)">
            <summary>
            Kiểm tra có thể xóa danh mục không (không có danh mục con)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.ExpenseCategoryService">
            <summary>
            Service quản lý danh mục chi phí
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExpenseCategoryService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh mục chi phí với phân trang
            Hỗ trợ hai chế độ hiển thị: List (danh sách) và Tree (cây phân cấp)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExpenseCategoryService.GetByIdAsync(System.Int32)">
            <summary>
            Lấy danh mục chi phí theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExpenseCategoryService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExpenseCategoryModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo hoặc cập nhật danh mục chi phí
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExpenseCategoryService.DeleteAsync(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa danh mục chi phí
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExpenseCategoryService.GetAllAsync">
            <summary>
            Lấy danh sách tất cả danh mục chi phí (cho dropdown)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExpenseCategoryService.IsNameExistsAsync(System.String,System.Int32)">
            <summary>
            Kiểm tra tên danh mục có trùng không
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExpenseCategoryService.GetHierarchyAsync">
            <summary>
            Lấy danh sách danh mục chi phí theo cây phân cấp
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExpenseCategoryService.GetRootCategoriesAsync">
            <summary>
            Lấy danh sách danh mục gốc (không có ParentId)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExpenseCategoryService.GetChildrenAsync(System.Int32)">
            <summary>
            Lấy danh sách danh mục con theo ParentId
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExpenseCategoryService.CanDeleteAsync(System.Int32)">
            <summary>
            Kiểm tra có thể xóa danh mục không (không có danh mục con)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExpenseCategoryService.PopulateApprovedByUserNames(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem})">
            <summary>
            Lấy thông tin tên người duyệt cho danh sách items
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExpenseCategoryService.BuildTreeStructure(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem})">
            <summary>
            Xây dựng cấu trúc cây từ danh sách phẳng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExpenseCategoryService.BuildHierarchy(Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.ExpenseCategoryItem},System.Int32)">
            <summary>
            Xây dựng cây phân cấp đệ quy
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.IExportOrderService">
            <summary>
            Interface cho dịch vụ xuất Excel thông tin đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IExportOrderService.ExportOrdersToExcelAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExportOrderModel)">
            <summary>
            Xuất Excel thông tin đơn hàng theo danh sách OrderId hoặc OrderCode
            </summary>
            <param name="model">Thông tin đầu vào</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IExportOrderService.ExportOrdersByIdsAsync(System.Collections.Generic.List{System.Int32},System.String)">
            <summary>
            Xuất Excel thông tin đơn hàng theo danh sách OrderId
            </summary>
            <param name="orderIds">Danh sách ID đơn hàng</param>
            <param name="filePath">Đường dẫn file Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IExportOrderService.ExportOrdersByCodesAsync(System.Collections.Generic.List{System.String},System.String)">
            <summary>
            Xuất Excel thông tin đơn hàng theo danh sách OrderCode
            </summary>
            <param name="orderCodes">Danh sách mã đơn hàng</param>
            <param name="filePath">Đường dẫn file Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.ExportOrderService">
            <summary>
            Dịch vụ xuất Excel thông tin đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExportOrderService.ExportOrdersToExcelAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ExportOrderModel)">
            <summary>
            Xuất Excel thông tin đơn hàng theo danh sách OrderId hoặc OrderCode
            </summary>
            <param name="model">Thông tin đầu vào</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExportOrderService.ExportOrdersByIdsAsync(System.Collections.Generic.List{System.Int32},System.String)">
            <summary>
            Xuất Excel thông tin đơn hàng theo danh sách OrderId
            </summary>
            <param name="orderIds">Danh sách ID đơn hàng</param>
            <param name="filePath">Đường dẫn file Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExportOrderService.ExportOrdersByCodesAsync(System.Collections.Generic.List{System.String},System.String)">
            <summary>
            Xuất Excel thông tin đơn hàng theo danh sách OrderCode
            </summary>
            <param name="orderCodes">Danh sách mã đơn hàng</param>
            <param name="filePath">Đường dẫn file Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExportOrderService.ProcessOrdersAndCreateExcel(System.Collections.Generic.List{Lada.Framework.Data.Domains.Orders.Order},System.Collections.Generic.List{System.String},System.String)">
            <summary>
            Xử lý danh sách đơn hàng và tạo file Excel
            </summary>
            <param name="orders">Danh sách đơn hàng</param>
            <param name="requestedItems">Danh sách ID/Code được yêu cầu</param>
            <param name="filePath">Đường dẫn file</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExportOrderService.CreateExcelFile(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem},System.String)">
            <summary>
            Tạo file Excel từ danh sách đơn hàng
            </summary>
            <param name="exportItems">Danh sách đơn hàng cần xuất</param>
            <param name="filePath">Đường dẫn file</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExportOrderService.SetupExcelHeaders(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Thiết lập header cho Excel
            </summary>
            <param name="worksheet">Worksheet</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExportOrderService.FillExcelData(OfficeOpenXml.ExcelWorksheet,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillExportOrderItem})">
            <summary>
            Điền dữ liệu vào Excel
            </summary>
            <param name="worksheet">Worksheet</param>
            <param name="exportItems">Danh sách đơn hàng</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ExportOrderService.FormatExcelWorksheet(OfficeOpenXml.ExcelWorksheet,System.Int32)">
            <summary>
            Định dạng Excel worksheet
            </summary>
            <param name="worksheet">Worksheet</param>
            <param name="dataRowCount">Số dòng dữ liệu</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ICustomerReconciliationSlipService.GetCustomersOverviewAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy danh sách khách hàng cần đối soát (có đơn hàng chưa đối soát)
            Sale chỉ thấy khách hàng của mình
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ICustomerReconciliationSlipService.GetReconciliableOrdersAsync(System.Int32,System.Int32)">
            <summary>
            Lấy danh sách đơn hàng có thể đối soát của một khách hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ICustomerReconciliationSlipService.CreateSlipAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateCustomerReconciliationSlipModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo phiếu đối soát mới
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ICustomerReconciliationSlipService.GetSlipsAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ICustomerReconciliationSlipService.GetSlipByIdAsync(System.Int32,System.Int32)">
            <summary>
            Lấy chi tiết phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ICustomerReconciliationSlipService.ApproveSlipAsync(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Duyệt phiếu (Kế toán)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ICustomerReconciliationSlipService.RejectSlipAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.RejectCustomerReconciliationSlipModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Từ chối phiếu (Kế toán)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ICustomerReconciliationSlipService.CompleteSlipAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CompleteCustomerReconciliationSlipModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Hoàn thành phiếu (Xác nhận thanh toán)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ICustomerReconciliationSlipService.UploadProofImagesAsync(System.Int32,System.Collections.Generic.List{Microsoft.AspNetCore.Http.IFormFile},Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Upload ảnh chứng từ cho phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ICustomerReconciliationSlipService.GetSlipLogsAsync(System.Int32,System.Int32)">
            <summary>
            Lấy lịch sử thao tác
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.IIncomeCategoryService">
            <summary>
            Interface cho service quản lý danh mục doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IIncomeCategoryService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh mục doanh thu với phân trang
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IIncomeCategoryService.GetByIdAsync(System.Int32)">
            <summary>
            Lấy danh mục doanh thu theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IIncomeCategoryService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeCategoryModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo hoặc cập nhật danh mục doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IIncomeCategoryService.DeleteAsync(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa danh mục doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IIncomeCategoryService.GetAllAsync">
            <summary>
            Lấy danh sách tất cả danh mục doanh thu (cho dropdown)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IIncomeCategoryService.IsNameExistsAsync(System.String,System.Int32)">
            <summary>
            Kiểm tra tên danh mục có trùng không
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IIncomeCategoryService.GetHierarchyAsync">
            <summary>
            Lấy danh sách danh mục doanh thu theo cây phân cấp
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IIncomeCategoryService.GetRootCategoriesAsync">
            <summary>
            Lấy danh sách danh mục gốc (không có ParentId)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IIncomeCategoryService.GetChildrenAsync(System.Int32)">
            <summary>
            Lấy danh sách danh mục con theo ParentId
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IIncomeCategoryService.CanDeleteAsync(System.Int32)">
            <summary>
            Kiểm tra có thể xóa danh mục không (không có danh mục con)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.IncomeCategoryService">
            <summary>
            Service quản lý danh mục doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IncomeCategoryService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh mục doanh thu với phân trang
            Hỗ trợ hai chế độ hiển thị: List (danh sách) và Tree (cây phân cấp)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IncomeCategoryService.GetByIdAsync(System.Int32)">
            <summary>
            Lấy danh mục doanh thu theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IncomeCategoryService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeCategoryModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo hoặc cập nhật danh mục doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IncomeCategoryService.DeleteAsync(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa danh mục doanh thu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IncomeCategoryService.GetAllAsync">
            <summary>
            Lấy danh sách tất cả danh mục doanh thu (cho dropdown)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IncomeCategoryService.IsNameExistsAsync(System.String,System.Int32)">
            <summary>
            Kiểm tra tên danh mục có trùng không
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IncomeCategoryService.GetHierarchyAsync">
            <summary>
            Lấy danh sách danh mục doanh thu theo cây phân cấp
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IncomeCategoryService.GetRootCategoriesAsync">
            <summary>
            Lấy danh sách danh mục gốc (không có ParentId)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IncomeCategoryService.GetChildrenAsync(System.Int32)">
            <summary>
            Lấy danh sách danh mục con theo ParentId
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IncomeCategoryService.CanDeleteAsync(System.Int32)">
            <summary>
            Kiểm tra có thể xóa danh mục không (không có danh mục con)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IncomeCategoryService.PopulateApprovedByUserNames(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.IncomeCategoryItem})">
            <summary>
            Lấy thông tin tên người duyệt cho danh sách items
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IncomeCategoryService.BuildTreeStructure(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.IncomeCategoryItem})">
            <summary>
            Xây dựng cấu trúc cây từ danh sách phẳng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IncomeCategoryService.BuildHierarchy(Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.IncomeCategoryItem,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.IncomeCategoryItem},System.Int32)">
            <summary>
            Xây dựng cây phân cấp đệ quy
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.IUserBankAccountService">
            <summary>
            Interface service quản lý tài khoản ngân hàng người dùng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IUserBankAccountService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm tài khoản ngân hàng người dùng
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Kết quả tìm kiếm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IUserBankAccountService.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết tài khoản ngân hàng theo ID
            </summary>
            <param name="id">ID tài khoản ngân hàng</param>
            <returns>Thông tin chi tiết tài khoản ngân hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IUserBankAccountService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UserBankAccountModel)">
            <summary>
            Tạo mới hoặc cập nhật tài khoản ngân hàng
            </summary>
            <param name="model">Thông tin tài khoản ngân hàng</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IUserBankAccountService.Delete(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UserBankAccountModel)">
            <summary>
            Xóa tài khoản ngân hàng
            </summary>
            <param name="model">Thông tin tài khoản ngân hàng cần xóa</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IUserBankAccountService.GetByUserId(System.Int32)">
            <summary>
            Lấy danh sách tài khoản ngân hàng của người dùng
            </summary>
            <param name="userId">ID người dùng</param>
            <returns>Danh sách tài khoản ngân hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IUserBankAccountService.SearchByUserId(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm tài khoản ngân hàng của người dùng cụ thể
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <param name="userId">ID người dùng</param>
            <returns>Kết quả tìm kiếm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IUserBankAccountService.GetByIdAndUserId(System.Int32,System.Int32)">
            <summary>
            Lấy tài khoản ngân hàng theo ID và kiểm tra quyền sở hữu
            </summary>
            <param name="id">ID tài khoản ngân hàng</param>
            <param name="userId">ID người dùng</param>
            <returns>Thông tin tài khoản ngân hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IUserBankAccountService.DeleteByIdAndUserId(System.Int32,System.Int32,System.Int32,System.String)">
            <summary>
            Xóa tài khoản ngân hàng với kiểm tra quyền sở hữu
            </summary>
            <param name="id">ID tài khoản ngân hàng</param>
            <param name="userId">ID người dùng</param>
            <param name="updatedBy">ID người cập nhật</param>
            <param name="updatedByUserName">Tên người cập nhật</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.IReconciliationExcelService">
            <summary>
            Interface cho dịch vụ xuất Excel phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IReconciliationExcelService.ExportReconciliationsAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel)">
            <summary>
            Xuất Excel danh sách phiếu đối soát
            </summary>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IReconciliationExcelService.ExportReconciliationDetailAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel)">
            <summary>
            Xuất Excel chi tiết phiếu đối soát
            </summary>
            <param name="reconciliationId">ID phiếu đối soát</param>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService">
            <summary>
            Dịch vụ xuất Excel phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.ExportReconciliationsAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel)">
            <summary>
            Xuất Excel danh sách phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.ExportReconciliationDetailAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel)">
            <summary>
            Xuất Excel chi tiết phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.GetReconciliationsDataAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel)">
            <summary>
            Lấy dữ liệu phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.GetReconciliationDetailDataAsync(System.Int32)">
            <summary>
            Lấy dữ liệu chi tiết phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.CreateReconciliationExcelPackageAsync(System.Collections.Generic.List{Lada.Framework.Data.Domains.Finance.Reconciliation},Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel)">
            <summary>
            Tạo ExcelPackage danh sách phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.CreateReconciliationDetailExcelPackageAsync(Lada.Framework.Data.Domains.Finance.Reconciliation,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ReconciliationExcelExportModel)">
            <summary>
            Tạo ExcelPackage chi tiết phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.AddCompanyHeader(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Thêm thông tin công ty vào đầu worksheet
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.AddReconciliationGeneralInfo(OfficeOpenXml.ExcelWorksheet,Lada.Framework.Data.Domains.Finance.Reconciliation)">
            <summary>
            Thêm thông tin chung phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.AddReconciliationOrdersDetail(OfficeOpenXml.ExcelWorksheet,Lada.Framework.Data.Domains.Finance.Reconciliation)">
            <summary>
            Thêm chi tiết đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.GetSenderAddress(Lada.Framework.Data.Domains.Orders.Order)">
            <summary>
            Lấy địa chỉ gửi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.GetReceiverAddress(Lada.Framework.Data.Domains.Orders.Order)">
            <summary>
            Lấy địa chỉ nhận
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.GetOrderProducts(Lada.Framework.Data.Domains.Orders.Order)">
            <summary>
            Lấy thông tin sản phẩm
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.GetOrderFinancialInfo(Lada.Framework.Data.Domains.Orders.Order)">
            <summary>
            Lấy thông tin tài chính đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.FormatReconciliationDetailWorksheet(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Định dạng worksheet chi tiết phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.SetupReconciliationHeaders(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Thiết lập header cho danh sách phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.FillReconciliationData(OfficeOpenXml.ExcelWorksheet,System.Collections.Generic.List{Lada.Framework.Data.Domains.Finance.Reconciliation})">
            <summary>
            Điền dữ liệu danh sách phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.FormatReconciliationWorksheet(OfficeOpenXml.ExcelWorksheet,System.Int32)">
            <summary>
            Định dạng worksheet danh sách phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationExcelService.GetStatusDescription(Lada.Framework.Data.Domains.Finance.ReconciliationStatus)">
            <summary>
            Lấy mô tả trạng thái
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibility">
            <summary>
            Phạm vi dữ liệu đối soát của một người dùng: hoặc không giới hạn, hoặc một tập nhân sự cụ thể.
            </summary>
            <remarks>
            Cố ý KHÔNG trả <c>List&lt;int&gt;</c> trần. Danh sách rỗng có hai nghĩa trái ngược nhau —
            "không thấy gì" và "thấy tất cả" — và mọi bên gọi sẽ phải tự nhớ nghĩa nào là nghĩa nào.
            Kiểu này ép bên gọi hỏi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibility.Unrestricted"/> trước.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibility.Unrestricted">
            <summary>Không giới hạn phạm vi — Founder và kế toán.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibility.VisibleStaffIds">
            <summary>Tập nhân sự xem được, chỉ có nghĩa khi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibility.Unrestricted"/> là false.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibility.IsEmpty">
            <summary>Không xem được dòng nào — tài khoản không xác định được, fail-closed.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibility.Narrow(System.Int32)">
            <summary>
            Thu hẹp phạm vi theo một nhân sự do người dùng chỉ định (bộ lọc trên giao diện).
            </summary>
            <remarks>
            Bộ lọc của client chỉ được **thu hẹp** tập đang xem được: truyền id của người ngoài phạm vi
            vào thì giao ra rỗng chứ không lấy thêm được dòng nào (chống IDOR).
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.IReconciliationVisibilityResolver">
            <summary>
            Nguồn duy nhất của luật "ai xem được phiếu đối soát của ai".
            </summary>
            <remarks>
            <para>
            Miền đối soát có <b>bảy</b> đường đọc cùng một tập dữ liệu — danh sách khách cần đối soát,
            danh sách phiếu, chi tiết phiếu, đơn có thể đối soát, nhật ký phiếu và hai đường xuất Excel.
            Trước bản này mỗi đường tự chép lại luật và đã lệch nhau thật: chi tiết phiếu cho qua bất kỳ ai
            có role <c>CustomerReconciliationSlip.View</c> (tức cả nhóm "Kinh doanh"), còn xuất Excel danh
            sách phiếu thì không nhận <c>userId</c> nên xuất toàn bộ phiếu của công ty.
            </para>
            <para>
            Ba cấp phạm vi, tính từ đúng hai cây phân cấp mà hệ thống đang dùng ở các miền khác
            (KPI, chat, bảo dưỡng) — không dựng cây thứ ba:
            </para>
            <list type="bullet">
            <item>Nhân viên: chỉ khách mình phụ trách (<c>Customer.ManagerId</c> hoặc đồng quản lý).</item>
            <item>Quản lý nhóm: thêm cấp dưới theo <c>UserPreference.ManagerId</c>, đệ quy hết cây.</item>
            <item>Quản lý chi nhánh / mạng lưới: thêm nhân sự của các chi nhánh mình đứng tên quản lý
            (<c>Agency.ManagerId</c>) và toàn bộ chi nhánh con cháu của chúng.</item>
            </list>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.IReconciliationVisibilityResolver.ResolveAsync(System.Int32)">
            <summary>
            Phạm vi của một người dùng. Người không xác định được thì không thấy gì (fail-closed).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibilityResolver">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Finance.IReconciliationVisibilityResolver" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibilityResolver.RoleFounder">
            <summary>Founder bỏ qua mọi ràng buộc phạm vi ở tầng máy chủ.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibilityResolver.RoleAccountant">
            <summary>Kế toán đối soát toàn công ty — vốn đã là luật của miền này từ trước.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibilityResolver.MaxDoSauCayQuanLy">
            <summary>
            Chặn vòng lặp dữ liệu khi duyệt cây quản lý nhân sự. Cây thật sâu 3–4 tầng; 10 là mức
            không bao giờ chạm tới trong nghiệp vụ nhưng vẫn cứu được nếu ai đó trỏ vòng A→B→A.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibilityResolver._userRepository">
            <summary>
            <c>IUserRepository</c> chứ không phải <c>IRepository&lt;User&gt;</c>: <c>Repository&lt;T&gt;</c>
            ràng buộc <c>T : BaseEntity</c> còn <c>User</c> kế thừa <c>IdentityUser&lt;int&gt;</c>, nên
            bản generic biên dịch xanh nhưng ném ngay khi DI dựng service.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibilityResolver.LayCapDuoiTheoCayQuanLyAsync(System.Int32)">
             <summary>
             Cấp dưới theo cây quản lý nhân sự, đệ quy hết các tầng.
             </summary>
             <remarks>
             Đọc <c>UserPreference.ManagerId</c>, KHÔNG phải <c>User.ManagerId</c>: cột trên User chỉ
             còn nghĩa cũ "sale quản lý khách hàng" và không luồng nào ghi cho nhân viên (đo trên DB
             2026-08-14: 0/131 nhân viên có <c>User.ManagerId &gt; 0</c>, 46 người có
             <c>UserPreference.ManagerId &gt; 0</c>). Cùng nguồn với <c>KpiVisibilityResolver</c>.
            
             Khác KPI ở chỗ đi hết cây thay vì dừng ở cấp dưới trực tiếp: trưởng phòng kinh doanh quản
             lý trưởng nhóm, trưởng nhóm quản lý sale — dừng ở một tầng thì trưởng phòng không thấy
             tiền COD của chính tệp khách phòng mình.
             </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibilityResolver.LayNhanSuCacChiNhanhMinhQuanLyAsync(System.Int32)">
            <summary>
            Nhân sự thuộc các chi nhánh mà người này đứng tên quản lý, kể cả chi nhánh con cháu.
            </summary>
            <remarks>
            Mở theo <c>Agency.ManagerId</c> chứ KHÔNG theo <c>User.AgencyId</c> của chính người dùng:
            lấy theo chi nhánh của bản thân thì mọi sale ngồi cùng bưu cục cũng thấy tiền của nhau,
            đúng thứ bản vá này đang chữa. Chỉ người đứng tên quản lý chi nhánh mới được mở rộng.
            Cây chi nhánh duyệt bằng <c>IAgencyService.GetAgencyWithDescendantIdsAsync</c> (đệ quy đầy
            đủ, có cache 10 phút) — cùng hàm mà phân hệ bảo dưỡng và điều phối đang dùng.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.ITaxInvoiceService">
            <summary>
            Interface dịch vụ quản lý hóa đơn thuế
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.TaxInvoiceService">
            <summary>
            Dịch vụ quản lý hóa đơn thuế
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TaxInvoiceService.CreateTaxInvoiceAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateTaxInvoiceModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo hóa đơn thuế mới
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TaxInvoiceService.UpdateTaxInvoiceStatusAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UpdateTaxInvoiceStatusModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Cập nhật trạng thái hóa đơn thuế
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TaxInvoiceService.GetTaxInvoiceByIdAsync(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy thông tin hóa đơn thuế theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TaxInvoiceService.GetTaxInvoiceBySlipIdAsync(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy thông tin hóa đơn thuế theo ID phiếu đối soát
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TaxInvoiceService.DeleteTaxInvoiceAsync(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa hóa đơn thuế (chỉ cho phép xóa khi ở trạng thái NotIssued)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TaxInvoiceService.IsValidStatusTransition(Lada.Framework.Data.Domains.Finance.TaxInvoiceStatus,Lada.Framework.Data.Domains.Finance.TaxInvoiceStatus)">
            <summary>
            Kiểm tra chuyển trạng thái hợp lệ
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TaxInvoiceService.MapToItem(Lada.Framework.Data.Domains.Finance.TaxInvoice)">
            <summary>
            Map entity sang item using AutoMapper
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TaxInvoiceService.GetVatRateAsync">
            <summary>
            Lấy VAT rate từ cấu hình với fallback mặc định 8%
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.ITransferPaymentBillExcelService">
            <summary>
            Interface cho dịch vụ xuất Excel phiếu chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ITransferPaymentBillExcelService.ExportTransferPaymentBillsAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel)">
            <summary>
            Xuất Excel danh sách phiếu chuyển khoản
            </summary>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ITransferPaymentBillExcelService.ExportTransferPaymentBillDetailAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel)">
            <summary>
            Xuất Excel chi tiết phiếu chuyển khoản
            </summary>
            <param name="transferPaymentBillId">ID phiếu chuyển khoản</param>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.ITransferPaymentBillExcelService.ExportCustomerTransferableOrdersAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersExcelExportModel)">
            <summary>
            Xuất Excel danh sách đơn hàng nợ cước của khách hàng
            </summary>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService">
            <summary>
            Dịch vụ xuất Excel phiếu chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.ExportTransferPaymentBillsAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel)">
            <summary>
            Xuất Excel danh sách phiếu chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.ExportTransferPaymentBillDetailAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel)">
            <summary>
            Xuất Excel chi tiết phiếu chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.GetTransferPaymentBillsDataAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel)">
            <summary>
            Lấy dữ liệu phiếu chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.GetTransferPaymentBillDetailDataAsync(System.Int32)">
            <summary>
            Lấy dữ liệu chi tiết phiếu chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.CreateTransferPaymentBillExcelPackageAsync(System.Collections.Generic.List{Lada.Framework.Data.Domains.Finance.TransferPaymentBill},Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel)">
            <summary>
            Tạo ExcelPackage danh sách phiếu chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.CreateTransferPaymentBillDetailExcelPackageAsync(Lada.Framework.Data.Domains.Finance.TransferPaymentBill,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.TransferPaymentBillExcelExportModel)">
            <summary>
            Tạo ExcelPackage chi tiết phiếu chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.AddCompanyHeader(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Thêm thông tin công ty vào đầu worksheet
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.AddTransferPaymentBillGeneralInfo(OfficeOpenXml.ExcelWorksheet,Lada.Framework.Data.Domains.Finance.TransferPaymentBill)">
            <summary>
            Thêm thông tin chung phiếu chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.AddTransferPaymentBillOrdersDetail(OfficeOpenXml.ExcelWorksheet,Lada.Framework.Data.Domains.Finance.TransferPaymentBill)">
            <summary>
            Thêm chi tiết đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.GetSenderAddress(Lada.Framework.Data.Domains.Orders.Order)">
            <summary>
            Lấy địa chỉ gửi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.GetReceiverAddress(Lada.Framework.Data.Domains.Orders.Order)">
            <summary>
            Lấy địa chỉ nhận
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.GetOrderProducts(Lada.Framework.Data.Domains.Orders.Order)">
            <summary>
            Lấy thông tin sản phẩm
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.GetOrderFinancialInfo(Lada.Framework.Data.Domains.Orders.Order)">
            <summary>
            Lấy thông tin tài chính đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.FormatTransferPaymentBillDetailWorksheet(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Định dạng worksheet chi tiết phiếu chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.SetupTransferPaymentBillHeaders(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Thiết lập header cho danh sách phiếu chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.FillTransferPaymentBillData(OfficeOpenXml.ExcelWorksheet,System.Collections.Generic.List{Lada.Framework.Data.Domains.Finance.TransferPaymentBill})">
            <summary>
            Điền dữ liệu danh sách phiếu chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.FormatTransferPaymentBillWorksheet(OfficeOpenXml.ExcelWorksheet,System.Int32)">
            <summary>
            Định dạng worksheet danh sách phiếu chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.GetStatusDescription(Lada.Framework.Data.Domains.Finance.TransferPaymentBillStatus)">
            <summary>
            Lấy mô tả trạng thái
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.GetPriorityDescription(Lada.Framework.Data.Domains.Finance.TransferPaymentBillPriority)">
            <summary>
            Lấy mô tả mức độ ưu tiên
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.ExportCustomerTransferableOrdersAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersExcelExportModel)">
            <summary>
            Xuất Excel danh sách đơn hàng nợ cước của khách hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.GetCustomerTransferableOrdersDataAsync(System.Int32)">
            <summary>
            Lấy dữ liệu đơn hàng nợ cước của khách hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.CreateCustomerTransferableOrdersExcelPackageAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersExcelExportModel)">
            <summary>
            Tạo ExcelPackage danh sách đơn hàng nợ cước của khách hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.AddCompanyHeaderForOrders(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Thêm thông tin công ty vào đầu worksheet cho đơn hàng nợ cước
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.AddCustomerInfo(OfficeOpenXml.ExcelWorksheet,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerInfoModel,System.Int32,System.Decimal)">
            <summary>
            Thêm thông tin khách hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.AddTransferableOrdersDetail(OfficeOpenXml.ExcelWorksheet,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Finance.TransferPaymentBillOrderItem},Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersExcelExportModel)">
            <summary>
            Thêm chi tiết đơn hàng nợ cước
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillExcelService.FormatCustomerTransferableOrdersWorksheet(OfficeOpenXml.ExcelWorksheet,System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CustomerTransferableOrdersExcelExportModel)">
            <summary>
            Định dạng worksheet danh sách đơn hàng nợ cước
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillService">
            <summary>
            Service quản lý hóa đơn thanh toán chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillService.SearchCustomersForTransferPayment(Lada.Framework.DTO.SmartTable.SmartTableParam,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tìm kiếm khách hàng có đơn hàng cần tạo hóa đơn thanh toán chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillService.GetTransferableOrdersByCustomer(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy danh sách đơn hàng có thể tạo hóa đơn thanh toán của khách hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CreateTransferPaymentBillModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo hóa đơn thanh toán chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillService.CalculatePriority(System.DateTimeOffset)">
            <summary>
            Tính mức độ ưu tiên dựa trên ngày tạo đơn hàng cũ nhất
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillService.GenerateTransferPaymentBillCode">
            <summary>
            Generate mã hóa đơn không trùng lặp với retry logic
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tìm kiếm danh sách hóa đơn thanh toán chuyển khoản
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillService.GetById(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy chi tiết hóa đơn thanh toán theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillService.Cancel(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.CancelTransferPaymentBillModel)">
            <summary>
            Hủy hóa đơn thanh toán chuyển khoản với thông tin chi tiết
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillService.Cancel(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Hủy hóa đơn thanh toán chuyển khoản (phương thức cũ - deprecated)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.TransferPaymentBillService.Approve(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.ApproveTransferPaymentBillModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Duyệt hóa đơn thanh toán chuyển khoản
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Finance.UserBankAccountService">
            <summary>
            Service quản lý tài khoản ngân hàng người dùng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.UserBankAccountService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm tài khoản ngân hàng người dùng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.UserBankAccountService.GetById(System.Int32)">
            <summary>
            Lấy thông tin chi tiết tài khoản ngân hàng theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.UserBankAccountService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UserBankAccountModel)">
            <summary>
            Tạo mới hoặc cập nhật tài khoản ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.UserBankAccountService.Delete(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.UserBankAccountModel)">
            <summary>
            Xóa tài khoản ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.UserBankAccountService.GetByUserId(System.Int32)">
            <summary>
            Lấy danh sách tài khoản ngân hàng của người dùng
            </summary>
            <param name="userId">ID người dùng</param>
            <returns>Danh sách tài khoản ngân hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.UserBankAccountService.SearchByUserId(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm tài khoản ngân hàng của người dùng cụ thể
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <param name="userId">ID người dùng</param>
            <returns>Kết quả tìm kiếm</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.UserBankAccountService.GetByIdAndUserId(System.Int32,System.Int32)">
            <summary>
            Lấy tài khoản ngân hàng theo ID và kiểm tra quyền sở hữu
            </summary>
            <param name="id">ID tài khoản ngân hàng</param>
            <param name="userId">ID người dùng</param>
            <returns>Thông tin tài khoản ngân hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Finance.UserBankAccountService.DeleteByIdAndUserId(System.Int32,System.Int32,System.Int32,System.String)">
            <summary>
            Xóa tài khoản ngân hàng với kiểm tra quyền sở hữu
            </summary>
            <param name="id">ID tài khoản ngân hàng</param>
            <param name="userId">ID người dùng</param>
            <param name="updatedBy">ID người cập nhật</param>
            <param name="updatedByUserName">Tên người cập nhật</param>
            <returns>Kết quả của thao tác</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardService">
            <summary>
            Interface cho service quản lý thẻ xăng dầu (thẻ tín dụng)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm thẻ xăng dầu với phân trang
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardService.GetByIdAsync(System.Int32)">
            <summary>
            Lấy thẻ xăng dầu theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardService.GetByQrCodeAsync(System.String)">
            <summary>
            Lấy thẻ xăng dầu theo QR Code
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo hoặc cập nhật thẻ xăng dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardService.DeleteAsync(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa thẻ xăng dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardService.GetActiveCardsAsync">
            <summary>
            Lấy danh sách thẻ đang hoạt động
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardService.GetTotalDebtAsync">
            <summary>
            Lấy tổng nợ thẻ tín dụng chưa thanh toán cho ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardService.SugFuelCard(System.String)">
            <summary>
            Tìm kiếm thẻ xăng dầu cho autocomplete (SugFuelCard)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardService.GetHistoryAsync(System.Int32)">
            <summary>
            Lấy lịch sử thẻ xăng dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardService.GetMyFuelCardAsync(System.Int32)">
            <summary>
            Lấy thẻ xăng dầu mà lái xe đang được gán (bao gồm cả PendingAccept)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardService.ConfirmReceiveFuelCardAsync(System.Int32,System.Collections.Generic.List{Microsoft.AspNetCore.Http.IFormFile},System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lái xe xác nhận nhận thẻ (kèm ảnh minh chứng)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardService.ReturnFuelCardAsync(System.Int32,System.Collections.Generic.List{Microsoft.AspNetCore.Http.IFormFile},System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lái xe trả thẻ (kèm ảnh minh chứng)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardService.RecalculateDebtAsync(System.Int32)">
            <summary>
            Tính lại nợ hiện tại cho thẻ dựa trên sao kê và giao dịch chưa thanh toán.
            Đây là single source of truth cho công thức tính nợ.
            Gọi method này sau mỗi mutation (import/delete/update transaction, pay statement).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelCardService">
            <summary>
            Service quản lý thẻ xăng dầu (thẻ tín dụng)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelCardService.SugFuelCard(System.String)">
            <summary>
            Tìm kiếm thẻ xăng dầu cho autocomplete
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelCardService.CreateHandoverAsync(System.Int32,System.Nullable{System.Int32},System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo record bàn giao thẻ mới (PendingAccept)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelCardService.CloseActiveHandoverAsync(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Đóng handover đang active (PendingAccept/Received) cho thẻ
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelCardService.ProcessHandoverMediaAsync(System.Int32,System.Collections.Generic.List{Microsoft.AspNetCore.Http.IFormFile},Lada.Framework.Data.Enums.FuelCardHandoverMediaType,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Upload ảnh bàn giao thẻ (pattern giống TruckActivityService.ProcessActivityMedia)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelCardService.RecalculateDebtAsync(System.Int32)">
            <summary>
            Tính lại nợ hiện tại cho thẻ dựa trên sao kê và giao dịch chưa thanh toán.
            Công thức: CurrentDebt = (Nợ từ các kỳ sao kê chưa trả hết) + (Chi tiêu chưa gắn kỳ sao kê chưa trả NH)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardTransactionService">
            <summary>
            Interface cho service quản lý giao dịch thẻ tín dụng xăng dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardTransactionService.ImportStatementAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionImportModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Import sao kê thẻ tín dụng từ Excel
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardTransactionService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Nullable{System.Int32})">
            <summary>
            Tìm kiếm giao dịch thẻ
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardTransactionService.GetByIdAsync(System.Guid)">
            <summary>
            Lấy chi tiết giao dịch
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardTransactionService.ReconcileWithRefillAsync(System.Guid,System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Đối soát giao dịch thẻ với lần đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardTransactionService.MarkAsPaidToBankAsync(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Đánh dấu đã thanh toán cho ngân hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardTransactionService.ImportTransactionHistoryAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionHistoryImportModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Import lịch sử giao dịch thẻ xăng dầu từ Excel.
            Tự động mapping thẻ dựa vào số thẻ trong file.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardTransactionService.BulkDeleteAsync(System.Collections.Generic.List{System.Guid},Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy danh sách giao dịch chưa đối soát theo thẻ và ngày
            </summary>
            <summary>
            Xóa giao dịch thẻ
            </summary>
            <summary>
            Xóa nhiều giao dịch thẻ cùng lúc
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelCardTransactionService.UpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionUpdateModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Cập nhật giao dịch thẻ
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelCardTransactionService">
            <summary>
            Service quản lý giao dịch thẻ tín dụng xăng dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelCardTransactionService.ImportTransactionHistoryAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelCardTransactionHistoryImportModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Import lịch sử giao dịch thẻ xăng dầu từ file Excel.
            Tự động mapping thẻ dựa vào cột "Tài khoản thẻ/ Số thẻ".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelCardTransactionService.ColumnMapping.HasSeparateCreditDebit">
            <summary>
            True nếu file dùng format VPBank (2 cột Ghi có / Ghi nợ riêng)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelCardTransactionService.ParseAmountFromCreditDebit(OfficeOpenXml.ExcelWorksheet,System.Int32,Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelCardTransactionService.ColumnMapping)">
            <summary>
            Parse số tiền từ 2 cột Ghi có / Ghi nợ riêng biệt (VPBank format)
            Ghi nợ = chi tiêu (trả về âm), Ghi có = thanh toán NH (trả về dương)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelCardTransactionService.ParseAmountFromText(System.String,OfficeOpenXml.ExcelRange)">
            <summary>
            Parse số tiền từ text (xử lý VND suffix, thousand separators, etc.)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelCardTransactionService.BulkDeleteAsync(System.Collections.Generic.List{System.Guid},Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa nhiều giao dịch thẻ cùng lúc
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillExcelService">
            <summary>
            Interface cho dịch vụ xuất Excel lịch sử đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillExcelService.ExportFuelRefillsAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Xuất Excel lịch sử đổ dầu
            </summary>
            <param name="param">Tham số tìm kiếm và sắp xếp</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillExcelService">
            <summary>
            Dịch vụ xuất Excel lịch sử đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillExcelService.ExportFuelRefillsAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Xuất Excel lịch sử đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillExcelService.GetRefillsDataAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy dữ liệu lịch sử đổ dầu (không phân trang)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillExcelService.CreateExcelPackage(System.Collections.Generic.List{Lada.Framework.Data.Domains.Trucks.FuelRefill})">
            <summary>
            Tạo ExcelPackage
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillExcelService.SetupHeaders(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Thiết lập header
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillExcelService.FillData(OfficeOpenXml.ExcelWorksheet,System.Collections.Generic.List{Lada.Framework.Data.Domains.Trucks.FuelRefill})">
            <summary>
            Điền dữ liệu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillExcelService.FormatWorksheet(OfficeOpenXml.ExcelWorksheet,System.Int32)">
            <summary>
            Định dạng worksheet
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillNavPermissions">
            <summary>
            Luật "ai thấy nút nào" của màn Lịch sử đổ dầu (<c>/lich-su-do-dau</c>).
            </summary>
            <remarks>
            <para>
            <b>Hàm thuần</b> — không chạm database, không đọc <c>HttpContext</c>: nhận danh sách role đã phân giải qua
            <c>IUserRoleResolver</c>, trả các cờ. Controller thì không test được sạch vì <c>User.GetCurrentUser()</c>
            nuốt mọi ngoại lệ rồi trả <c>UserId = 0</c>.
            </para>
            <para>
            Mỗi cờ đọc đúng role của endpoint nó gác, cộng <c>Founder</c>. Đổi role trên một endpoint mà quên cờ là test
            <c>FuelRefillNavPermissionsTests</c> đỏ (đọc <c>[Authorize(Roles)]</c> thật bằng reflection).
            </para>
            <para>
            Cờ chỉ gác lời gọi chính của nút. Lời gọi phụ trong hộp thoại (form sửa cần <c>Truck.GetLastRefillOdo</c>,
            hộp thoại Duyệt cần <c>FuelCard.GetUnreconciledTransactions</c>) được cấp kèm theo nhóm quyền ở migration
            <c>202610281400</c> — gán role tay cho người dùng thì nhớ gán đủ bộ.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillNavPermissions.Founder">
            <summary>Vai bỏ qua mọi kiểm tra role của hệ thống — ẩn nút của Founder là dựng hàng rào không có thật.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillNavPermissions.Resolve(System.Collections.Generic.IEnumerable{System.String})">
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c>; <c>null</c> hoặc rỗng = không có role nào</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillNavFlags">
            <summary>Cờ hiển thị của màn Lịch sử đổ dầu — mỗi cờ gác đúng một nhóm nút (xem <see cref="T:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillNavPermissions"/>)</summary>
            <param name="CanApprove">Hiện nút "Duyệt" và "Từ chối" ở phiếu chờ duyệt</param>
            <param name="CanUnapprove">Hiện nút "Bỏ duyệt" ở phiếu đã duyệt</param>
            <param name="CanEdit">Hiện nút "Đổ dầu mới" và "Cập nhật"</param>
            <param name="CanDelete">Hiện nút "Xóa"</param>
            <param name="CanExport">Hiện nút "Xuất Excel"</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillNavFlags.#ctor(System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
            <summary>Cờ hiển thị của màn Lịch sử đổ dầu — mỗi cờ gác đúng một nhóm nút (xem <see cref="T:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillNavPermissions"/>)</summary>
            <param name="CanApprove">Hiện nút "Duyệt" và "Từ chối" ở phiếu chờ duyệt</param>
            <param name="CanUnapprove">Hiện nút "Bỏ duyệt" ở phiếu đã duyệt</param>
            <param name="CanEdit">Hiện nút "Đổ dầu mới" và "Cập nhật"</param>
            <param name="CanDelete">Hiện nút "Xóa"</param>
            <param name="CanExport">Hiện nút "Xuất Excel"</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillNavFlags.CanApprove">
            <summary>Hiện nút "Duyệt" và "Từ chối" ở phiếu chờ duyệt</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillNavFlags.CanUnapprove">
            <summary>Hiện nút "Bỏ duyệt" ở phiếu đã duyệt</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillNavFlags.CanEdit">
            <summary>Hiện nút "Đổ dầu mới" và "Cập nhật"</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillNavFlags.CanDelete">
            <summary>Hiện nút "Xóa"</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillNavFlags.CanExport">
            <summary>Hiện nút "Xuất Excel"</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService">
            <summary>
            Interface cho service quản lý việc đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo hoặc cập nhật thông tin đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService.RefillFuelAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lái xe đổ dầu - Upload ảnh và tự động tính chênh lệch định mức khoán
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm lịch sử đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService.GetByIdAsync(System.Int32)">
            <summary>
            Lấy chi tiết lần đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService.GetByTruckAsync(System.Int32)">
            <summary>
            Lấy lịch sử đổ dầu theo xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService.GetByDriverAsync(System.Int32)">
            <summary>
            Lấy lịch sử đổ dầu theo lái xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService.UpdateRefillAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Cập nhật thông tin đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService.DeleteAsync(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa bản ghi đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService.DriverFuelRefill(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Đổ dầu cho lái xe trên app mobile.
            Tự động xác định xe từ CurrentDriverId, lấy PreviousOdo từ LastRefillOdo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService.SearchByDriverAsync(System.Int32,Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm lịch sử đổ dầu theo lái xe (có phân trang, lọc ngày, từ khóa)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService.ApproveFuelRefill(System.Int32,System.Nullable{System.Guid},Lada.Framework.Infrastructures.CurrentUser,System.Nullable{System.Int32},System.Nullable{System.Int32})">
            <summary>
            Duyệt phiếu đổ dầu (thực hiện reconcile + UpdateLastRefillOdo + tạo Expense nếu tiền mặt)
            </summary>
            <param name="id">ID phiếu đổ dầu</param>
            <param name="transactionId">ID giao dịch thẻ xăng để đối soát (bắt buộc khi đổ bằng thẻ)</param>
            <param name="currentUser">Người dùng hiện tại (admin)</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService.RejectFuelRefill(System.Int32,System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Từ chối phiếu đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService.UnapproveFuelRefill(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Bỏ duyệt phiếu đổ dầu đã duyệt (chưa chốt lương): đưa về chờ duyệt và gỡ đối soát giao dịch thẻ
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService.ResubmitFuelRefill(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel,System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lái xe chỉnh sửa và gửi lại phiếu đổ dầu bị từ chối
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.IFuelRefillService.DeleteFuelRefillByDriver(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lái xe xóa phiếu đổ dầu (chỉ khi Pending hoặc Rejected)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillService">
            <summary>
            Service quản lý việc đổ dầu với tính toán định mức khoán
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillService.ResolvePreviousOdoAsync(System.Int32,System.DateTimeOffset,System.Int32)">
            <summary>
            Xác định PreviousOdo cho một phiếu đổ dầu dựa trên chuỗi phiếu của xe.
            Ưu tiên: CurrentOdo của phiếu gần nhất cùng xe (chưa bị từ chối, chưa xóa)
            có (RefillTime, Id) đứng ngay trước phiếu hiện tại.
            Nếu không có phiếu trước → lấy CurrentOdo của bản ghi nhận xe (CheckIn) gần nhất
            có thời điểm &lt;= RefillTime. Nếu vẫn không có → 0.
            </summary>
            <param name="truckId">ID xe</param>
            <param name="refillTime">Thời điểm đổ dầu của phiếu hiện tại</param>
            <param name="excludeRefillId">ID phiếu hiện tại (loại khỏi truy vấn, dùng khi sửa)</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillService.ApplyOdoDerivedValues(Lada.Framework.Data.Domains.Trucks.FuelRefill,System.Int32)">
            <summary>
            Tính lại số liệu suy ra (DistanceKm, QuotaLiters, DifferenceLiters) cho một phiếu
            từ PreviousOdo mới. Không ghi DB — chỉ cập nhật entity in-memory.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillService.RecalculateChainFromAsync(System.Int32,System.DateTimeOffset,Lada.Framework.Infrastructures.CurrentUser,System.Nullable{System.Int32})">
             <summary>
             Tính lại chuỗi phiếu đổ dầu của một xe từ một mốc thời gian trở đi.
             Vì PreviousOdo của mỗi phiếu phụ thuộc CurrentOdo của phiếu liền trước, nên khi
             thêm/sửa/xóa/từ chối một phiếu, các phiếu liền sau cần được tính lại theo dây chuyền.
            
             Quy tắc khóa lương: phiếu có IsPayrollLocked = true sẽ được BỎ QUA (không sửa),
             nhưng vẫn dùng CurrentOdo của nó làm mốc cho phiếu kế tiếp (theo quyết định nghiệp vụ).
             </summary>
             <param name="truckId">ID xe cần tính lại</param>
             <param name="fromRefillTime">Mốc thời gian bắt đầu tính lại (thường là RefillTime của phiếu vừa thay đổi)</param>
             <param name="currentUser">Người dùng thực hiện (đóng dấu UpdatedBy lên các phiếu được tính lại)</param>
             <param name="excludeRefillId">ID phiếu bỏ qua khi ghi lại (phiếu vừa được tính/ghi ở nơi gọi) — vẫn dùng làm mốc</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillService.DriverFuelRefill(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Đổ dầu cho lái xe trên app mobile.
            Tự động xác định xe, lái xe, PreviousOdo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillService.SearchByDriverAsync(System.Int32,Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm lịch sử đổ dầu theo lái xe (có phân trang, lọc ngày, từ khóa)
            Lái xe có thể lái nhiều xe khác nhau nên lọc theo DriverId
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillService.UpdateRefillAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.FuelCards.FuelRefillUpdateModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Cập nhật thông tin đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillService.HandleTransactionReconciliationAsync(Lada.Framework.Data.Domains.Trucks.FuelRefill,System.Nullable{System.Guid},System.Nullable{System.Int32},Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Handle transaction reconciliation changes when creating or updating fuel refill
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillService.ApproveFuelRefill(System.Int32,System.Nullable{System.Guid},Lada.Framework.Infrastructures.CurrentUser,System.Nullable{System.Int32},System.Nullable{System.Int32})">
            <summary>
            Duyệt phiếu đổ dầu: reconcile transaction, UpdateLastRefillOdo, tạo Expense nếu tiền mặt
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillService.CreateAutoExpenseForFuelRefill(Lada.Framework.Data.Domains.Trucks.FuelRefill,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo Expense tự động cho phiếu đổ dầu tiền mặt (CreatedBy = lái xe)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillService.RejectFuelRefill(System.Int32,System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Từ chối phiếu đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillService.UnapproveFuelRefill(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Bỏ duyệt phiếu đổ dầu: đưa phiếu đã duyệt về chờ duyệt để sửa sai sót (nhầm tiền mặt / thẻ dầu,
            chọn nhầm giao dịch thẻ, sai ODO) rồi duyệt lại.
            </summary>
            <remarks>
            <para>
            Gỡ đối soát giao dịch thẻ đang gắn với phiếu. Hộp thoại duyệt chỉ liệt kê giao dịch có
            <c>FuelRefillId == null</c>, và lúc duyệt giao dịch còn <c>IsReconciled</c> sẽ bị chặn là "đã đối soát
            với lần đổ dầu khác" — giữ liên kết cũ thì không chọn lại được chính giao dịch ấy, còn khi đổi sang
            tiền mặt thì giao dịch bị treo ở trạng thái đã đối soát với một phiếu không còn dùng thẻ.
            </para>
            <para>
            Không cần tính lại chuỗi ODO: phiếu chờ duyệt vẫn nằm trong chuỗi (chỉ phiếu từ chối bị loại), nên
            PreviousOdo của các phiếu liền sau không đổi. Thu nhập dầu trong kỳ lương chỉ đếm phiếu đã duyệt,
            nên phiếu đã chốt lương thì không được bỏ duyệt — giống quy tắc chặn sửa/xóa.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillService.ResubmitFuelRefill(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.DriverFuelRefillModel,System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lái xe chỉnh sửa và gửi lại phiếu đổ dầu bị từ chối → Pending
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.FuelCards.FuelRefillService.DeleteFuelRefillByDriver(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lái xe xóa phiếu đổ dầu (chỉ khi Pending hoặc Rejected)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceFormulas">
            <summary>
            Công thức thuần quy đổi giờ làm của MỘT CA chấm công (giờ thô, chưa làm tròn) thành công / kíp.
            Nguồn sự thật duy nhất, dùng chung cho tính lương (<c>PayrollService</c>) và chi tiết chấm công
            (<c>AttendanceService.GetAttendanceDetailByUserAsync</c>).
            </summary>
            <remarks>
            Đầu vào bắt buộc là giờ THÔ của TỪNG CA. Áp ngưỡng lên số giờ đã gộp theo ngày hoặc đã làm tròn
            (như cột <c>WorkingHours DECIMAL(10,1)</c> của <c>sp_GetAttendanceDetailByUser</c>) sẽ cho kíp dư:
            các ngưỡng là bội của 0,1h với so sánh &gt;=, nên làm tròn 0,1h chỉ có thể đẩy giá trị sát dưới
            ngưỡng LÊN qua ngưỡng (ví dụ thật tháng 7/2026: ca 13,4789h bị tròn thành 13,5 → hiển thị 1 kíp
            trong khi lương tính 0 kíp). Đây chính là lỗi lệch kíp form phiếu lương vá ngày 2026-08-20.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceFormulas.CalculateWorkCredits(System.Double)">
            <summary>
            Quy tắc tính công theo ngưỡng số giờ làm việc của một ca:
              &gt; 8h  → 1.0 công; &gt;= 3h → 0.5 công; &gt;= 2h → 0.25 công; còn lại → 0 công.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceFormulas.CalculateOvertimeKips(System.Double)">
            <summary>
            Quy tắc tính kíp theo ngưỡng số giờ làm việc của một ca:
              &lt; 13.5h → 0 kíp; &lt; 15h → 1 kíp; &lt; 15.5h → 1.5 kíp; &gt;= 15.5h → 2 kíp.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService">
            <summary>
            Giao diện cho dịch vụ chấm công.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.PunchAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CheckInOutModel)">
            <summary>
            Xử lý chấm công (Check-in hoặc Check-out) dựa trên trạng thái hiện tại.
            </summary>
            <param name="model">Mô hình CheckInOutModel chứa thông tin chấm công.</param>
            <returns>Kết quả chấm công với thông tin chi tiết.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.GetCurrentAttendance(System.Int32)">
            <summary>
            Lấy thông tin chấm công hiện tại của người dùng (chưa check-out hoặc hôm nay)
            </summary>
            <param name="userId">ID người dùng</param>
            <returns>Thông tin chấm công hiện tại</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.SuggestCheckOutTimeAsync(System.Int32,System.DateTimeOffset)">
            <summary>
            Gợi ý giờ chấm ra cho một ca, suy ra từ thời điểm giao/lấy hàng muộn nhất
            của lái xe kể từ khi ca bắt đầu. Dùng cho dialog chấm bù khi lái xe quên chấm ra.
            </summary>
            <param name="userId">ID lái xe.</param>
            <param name="checkInTime">Thời điểm ca bắt đầu (giờ chấm vào).</param>
            <returns>Kết quả gợi ý giờ ra (HasData + SuggestedTime).</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.CheckOverlapAsync(System.Int32,System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset},System.Nullable{System.Guid})">
            <summary>
            Kiểm tra trước xem khoảng thời gian ca định ghi có chồng lấp ca chấm công nào đã có
            của cùng nhân viên hay không. Dùng cho FE cảnh báo sớm trong dialog chấm công thủ công
            và chấm ra bù, trước khi người dùng bấm lưu.
            </summary>
            <param name="userId">ID nhân viên.</param>
            <param name="checkInTime">Giờ vào của ca định ghi (null nếu chỉ có giờ ra).</param>
            <param name="checkOutTime">Giờ ra của ca định ghi (null nếu ca còn mở).</param>
            <param name="excludeId">Id bản ghi cần loại trừ (chính bản ghi đang sửa).</param>
            <returns>Kết quả kiểm tra trùng ca.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.CloseStaleShiftsAsync">
            <summary>
            Quét và tự đóng toàn bộ ca treo (quên chấm ra) đã vượt ngưỡng giờ, không giới hạn cũ đến đâu.
            Dùng cho Hangfire job chạy cuối ngày. Mỗi ca được đóng bằng giờ hoạt động đơn hàng muộn nhất
            trong cửa sổ ca; ca không suy ra được giờ sẽ để nguyên cho admin sửa tay.
            </summary>
            <returns>Số ca đã tự đóng được.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm bản ghi chấm công theo điều kiện.
            </summary>
            <param name="param">Tham số SmartTableParam.</param>
            <returns>Kết quả tìm kiếm bản ghi chấm công.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.SearchByUserAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm lịch sử chấm công của chính một lái xe (ép theo userId, không đọc UserId từ client).
            Dùng cho DriverApp để tránh IDOR. Vẫn cho lọc khoảng ngày qua CheckInStart/CheckInEnd.
            </summary>
            <param name="param">Tham số SmartTableParam (Pagination + Sort bắt buộc).</param>
            <param name="userId">ID lái xe hiện tại (lấy từ token, ép server-side).</param>
            <returns>Kết quả tìm kiếm bản ghi chấm công của lái xe đó.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.CreateAsync(Lada.Framework.Data.Domains.Hr.Attendance)">
            <summary>
            Tạo mới bản ghi chấm công.
            </summary>
            <param name="attendance">Đối tượng Attendance.</param>
            <returns>Bản ghi Attendance đã tạo.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.UpdateAsync(Lada.Framework.Data.Domains.Hr.Attendance)">
            <summary>
            Cập nhật bản ghi chấm công.
            </summary>
            <param name="attendance">Đối tượng Attendance cần cập nhật.</param>
            <returns>Bản ghi Attendance đã cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.DeleteAsync(System.Guid,System.Int32,System.String)">
            <summary>
            Xoá mềm một bản ghi chấm công (chỉ Founder được gọi — chặn ở controller).
            Bản ghi biến mất khỏi mọi đường đọc qua <c>Query()</c> (danh sách, chống trùng ca,
            tính lương) và khỏi hai stored procedure tổng hợp công; ảnh chấm công giữ nguyên để
            còn đối chiếu/khôi phục.
            </summary>
            <param name="id">Id bản ghi chấm công.</param>
            <param name="deletedBy">Id người xoá (đóng dấu UpdatedBy).</param>
            <param name="deletedByUserName">Tên đăng nhập người xoá (đóng dấu UpdatedByUserName).</param>
            <returns>Kết quả xử lý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.GetByIdAsync(System.Guid)">
            <summary>
            Lấy thông tin bản ghi chấm công theo Id.
            </summary>
            <param name="id">Id bản ghi chấm công.</param>
            <returns>Bản ghi Attendance nếu tìm thấy, ngược lại null.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.ExportToExcelAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.String)">
            <summary>
            Xuất danh sách chấm công ra file Excel.
            </summary>
            <param name="param">Tham số SmartTableParam.</param>
            <param name="filePath">Đường dẫn file Excel.</param>
            <returns>Kết quả xuất file.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.GetAttendanceSummaryByMonthAsync(System.Int32,System.Int32)">
            <summary>
            Lấy tổng hợp số công của tất cả nhân viên theo tháng
            </summary>
            <param name="month">Tháng (1-12)</param>
            <param name="year">Năm (ví dụ: 2025)</param>
            <returns>Danh sách tổng hợp số công của nhân viên</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.GetAttendanceDetailByUserAsync(System.Int32,System.Int32,System.Int32)">
            <summary>
            Lấy chi tiết công từng ngày của một nhân viên theo tháng
            </summary>
            <param name="month">Tháng (1-12)</param>
            <param name="year">Năm (ví dụ: 2025)</param>
            <param name="userId">ID nhân viên</param>
            <returns>Danh sách chi tiết công từng ngày</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.CreateOrUpdateManualAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualAttendanceModel)">
            <summary>
            Tạo mới hoặc cập nhật bản ghi chấm công thủ công (bổ sung khi lái xe/nhân viên quên chấm vào/ra).
            Giờ vào và giờ ra được xử lý độc lập.
            </summary>
            <param name="model">Thông tin chấm công thủ công.</param>
            <returns>Kết quả xử lý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.ManualCheckOutAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualCheckOutModel)">
            <summary>
            Chấm ra bù cho một bản ghi chấm công chưa có giờ ra (admin thao tác hộ khi lái xe quên chấm ra).
            Cho phép đính kèm ảnh ODO bù. Hỗ trợ ca qua đêm (giờ ra có thể sang ngày hôm sau).
            </summary>
            <param name="model">Thông tin chấm ra bù (kèm ảnh ODO tùy chọn).</param>
            <returns>Kết quả xử lý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.ImportFromExcelAsync(System.IO.Stream,System.String,System.Int32,System.String)">
            <summary>
            Import bảng chấm công từ file Excel (máy chấm công vân tay). Map nhân viên qua mã chấm công (AttendanceCode).
            </summary>
            <param name="fileStream">Luồng dữ liệu file Excel.</param>
            <param name="fileName">Tên file.</param>
            <param name="updatedBy">ID người thực hiện import.</param>
            <param name="updatedByUserName">Tên đăng nhập người thực hiện import.</param>
            <returns>Kết quả import với thống kê dòng xử lý/lỗi/bỏ qua.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService">
            <summary>
            Triển khai dịch vụ chấm công.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.SHIFT_MAX_HOURS">
            <summary>
            Số giờ tối đa của một ca làm việc hợp lệ. Ca dài nhất theo nghiệp vụ là 8h sáng → 2h đêm hôm sau (~18h),
            lấy ngưỡng 20h để có biên an toàn. Nếu ca mở vượt ngưỡng này → coi như quên chấm ra.
            (Có thể chuyển sang appsettings/config sau nếu cần.)
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.STALE_CLOSE_BY_ORDER">
            <summary>
            Dấu vết người sửa cho ca treo được tự đóng bằng giờ hoạt động đơn hàng suy ra được.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.STALE_CLOSE_NO_EVIDENCE">
            <summary>
            Dấu vết người sửa cho ca treo bị đóng bằng CHÍNH GIỜ VÀO vì không có căn cứ nào để suy giờ ra.
            Tách khỏi <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.STALE_CLOSE_BY_ORDER"/> để HR lọc ra đúng những ca cần chấm bù.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.PunchAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CheckInOutModel)">
            <summary>
            Xử lý chấm công (Check-in hoặc Check-out) dựa trên trạng thái hiện tại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CheckIn(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CheckInOutModel)">
            <summary>
            Chấm công vào (Check-in) với mô hình CheckInOutModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CheckOut(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CheckInOutModel)">
            <summary>
            Chấm công ra (Check-out) với mô hình CheckInOutModel.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm bản ghi chấm công theo điều kiện.
            </summary>
            <param name="param">Tham số SmartTableParam.</param>
            <returns>Kết quả tìm kiếm bản ghi chấm công.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.SearchByUserAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm bản ghi chấm công của một lái xe cụ thể (dùng cho DriverApp).
            UserId được ép ở tầng service, không đọc từ client để tránh IDOR.
            </summary>
            <param name="param">Tham số SmartTableParam (chỉ đọc Pagination + lọc khoảng ngày CheckInStart/CheckInEnd).</param>
            <param name="userId">ID lái xe hiện tại (lấy từ token ở controller).</param>
            <returns>Kết quả tìm kiếm bản ghi chấm công của chính lái xe đó.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CreateAsync(Lada.Framework.Data.Domains.Hr.Attendance)">
            <summary>
            Tạo mới bản ghi chấm công.
            </summary>
            <param name="attendance">Đối tượng Attendance.</param>
            <returns>Bản ghi Attendance đã tạo.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.UpdateAsync(Lada.Framework.Data.Domains.Hr.Attendance)">
            <summary>
            Cập nhật bản ghi chấm công.
            </summary>
            <param name="attendance">Đối tượng Attendance cần cập nhật.</param>
            <returns>Bản ghi Attendance đã cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.DeleteAsync(System.Guid,System.Int32,System.String)">
            <summary>
            Xoá mềm một bản ghi chấm công. Xem mô tả ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IAttendanceService.DeleteAsync(System.Guid,System.Int32,System.String)"/>.
            </summary>
            <remarks>
            <para>
            <b>Xoá mềm, không xoá cứng</b> — theo nếp chung của <c>Repository.DeleteAsync</c>. Mọi đường
            đọc chấm công trong code (<c>SearchAsync</c>, <c>FindOverlappingShiftAsync</c>,
            <c>PayrollService.BuildPayrollRecord</c>, job đóng ca treo) đều đi qua <c>Query()</c> nên tự
            bỏ qua bản ghi này. Hai stored procedure <c>sp_GetAttendanceDetailByUser</c> /
            <c>sp_GetAttendanceSummaryByMonth</c> đọc thẳng bảng nên phải lọc <c>IsDeleted = 0</c>
            (migration <c>M202608191000_LocXoaMemTrongSpBaoCaoChamCong</c>).
            </para>
            <para>
            <b>Không chặn theo kỳ lương đã trả.</b> <c>EmployeePayrollRecord</c> trạng thái Paid là ảnh
            chụp (CreateOrUpdate chặn ghi đè) nên tiền đã trả không đổi; kỳ Draft sẽ ra số công mới khi
            tính lại — đúng ý đồ của người xoá. Đường sửa (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CreateOrUpdateManualAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualAttendanceModel)"/>) cũng
            không chặn, xoá không nên khắt khe hơn sửa.
            </para>
            <para>
            <b>Tìm bằng <c>Query()</c> thay vì <c>GetByIdAsync</c></b>: bản ghi đã xoá mềm phải trả
            "không tìm thấy" (không xoá hai lần), và bệ test <c>RecordingRepository</c> không cài
            <c>GetByIdAsync</c>.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.GetByIdAsync(System.Guid)">
            <summary>
            Lấy thông tin bản ghi chấm công theo Id.
            </summary>
            <param name="id">Id bản ghi chấm công.</param>
            <returns>Bản ghi Attendance nếu tìm thấy, ngược lại null.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.ExportToExcelAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.String)">
            <summary>
            Xuất danh sách chấm công ra file Excel.
            </summary>
            <param name="param">Tham số SmartTableParam.</param>
            <param name="filePath">Đường dẫn file Excel.</param>
            <returns>Kết quả xuất file.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.GetAttendanceItemById(System.Guid)">
            <summary>
            Lấy thông tin chi tiết của một bản ghi chấm công theo ID
            </summary>
            <param name="attendanceId">ID của bản ghi chấm công</param>
            <returns>Thông tin chi tiết của bản ghi chấm công</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.GetCurrentAttendance(System.Int32)">
            <summary>
            Lấy thông tin chấm công hiện tại của người dùng (chưa check-out hoặc hôm nay)
            </summary>
            <param name="userId">ID người dùng</param>
            <returns>Thông tin chấm công hiện tại</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.SuggestCheckOutTimeAsync(System.Int32,System.DateTimeOffset)">
            <summary>
            Gợi ý giờ chấm ra cho một ca dựa trên thời điểm hoạt động đơn hàng (lấy/giao) muộn nhất
            của lái xe kể từ khi ca bắt đầu. Dùng cho dialog chấm bù công của admin.
            </summary>
            <param name="userId">ID lái xe.</param>
            <param name="checkInTime">Thời điểm ca bắt đầu (giờ vào).</param>
            <returns>Kết quả chứa giờ gợi ý và cờ có dữ liệu hay không.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CheckOverlapAsync(System.Int32,System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset},System.Nullable{System.Guid})">
            <summary>
            Kiểm tra trước xem khoảng thời gian ca định ghi có chồng lấp ca chấm công nào đã có
            của cùng nhân viên hay không. Chỉ để FE cảnh báo sớm — hàng rào chặn thật vẫn nằm ở
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CreateOrUpdateManualAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualAttendanceModel)"/> / <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.ManualCheckOutAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualCheckOutModel)"/> / <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CheckIn(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CheckInOutModel)"/>.
            </summary>
            <param name="userId">ID nhân viên.</param>
            <param name="checkInTime">Giờ vào của ca định ghi (null nếu chỉ có giờ ra).</param>
            <param name="checkOutTime">Giờ ra của ca định ghi (null nếu ca còn mở).</param>
            <param name="excludeId">Id bản ghi cần loại trừ (chính bản ghi đang sửa).</param>
            <returns>Kết quả kiểm tra trùng ca.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.UpdateUserTruckOperatingStatus(System.Int32,Lada.Framework.Data.Enums.OperatingStatus)">
            <summary>
            Cập nhật trạng thái hoạt động của xe mà người dùng đang phụ trách
            </summary>
            <param name="userId">ID người dùng</param>
            <param name="operatingStatus">Trạng thái hoạt động mới</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.GetLatestOrderActivityTimeAsync(System.Int32,System.DateTimeOffset,System.DateTimeOffset)">
             <summary>
             Tìm thời điểm hoạt động đơn hàng (lấy/giao hàng) muộn nhất do chính lái xe thực hiện,
             TRONG CỬA SỔ <c>[giờ vào ca, giờ vào ca + SHIFT_MAX_HOURS]</c>. Dùng để suy ra giờ chấm ra
             khi lái xe quên chấm ra. Trả về null nếu không có hoạt động nào trong cửa sổ đó.
             </summary>
             <remarks>
             TRẦN THỜI GIAN LÀ HÀNG RÀO AN TOÀN, KHÔNG PHẢI TỐI ƯU TRUY VẤN. Trước 16/08/2026 hàm này
             chỉ chặn dưới (<c>&gt;= shiftStart</c>): một ca treo từ 2025 vì thế được đóng bằng đơn hàng
             của 11 tháng sau, sinh ra 73 bản ghi dài tới 338 ngày trên production, tất cả mang dấu
             <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.STALE_CLOSE_BY_ORDER"/>.
            
             Cửa sổ 20h chính là "thao tác đơn hàng cuối cùng của lái xe" theo đúng ý nghiệp vụ, chỉ khác
             ở chỗ không cắt ngang nửa đêm: đo trên 239 ca cần dọn (16/08/2026), luật theo ngày lịch suy
             được 196 ca còn cửa sổ 20h suy được 219 — 23 ca chênh lệch đều là ca đêm bị ngày lịch cắt đôi.
             </remarks>
             <param name="userId">ID lái xe.</param>
             <param name="shiftStart">Thời điểm ca bắt đầu (CheckInTime).</param>
             <param name="shiftEnd">Trần cửa sổ, lấy từ <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.GetShiftInferenceUpperBoundAsync(System.Int32,System.DateTimeOffset,System.Nullable{System.Guid})"/>.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.GetShiftInferenceUpperBoundAsync(System.Int32,System.DateTimeOffset,System.Nullable{System.Guid})">
             <summary>
             Trần của cửa sổ suy giờ ra cho một ca: sớm hơn giữa <c>giờ vào + SHIFT_MAX_HOURS</c> và
             <b>giờ vào của ca kế tiếp</b> của cùng nhân viên.
             </summary>
             <remarks>
             VÌ SAO PHẢI CẮT TẠI CA KẾ TIẾP — nếu chỉ có trần 20h thì cửa sổ của hai ca treo liên tiếp
             CHỒNG NHAU, và một thao tác đơn hàng duy nhất đóng được cả hai ca. Ví dụ thật: lái xe tồn
             ca S1 vào 08:00 và ca S2 vào 20:00 cùng ngày, cả ngày chỉ có một lần giao hàng lúc 23:00.
             Không cắt thì S1 đóng lúc 23:00 (15h → 1 công + 1,5 kíp) và S2 cũng đóng lúc 23:00
             (3h → thêm 0,5 công) — MỘT khối công việc được trả công hai lần. Tệ hơn, S1 (08:00–23:00)
             chồng lấn S2 (20:00–23:00), tức chính đường tự đóng lại đẻ ra cặp ca trùng mà đợt này đang dẹp.
            
             Đo trên DB dev 16/08/2026: <b>79/239</b> ca cần dọn có một ca kế tiếp nằm trong cửa sổ 20h,
             tức khoảng một phần ba. Với 6 lái xe của bảng §2.4 thì luật này KHÔNG đổi con số công/kíp
             nào (đã đối chiếu lại cả 12 ô), nhưng nó chặn được nguồn sinh ca chồng lấn cho phần còn lại.
             </remarks>
             <param name="userId">ID nhân viên.</param>
             <param name="shiftStart">Giờ vào của ca đang cần suy giờ ra.</param>
             <param name="excludeId">Id bản ghi cần loại trừ (chính ca đang xét).</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.AutoCloseStaleShiftAsync(Lada.Framework.Data.Domains.Hr.Attendance)">
            <summary>
            Tự đóng ca treo (quên chấm ra) bằng thời điểm hoạt động đơn hàng muộn nhất của lái xe.
            Nếu không suy ra được giờ nào (lái xe không có hoạt động đơn hàng sau khi vào ca)
            thì để nguyên ca treo cho admin xử lý thủ công.
            Trả về true nếu đã đóng được ca.
            </summary>
            <param name="staleShift">Bản ghi ca treo cần đóng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CloseStaleShiftAsync(Lada.Framework.Data.Domains.Hr.Attendance)">
             <summary>
             Đóng DỨT ĐIỂM một ca treo theo luật chung của plan §6.6: ưu tiên giờ hoạt động đơn hàng
             muộn nhất trong cửa sổ ca; không có căn cứ nào thì đóng bằng CHÍNH GIỜ VÀO (ca 0 phút).
             </summary>
             <remarks>
             Vì sao ca 0 phút chứ không phải "độ dài ca mặc định": ca 0 phút cho 0 công và 0 kíp
             (<c>PayrollService.CalculateWorkCredits</c> / <c>CalculateOvertimeKips</c>) nên không bịa ra
             một đồng lương nào, mà bản ghi vẫn còn nguyên để HR lọc theo
             <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.STALE_CLOSE_NO_EVIDENCE"/> rồi chấm bù nếu lái xe thực sự có làm.
            
             Trước 16/08/2026, nhánh "không suy được giờ ra" để nguyên ca treo — mà
             <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.PunchAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CheckInOutModel)"/> vẫn mở ca mới ngay sau đó, nên ca mở tích tụ dần. Đó chính là cỗ máy
             sinh ra 166 ca treo / 28 người trên production, cá biệt một người tồn 33 ca mở cùng lúc.
             </remarks>
             <param name="staleShift">Bản ghi ca treo cần đóng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CloseStaleShiftsOfUserAsync(System.Int32)">
            <summary>
            Đóng dứt điểm MỌI ca treo (đã vượt <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.SHIFT_MAX_HOURS"/>) của một nhân viên.
            </summary>
            <remarks>
            VÌ SAO ĐÓNG TẤT CẢ CHỨ KHÔNG CHỈ CA GẦN NHẤT: sau bản vá L3, hàng rào chống trùng
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.FindOverlappingShiftAsync(System.Int32,System.DateTimeOffset,System.Nullable{System.DateTimeOffset},System.Nullable{System.Guid},System.Boolean)"/> nhìn thấy mọi ca còn mở bất kể cũ đến đâu. Chỉ cần
            sót lại một ca treo cũ là mọi lần chấm vào sau đó bị chặn — với người đang tồn 33 ca mở thì
            đóng nhỏ giọt mỗi lần bấm một ca đồng nghĩa người đó không chấm công được nữa.
            </remarks>
            <param name="userId">ID nhân viên.</param>
            <returns>Số ca treo đã đóng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CloseStaleShiftsAsync">
             <summary>
             Quét và tự đóng TOÀN BỘ ca treo (quên chấm ra) đã vượt ngưỡng giờ, không giới hạn cũ đến đâu.
             Giữ đúng một cận trên <c>now - SHIFT_MAX_HOURS</c> để không đụng ca đang chạy hợp lệ.
             </summary>
             <remarks>
             CẬN DƯỚI 48h ĐÃ BỊ BỎ (16/08/2026). Nó khiến job không bao giờ chạm được phần tồn cũ hơn
             48h, nên 166 ca treo — cũ nhất từ 11/07/2025 — nằm lại vĩnh viễn. Bỏ được cận dưới là nhờ
             bản vá L1: <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.GetLatestOrderActivityTimeAsync(System.Int32,System.DateTimeOffset,System.DateTimeOffset)"/> giờ có trần 20h nên một ca treo từ
             2025 không còn bị đóng bằng đơn hàng của năm sau.
            
             KHÁC BIỆT CÓ CHỦ ĐÍCH so với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CloseStaleShiftsOfUserAsync(System.Int32)"/>: job nền chỉ đóng ca
             SUY RA ĐƯỢC giờ, ca không có căn cứ thì để nguyên cho admin chấm bù. Đường chấm công thật
             thì buộc phải đóng hết (nếu không thì tích tụ ca mở và L3 sẽ chặn chính người đó), còn job
             nền không bị sức ép đó nên giữ thái độ dè dặt hơn — không tự tay tạo ca 0 phút hàng loạt
             sau lưng người vận hành.
             </remarks>
             <returns>Số ca đã tự đóng được.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.FindOverlappingShiftAsync(System.Int32,System.DateTimeOffset,System.Nullable{System.DateTimeOffset},System.Nullable{System.Guid},System.Boolean)">
             <summary>
             Tìm ca chấm công của cùng nhân viên bị CHỒNG LẤP thời gian với khoảng [start, end) đang muốn ghi.
             Đây là hàng rào chống chấm trùng dùng chung cho mọi đường ghi (chấm bù, sửa, chấm ra bù,
             chấm vào từ app, import Excel). Cố tình so theo khoảng thời gian thay vì theo ngày lịch:
             ca qua đêm (vd 20h → 4h hôm sau) nằm trên 2 ngày nên so ngày sẽ bỏ sót trùng.
             Hai ca giáp ranh (giờ ra ca trước == giờ vào ca sau) KHÔNG tính là trùng.
            
             Ca ĐÃ CHỐT chỉ được coi là chiếm dụng tối đa <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.SHIFT_MAX_HOURS"/> giờ kể từ giờ vào:
             một bản ghi rác dài 7 tháng (do nhập sai hoặc do auto-close hỏng) không được phép chặn mọi
             ca mới suốt 7 tháng.
            
             Ca CÒN MỞ chặn bất kể giờ vào cũ đến đâu — nhưng CHỈ khi người gọi bật
             <paramref name="caConMoChanVoThoiHan"/>, xem phần ghi chú.
             </summary>
             <remarks>
             TRƯỚC 16/08/2026 CẬN DƯỚI ÁP CHO CẢ HAI LOẠI, và đó là lỗi L3: ca treo cũ hơn 20h trở nên
             vô hình với hàng rào, nên <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CheckIn(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CheckInOutModel)"/> thoải mái mở ca mới chồng lên nó. Cộng với
             lỗi L2 ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.PunchAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CheckInOutModel)"/> (không đóng nổi ca cũ mà vẫn mở ca mới), kết quả là
             1.276 cặp ca chồng lấn chỉ trong tháng 7+8/2026.
            
             VÌ SAO LUẬT "CA CÒN MỞ CHẶN VÔ THỜI HẠN" CHỈ ÁP CHO <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CheckIn(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CheckInOutModel)"/>. Bật nó cho mọi
             đường ghi thì <b>khoá luôn công cụ dọn dẹp</b>: một ca treo từ 11/07/2025 sẽ chặn mọi thao
             tác chấm bù / sửa / chấm ra bù cho người đó ở mọi ngày về sau, vì <c>CheckInTime</c> của nó
             nhỏ hơn mọi <c>newEnd</c>. Người đang tồn 33 ca mở còn tệ hơn — <paramref name="excludeId"/>
             chỉ loại được đúng một bản ghi, nên 32 ca còn lại vẫn chặn chính thao tác đang định gỡ chúng.
             Đó là hồi quy, không phải hàng rào.
            
             <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CheckIn(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CheckInOutModel)"/> thì khác: nó TẠO ca mới ở thời điểm hiện tại, đúng nơi ca treo phải
             giữ chỗ, và nó luôn được gọi sau khi <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.PunchAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CheckInOutModel)"/> đã dọn ca treo bằng
             <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CloseStaleShiftsOfUserAsync(System.Int32)"/> — nên bật ở đây là hàng rào phòng thủ chiều sâu
             không tốn gì. Các đường của admin giữ luật trần 20h cũ: họ vẫn được cảnh báo bởi ca đã chốt
             và ca mở gần đây, chỉ không bị rác lịch sử khoá tay.
             </remarks>
             <param name="userId">ID nhân viên.</param>
             <param name="start">Giờ vào của ca đang muốn ghi.</param>
             <param name="end">Giờ ra của ca đang muốn ghi (null nếu ca còn mở).</param>
             <param name="excludeId">Id bản ghi cần loại trừ (chính bản ghi đang sửa).</param>
             <param name="caConMoChanVoThoiHan">
             <c>true</c>: ca còn mở chặn bất kể cũ đến đâu — chỉ dùng cho <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CheckIn(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CheckInOutModel)"/>.
             <c>false</c> (mặc định): ca còn mở cũng chỉ chiếm tối đa <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.SHIFT_MAX_HOURS"/> giờ,
             đúng luật trước đây — dùng cho mọi đường ghi của admin và cho API xem trước của FE.
             </param>
             <returns>Bản ghi trùng đầu tiên tìm được, null nếu không trùng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.BuildOverlapMessage(Lada.Framework.Data.Domains.Hr.Attendance)">
            <summary>
            Dựng thông báo trùng ca theo NGÀY — đủ để người dùng biết ngày đó đã chấm công rồi.
            Ca qua đêm hiển thị cả 2 ngày để không gây nhầm.
            </summary>
            <param name="overlap">Bản ghi chấm công bị trùng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.SaveAttendanceMediaAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.AttendanceMediaModel)">
            <summary>
            Lưu media cho attendance (check-in/check-out)
            </summary>
            <param name="model">Model chứa thông tin attendance media</param>
            <returns>Danh sách kết quả lưu media</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.CreateOrUpdateManualAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualAttendanceModel)">
            <summary>
            Tạo mới hoặc cập nhật bản ghi chấm công thủ công (bổ sung khi quên chấm vào/ra).
            Giờ vào và giờ ra được xử lý độc lập.
            HỖ TRỢ CA QUA ĐÊM: FE gửi lên <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualAttendanceModel.CheckInTime"/> và
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualAttendanceModel.CheckOutTime"/> là DateTimeOffset đầy đủ (đã ghép ngày+giờ ở FE,
            giờ ra có thể rơi vào ngày hôm sau). KHÔNG tự ghép giờ ra vào cùng ngày giờ vào ở backend —
            nếu làm vậy ca qua đêm sẽ có CheckOut &lt; CheckIn và bị validate chặn nhầm.
            Validate chỉ so sánh trực tiếp 2 mốc datetime đầy đủ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.ManualCheckOutAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.ManualCheckOutModel)">
            <summary>
            Chấm ra thủ công cho một bản ghi chưa có giờ ra (admin bổ sung hộ khi lái xe quên chấm ra),
            cho phép upload ảnh ODO bù. Hỗ trợ ca qua đêm (giờ ra có thể sang ngày hôm sau).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.ImportFromExcelAsync(System.IO.Stream,System.String,System.Int32,System.String)">
            <summary>
            Import bảng chấm công từ file Excel (máy chấm công vân tay). Map nhân viên qua AttendanceCode.
            Cột: 1=Ngày (dd/MM/yyyy), 3=Họ tên, 4=Mã chấm công, 5=Giờ vào, 6=Giờ ra.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.TryParseTime(System.String,System.TimeSpan@)">
            <summary>
            Parse chuỗi giờ dạng HH:mm:ss hoặc HH:mm sang TimeSpan.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.GetAttendanceSummaryByMonthAsync(System.Int32,System.Int32)">
            <summary>
            Lấy tổng hợp số công của tất cả nhân viên theo tháng
            </summary>
            <param name="month">Tháng (1-12)</param>
            <param name="year">Năm (ví dụ: 2025)</param>
            <returns>Danh sách tổng hợp số công của nhân viên</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceService.GetAttendanceDetailByUserAsync(System.Int32,System.Int32,System.Int32)">
            <summary>
            Lấy chi tiết công từng ngày của một nhân viên theo tháng
            </summary>
            <param name="month">Tháng (1-12)</param>
            <param name="year">Năm (ví dụ: 2025)</param>
            <param name="userId">ID nhân viên</param>
            <returns>Danh sách chi tiết công từng ngày</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Hr.ICandidateService">
            <summary>
            Giao diện cho dịch vụ quản lý ứng viên.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.ICandidateService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm ứng viên.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm ứng viên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.ICandidateService.Delete(System.Int32)">
            <summary>
            Xóa ứng viên theo ID.
            </summary>
            <param name="id">ID của ứng viên.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.ICandidateService.GetReviewModelById(System.Int32)">
            <summary>
            Lấy thông tin đánh giá ứng viên theo ID.
            </summary>
            <param name="id">ID của ứng viên.</param>
            <returns>Thông tin đánh giá ứng viên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.ICandidateService.UpdateReview(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateReviewModel)">
            <summary>
            Cập nhật thông tin đánh giá ứng viên.
            </summary>
            <param name="model">Thông tin đánh giá ứng viên.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.ICandidateService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel)">
            <summary>
            Tạo ứng viên mới.
            </summary>
            <param name="model">Thông tin ứng viên.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.ICandidateService.GetById(System.Int32)">
            <summary>
            Lấy thông tin ứng viên theo ID.
            </summary>
            <param name="id">ID của ứng viên.</param>
            <returns>Thông tin ứng viên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.ICandidateService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel)">
            <summary>
            Cập nhật thông tin ứng viên.
            </summary>
            <param name="model">Thông tin ứng viên.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Hr.CandidateService">
            <summary>
            Triển khai dịch vụ quản lý ứng viên.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.CandidateService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Hr.Candidate},Lada.Framework.Infrastructures.Services.ICvUploadService,Lada.Framework.Data.Repositories.IUserRepository{Lada.Framework.Data.Domains.Identity.User},Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodLockService)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Hr.CandidateService"/>.
            </summary>
            <param name="candidateRepository">Đối tượng IRepository của Candidate.</param>
            <param name="cvUploadService">Dịch vụ upload CV.</param>
            <param name="userRepository">Kho người dùng — tra tên người phụ trách tuyển.</param>
            <param name="periodLock">Hỏi kỳ KPI đã chốt chưa trước khi xoá mốc nhận việc (nợ KPI-7).</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.CandidateService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm ứng viên.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm ứng viên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.CandidateService.FillRecruiterNamesAsync(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.Hr.CandidateItem})">
            <summary>
            Gán tên người phụ trách tuyển cho từng dòng kết quả.
            </summary>
            <remarks>
            <c>Candidate.RecruiterId</c> không có navigation property tới <c>User</c> (bảng này chưa
            từng khai FK tới User), nên tra tên theo trang kết quả thay vì Include.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.CandidateService.ApplyRecruiterAsync(Lada.Framework.Data.Domains.Hr.Candidate,System.Nullable{System.Int32})">
            <summary>
            Gán người phụ trách tuyển cho hồ sơ. Trả về thông báo lỗi tiếng Việt nếu không gán được,
            null nếu hợp lệ (đã gán, hoặc cố ý không đụng tới).
            </summary>
            <remarks>
            <para>
            <b>Không xoá giá trị cũ khi client không gửi trường này.</b> <c>RecruiterId</c> là
            <c>int?</c> nên "client không gửi" và "client muốn bỏ trống" đến service đều là <c>null</c> —
            không phân biệt được. Chọn giữ nguyên giá trị cũ, vì hướng nhầm còn lại làm mất dữ liệu.
            </para>
            <para>
            Đây không phải lo xa: bản đầu của GĐ B gán vô điều kiện <c>candidate.RecruiterId =
            model.RecruiterId</c>, mà màn đánh giá hồ sơ (<c>review.vue</c>) chỉ gửi
            <c>{Id, Status, StatusContent}</c> và lại là <b>đường duy nhất</b> trong SPA để chuyển hồ sơ
            sang "Nhận việc" ⇒ mỗi lần onboard là xoá trắng người phụ trách, khiến chỉ số
            <c>hr.onboard-count</c> luôn bằng 0 đúng vào lúc cần đếm. Review GĐ B bắt được (3/4 chiều
            độc lập cùng tìm ra), có ca test neo lại.
            </para>
            <para>
            Cũng kiểm luôn người được gán có thật và là nhân viên hay không: cột này là nguồn đếm của
            một chỉ số sẽ sinh tiền thưởng ở GĐ E, nhận Id rác vào thì số sai mà không ai thấy.
            Muốn bỏ trống người phụ trách thì làm qua một thao tác riêng, không đi bằng đường "quên gửi".
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.CandidateService.ApplyOnboardedStampAsync(Lada.Framework.Data.Domains.Hr.Candidate,Lada.Framework.Data.Domains.Hr.CandidateStatus)">
            <summary>
            Đóng dấu mốc nhận việc khi trạng thái hồ sơ đổi.
            </summary>
            <remarks>
            <para>
            Chỉ đóng dấu lần đầu chuyển sang <see cref="F:Lada.Framework.Data.Domains.Hr.CandidateStatus.Onboard"/>: sửa hồ sơ về sau
            không được đẩy mốc sang kỳ khác, vì mốc này quyết định kỳ nào tính chỉ số hr.onboard-count.
            Chuyển ra khỏi Onboard (nhận việc hụt) thì xoá dấu để kỳ đó không còn đếm.
            </para>
            <para>
            <b>Trừ khi kỳ chứa mốc đã chốt KPI</b> — đây là chỗ trả nợ <c>KPI-7</c>. Vòng trạng thái
            Onboard → Rejected → Onboard xoá dấu cũ rồi đóng dấu mới theo thời điểm hiện tại, tức
            **dịch công của kỳ cũ sang kỳ đang chạy**. §3.4 đã chốt số kỳ đã chốt là snapshot bất
            biến, nên mốc nằm trong kỳ đã chốt thì đóng băng: trạng thái hồ sơ vẫn đổi bình thường,
            chỉ riêng cái mốc là bất động. Chốt lại kỳ trong cửa sổ cho phép vì thế ra đúng số cũ.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.CandidateService.Delete(System.Int32)">
            <summary>
            Xóa ứng viên theo ID.
            </summary>
            <param name="id">ID của ứng viên.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.CandidateService.GetReviewModelById(System.Int32)">
            <summary>
            Lấy thông tin đánh giá ứng viên theo ID.
            </summary>
            <param name="id">ID của ứng viên.</param>
            <returns>Thông tin đánh giá ứng viên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.CandidateService.UpdateReview(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateReviewModel)">
            <summary>
            Cập nhật thông tin đánh giá ứng viên.
            </summary>
            <param name="model">Thông tin đánh giá ứng viên.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.CandidateService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel)">
            <summary>
            Tạo ứng viên mới.
            </summary>
            <param name="model">Thông tin ứng viên.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.CandidateService.GetById(System.Int32)">
            <summary>
            Lấy thông tin ứng viên theo ID.
            </summary>
            <param name="id">ID của ứng viên.</param>
            <returns>Thông tin ứng viên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.CandidateService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CandidateModel)">
            <summary>
            Cập nhật thông tin ứng viên.
            </summary>
            <param name="model">Thông tin ứng viên.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositService">
            <summary>
            Cổng ghi sổ DUY NHẤT cho cọc trách nhiệm và tạm ứng lương.
            Mọi thay đổi UserPreference.ResponsibilityDepositPaid / SalaryAdvance phải đi qua service này
            (kèm Transaction vào ví Personal của lái xe) — các service khác không tự sửa hai field đó.
            Tiền vào đi qua luồng Income có duyệt; tiền ra (hoàn cọc, tạm ứng) đi qua Expense có duyệt.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositService.CreateSalaryAdvanceAsync(System.Int32,System.Decimal,System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo YÊU CẦU tạm ứng lương — Expense Pending, chưa động vào số dư.
            Số dư chỉ thay đổi khi KT MarkAsPaid (hook gọi RecordAdvancePaidAsync).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositService.CreateRefundAsync(System.Int32,System.Decimal,System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo YÊU CẦU hoàn cọc trách nhiệm — Expense Pending, chưa động vào số dư.
            Số dư chỉ thay đổi khi KT MarkAsPaid (hook gọi RecordRefundPaidAsync).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositService.RecordDepositReceivedAsync(System.Int32,System.Decimal,System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Ghi sổ khi Income cọc được xác nhận nhận tiền (gọi từ IncomeService.MarkAsReceived,
            trong DB transaction của luồng đó): Paid += amount + Transaction loại ResponsibilityDeposit.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositService.RecordRefundPaidAsync(System.Int32,System.Decimal,System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Ghi sổ khi Expense hoàn cọc được chi tiền (gọi từ ExpenseService.MarkAsPaid,
            trong DB transaction của luồng đó): validate lại số dư, Paid -= amount + Transaction DepositRefund.
            Trả Failed nếu cọc hiện tại không đủ — caller phải rollback.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositService.RecordAdvancePaidAsync(System.Int32,System.Decimal,System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Ghi sổ khi Expense tạm ứng được chi tiền (gọi từ ExpenseService.MarkAsPaid,
            trong DB transaction của luồng đó): SalaryAdvance += amount + Transaction SalaryAdvance.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositService.RecordPayrollDepositAsync(System.Int32,System.Decimal,System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Ghi sổ khi NLĐ confirm phiếu lương có trừ cọc: Paid += amount + Transaction DepositFromPayroll.
            Gọi trong DB transaction của ConfirmPayrollAsync.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositService.RecordPayrollAdvanceSettleAsync(System.Int32,System.Decimal,System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Ghi sổ khi NLĐ confirm phiếu lương có cấn trừ tạm ứng:
            SalaryAdvance -= amount (trừ đúng snapshot trên phiếu, KHÔNG reset về 0)
            + Transaction SalaryAdvanceFromPayroll. Gọi trong DB transaction của ConfirmPayrollAsync.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositService.RevertPayrollAsync(System.Int32,System.Decimal,System.Decimal,System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Hoàn tác ghi sổ của một phiếu lương đã Confirmed (khi KT sửa lại phiếu):
            Paid -= deposit, SalaryAdvance += advance, kèm Transaction điều chỉnh.
            Gọi trong DB transaction của luồng sửa phiếu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositService.GetHistoryAsync(System.Int32)">
            <summary>
            Lấy lịch sử giao dịch cọc/tạm ứng của NV
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Search giao dich cọc/tạm ứng cho trang quản trị
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositService.GetBalanceAsync(System.Int32)">
            <summary>
            Lấy thông tin số dư cọc trách nhiệm + tạm ứng của NV
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.DepositService.ApplyWalletTransactionAsync(System.Int32,System.Decimal,Lada.Framework.Data.Enums.TransactionType,Lada.Framework.Data.Enums.TransactionDirection,System.String,System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Cập nhật ví Personal của lái xe + ghi Transaction, dùng cho mọi giao dịch cọc/tạm ứng.
            Ví Personal đóng vai trò sổ phụ "tiền công ty đang giữ của lái xe":
            nộp cọc/trừ từ lương → Income (+), hoàn cọc/tạm ứng → Outcome (−).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositTrackingService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Collections.Generic.List{System.Int32})">
            <summary>
            Danh sách lái xe kèm trạng thái cọc (Hạn mức / Đã đóng / Đang chờ / Còn thiếu)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IDepositTrackingService.GetSummaryAsync(System.Collections.Generic.List{System.Int32})">
            <summary>
            Số liệu tổng hợp cọc toàn công ty (theo scope agency của người xem)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.EmployeeSalaryConfigService.GetConfigsForPeriodAsync(System.Int32,System.Int32,System.Int32)">
            <summary>
            Lấy tất cả cấu hình lương có hiệu lực giao cắt với kỳ lương (month/year).
            Dùng cho Frontend hiển thị danh sách config khi lập phiếu lương.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Hr.IJobPostService">
            <summary>
            Giao diện cho dịch vụ quản lý bài đăng tuyển dụng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IJobPostService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm công việc.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm công việc.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IJobPostService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel)">
            <summary>
            Tạo hoặc cập nhật công việc.
            </summary>
            <param name="model">Thông tin công việc.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IJobPostService.GetById(System.Int32)">
            <summary>
            Lấy thông tin công việc theo ID.
            </summary>
            <param name="id">ID của công việc.</param>
            <returns>Thông tin công việc.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IJobPostService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa công việc theo ID.
            </summary>
            <param name="id">ID của công việc.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IJobPostService.UpdateStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobStatusModel,Lada.Framework.Data.Domains.Hr.JobStatus)">
            <summary>
            Cập nhật trạng thái công việc.
            </summary>
            <param name="model">Thông tin trạng thái công việc.</param>
            <param name="newStatus">Trạng thái mới của công việc.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.IJobPostService.RenewAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobRenewModel)">
            <summary>
            Gia hạn tin tuyển dụng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Hr.JobPostService">
            <summary>
            Triển khai dịch vụ quản lý bài đăng tuyển dụng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.JobPostService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Hr.JobPost},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Categories.Agency},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Cms.UrlRecord},Ladaer.BackEnd.Infrastructures.Services.Cms.IUrlRecordService,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Cms.Tag},Ladaer.BackEnd.Infrastructures.Services.Cms.ITagService,Lada.Framework.Infrastructures.Services.IContentFingerprint{Lada.Framework.Data.Domains.Hr.JobPost},Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchNotificationOutbox,Microsoft.Extensions.Logging.ILogger{Ladaer.BackEnd.Infrastructures.Services.Hr.JobPostService})">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Hr.JobPostService"/>.
            </summary>
            <param name="jobPostRepository">Đối tượng IRepository của JobPost.</param>
            <param name="agencyRepository">Đối tượng IRepository của Agency.</param>
            <param name="urlRecordRepository">Đối tượng IRepository của UrlRecord.</param>
            <param name="urlRecordService">Đối tượng IUrlRecordService.</param>
            <param name="jobPostFingerprint">Dấu vân tay nội dung tin tuyển dụng.</param>
            <param name="searchNotificationOutbox">Hàng đợi báo URL cho công cụ tìm kiếm.</param>
            <param name="logger">Nhật ký.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.JobPostService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel)">
            <summary>
            Tạo hoặc cập nhật công việc.
            </summary>
            <param name="model">Thông tin công việc.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.JobPostService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel)">
            <summary>
            Tạo mới công việc.
            </summary>
            <param name="jobPost">Thông tin công việc.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.JobPostService.NotifySearchEnginesAsync(Lada.Framework.Data.Domains.Hr.JobPost,System.Boolean,System.Boolean,System.Boolean)">
             <summary>
             Xếp hàng báo URL của tin cho công cụ tìm kiếm, nếu lần sửa này đáng báo.
            
             <para>
             Luật "lần sửa này đáng báo không, và báo loại gì" nằm ở
             <see cref="M:Lada.Framework.Infrastructures.Helpers.JobPostVisibility.DecideNotification(Lada.Framework.Data.Domains.Hr.JobPost,System.Boolean,System.Boolean,System.Boolean,System.DateTimeOffset)"/> — một hàm thuần, một nguồn duy nhất cho cả
             năm đường sửa tin (tạo, sửa, đổi trạng thái, gia hạn, xoá). Chỗ này chỉ còn việc nối luật ấy
             với hàng đợi.
             </para>
            
             <para>
             <b>Không bao giờ làm hỏng thao tác lưu.</b> Xếp hàng là việc phụ: một lỗi ở đây không được
             biến một lần lưu tin thành công thành thất bại dưới mắt người dùng.
             </para>
             </summary>
             <param name="jobPost">Tin vừa lưu, đã nạp <c>UrlRecord</c>.</param>
             <param name="wasPubliclyListed">Tin có đang được khai công khai <b>trước</b> lần sửa này không.</param>
             <param name="contentChanged">Dấu vân tay nội dung có đổi ở lần sửa này không.</param>
             <param name="isDeleted">Lần sửa này có phải là xoá tin không.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.JobPostService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostModel)">
            <summary>
            Cập nhật công việc.
            </summary>
            <param name="jobPost">Thông tin công việc.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.JobPostService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa công việc theo ID.
            </summary>
            <param name="id">ID của công việc.</param>
            <param name="currentUser">Thông tin người dùng hiện tại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.JobPostService.GetById(System.Int32)">
            <summary>
            Lấy thông tin công việc theo ID.
            </summary>
            <param name="jobPostId">ID của công việc.</param>
            <returns>Thông tin công việc.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.JobPostService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm công việc.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm công việc.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.JobPostService.UpdateStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobStatusModel,Lada.Framework.Data.Domains.Hr.JobStatus)">
            <summary>
            Cập nhật trạng thái công việc.
            </summary>
            <param name="model">Thông tin trạng thái công việc.</param>
            <param name="newStatus">Trạng thái mới của công việc.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.JobPostService.RenewAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobRenewModel)">
            <summary>
            Gia hạn tin tuyển dụng: cập nhật StartDate, EndDate và chuyển về Opening.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.JobPostService.UpdateJobPostTags(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.JobPostTagModel},System.Int32,System.String)">
            <summary>
            Cập nhật thẻ bài viết
            </summary>
            <param name="postTags">Danh sách thẻ bài viết.</param>
            <param name="createdBy">Người tạo.</param>
            <param name="createdByUserName">Tên người tạo.</param>
            <returns>Danh sách thẻ đã cập nhật.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Hr.IMyPayslipStatusService">
            <summary>
            Trạng thái phiếu lương gần nhất của CHÍNH người gọi (userId lấy từ JWT ở controller) — thẻ "Phiếu lương tháng M"
            trên đầu Bảng tin (docs/plan-bang-tin-noi-bo.md §3.8, §3.16). Tách khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Hr.IPayrollService"/>: chỉ đọc, một
            truy vấn, không kéo chi tiết thu nhập/khấu trừ như <c>MyPayroll</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.MyPayslipStatusService.GetLatestAsync(System.Int32)">
            <summary>
            Phiếu kỳ mới nhất KHÁC Bản nháp (nhân sự còn đang làm — chưa gửi cho người lao động). Không ghi gì: trạng thái
            "đã chi" suy ra lúc đọc bằng <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollStatusRules.Effective(Lada.Framework.Data.Enums.PayrollStatus,System.Nullable{Lada.Framework.Data.Enums.ExpenseStatus})"/> — cùng hàm <c>PayrollService</c> dùng để
            ghi lại (trang phiếu lương mới là nơi ghi).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.GetMyPendingPayrollAsync(System.Int32)">
            <summary>
            Lấy phiếu lương đang chờ xác nhận (PendingConfirmation) mới nhất cho NLĐ.
            Dùng cho Driver App — không cần truyền month/year.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.SendForConfirmationAsync(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            KT gửi phiếu cho NLĐ xác nhận
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.ConfirmPayrollAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.PayrollConfirmModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            NLĐ xác nhận → auto tạo Expense
            NLĐ từ chối → quay lại Draft
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.LockFuelRefillsForPayrollAsync(System.Int32,System.Int32,System.Int32,System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Khóa các phiếu đổ dầu đã dùng để tính thu nhập dầu của kỳ lương này.
            Gọi khi phiếu lương chuyển Confirmed — chốt cứng DifferenceLiters, tránh recalc chuỗi
            làm lệch snapshot FuelIncome đã trả cho NLĐ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.UnlockFuelRefillsForPayrollAsync(System.Guid,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Mở khóa các phiếu đổ dầu đã bị kỳ lương này khóa.
            Gọi khi phiếu lương Confirmed bị mở lại về Draft (KT sửa) — chỉ mở đúng phiếu
            có LockedByPayrollId == payrollId, không đụng phiếu đã bị kỳ khác khóa.
            KHÔNG dùng cho phiếu lương Paid (khóa vĩnh viễn).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.CalculateExpectedAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Hr.CreatePayrollModel,System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Preview tính lương cho 1 nhân viên — không lưu DB.
            Dùng cho chức năng "Tính trước" trên form lập phiếu lương.
            So sánh EffectiveFrom/To với kỳ lương (month/year) thay vì ngày hiện tại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.CalculateWorkCredits(System.Double)">
            <summary>
            Quy tắc ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceFormulas.CalculateWorkCredits(System.Double)"/> — nguồn sự thật duy nhất,
            dùng chung với chi tiết chấm công.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.CalculateOvertimeKips(System.Double)">
            <summary>
            Quy tắc ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Hr.AttendanceFormulas.CalculateOvertimeKips(System.Double)"/> — nguồn sự thật duy nhất,
            dùng chung với chi tiết chấm công. Đầu vào là giờ THÔ của từng ca.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.CalculateRevenueForUsers(System.Collections.Generic.List{System.Int32},System.Int32,System.Int32)">
            <summary>
            Tính doanh số ghi nhận (đã trừ VAT 8%) cho danh sách userIds trong kỳ.
            Dùng chung cho: cá nhân Sale, team TeamLeader, bưu cục BranchManager.
            Logic khớp với SP sp_GetOrderRevenueStatisticsBySale_Optimized (RecognizedRevenue).
            </summary>
            <remarks>
            Ranh giới kỳ đọc bằng <c>.Month</c>/<c>.Year</c> — EF dịch thành <c>DATEPART</c> trên
            chính giá trị lưu, mà cột <c>Head*FeeTime</c> lưu giờ Việt Nam +07:00, nên kỳ cắt đúng
            theo giờ Việt Nam. Đừng đổi sang so sánh với mốc <c>DateTimeOffset</c> dựng ở UTC: đó
            đúng là lỗi đã làm SP lệch 7 giờ so với hàm này (memory
            <c>bay-mui-gio-cast-datetimeoffset</c>, sửa bằng migration 202608161600).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.CalculateCommission(System.Decimal,Lada.Framework.Data.Domains.Hr.EmployeeSalaryConfig)">
            <summary>
            Tính hoa hồng cá nhân dựa theo CommissionType (Flat hoặc Tiered).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.CalculatePitAmount(System.Decimal)">
            <summary>
            Tính thuế TNCN theo biểu thuế lũy tiến từng phần 7 bậc (Luật Thuế TNCN Việt Nam).
            Sử dụng công thức tính nhanh (shortcut formula).
            </summary>
        </member>
        <!-- Badly formed XML comment ignored for member "M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.GetConfigsForPeriodAsync(System.Int32,System.Int32,System.Int32)" -->
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.CalculateProRataDays(Lada.Framework.Data.Domains.Hr.EmployeeSalaryConfig,System.Int32,System.Int32)">
            <summary>
            Tính số ngày hiệu lực thực tế của 1 cấu hình lương trong kỳ lương.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.BuildPayrollRecordMultiConfig(System.Collections.Generic.List{Lada.Framework.Data.Domains.Hr.EmployeeSalaryConfig},System.Int32,System.Int32,System.Int32,Lada.Framework.Infrastructures.CurrentUser,System.Nullable{System.Decimal},System.Nullable{System.Decimal},System.Decimal,System.Decimal)">
            <summary>
            Tính lương pro-rata khi nhân viên có nhiều cấu hình lương trong cùng tháng.
            Lương CB, phụ cấp: chia theo số ngày hiệu lực của từng config.
            Chấm công: lọc theo khoảng ngày của từng config.
            Hoa hồng, doanh số: tính toàn tháng, áp dụng tỷ lệ config cuối cùng.
            BHXH: lấy mức cao nhất.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.GetBranchMemberIdsAsync(System.Int32)">
            <summary>
            Lấy danh sách ID thành viên thuộc chi nhánh do userId quản lý.
            Ưu tiên: Agency.ManagerId → User.AgencyId.
            Fallback: User.ManagerId trực tiếp (khi chưa cấu hình AgencyId cho nhân viên).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollService.GetTeamRevenueDetailsAsync(System.Int32,System.Int32,System.Int32)">
            <summary>
            Lấy chi tiết doanh số từng thành viên trong team/bưu cục.
            Dùng cho SaleTeamLeader (mode 4) và BranchManager (mode 5).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollStatusRules">
            <summary>
            Luật trạng thái phiếu lương dùng chung — MỘT chỗ cho nơi ghi lại (<c>PayrollService.SyncRecordStatusIfNeededAsync</c>)
            và nơi chỉ đọc (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Hr.MyPayslipStatusService"/>, thẻ phiếu lương trên Bảng tin), để hai nơi không trôi khỏi nhau
            (review GĐ C bảng tin nội bộ).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Hr.PayrollStatusRules.Effective(Lada.Framework.Data.Enums.PayrollStatus,System.Nullable{Lada.Framework.Data.Enums.ExpenseStatus})">
            <summary>"NLĐ đã xác nhận" mà phiếu chi tự tạo đã chi → "Đã thanh toán"; mọi trường hợp khác giữ nguyên.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService">
            <summary>
            Service interface for managing Permission Groups and Role assignments
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService.CreatePermissionAsync(System.String,System.String,System.Collections.Generic.List{System.Int32})">
            <summary>
            Tạo Permission Group mới
            </summary>
            <param name="name">Tên Permission Group</param>
            <param name="description">Mô tả</param>
            <param name="roleIds">Danh sách Role ID</param>
            <returns>Permission đã tạo</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService.UpdatePermissionAsync(System.Int32,System.String,System.String,System.Collections.Generic.List{System.Int32})">
            <summary>
            Cập nhật Permission Group
            </summary>
            <param name="permissionId">ID của Permission</param>
            <param name="name">Tên mới</param>
            <param name="description">Mô tả mới</param>
            <param name="roleIds">Danh sách Role ID mới</param>
            <returns>Permission đã cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService.DeletePermissionAsync(System.Int32)">
            <summary>
            Xóa Permission Group
            </summary>
            <param name="permissionId">ID của Permission</param>
            <returns>True nếu xóa thành công</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService.AssignPermissionToUserAsync(System.Int32,System.Int32)">
            <summary>
            Gán Permission cho User và tự động cập nhật UserRole
            </summary>
            <param name="userId">ID của User</param>
            <param name="permissionId">ID của Permission</param>
            <returns>True nếu gán thành công</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService.RemovePermissionFromUserAsync(System.Int32)">
            <summary>
            Xóa Permission khỏi User và xóa tất cả UserRole
            </summary>
            <param name="userId">ID của User</param>
            <returns>True nếu xóa thành công</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService.GetAllPermissionsAsync">
            <summary>
            Lấy danh sách Permission
            </summary>
            <returns>Danh sách Permission</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService.GetPermissionByIdAsync(System.Int32)">
            <summary>
            Lấy Permission theo ID
            </summary>
            <param name="permissionId">ID của Permission</param>
            <returns>Permission hoặc null</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService.GetRolesInPermissionAsync(System.Int32)">
            <summary>
            Lấy danh sách Role trong Permission
            </summary>
            <param name="permissionId">ID của Permission</param>
            <returns>Danh sách Role</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService.UserHasRoleAsync(System.Int32,System.String)">
            <summary>
            Kiểm tra User có quyền truy cập Role không
            </summary>
            <param name="userId">ID của User</param>
            <param name="roleName">Tên Role cần kiểm tra</param>
            <returns>True nếu có quyền</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm Permission với phân trang
            </summary>
            <param name="param">Tham số tìm kiếm</param>
            <returns>Kết quả tìm kiếm có phân trang</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService.GetAllAvailableRolesAsync">
            <summary>
            Lấy tất cả Roles có thể gán cho Permission
            </summary>
            <returns>Danh sách tất cả Roles</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Itentity.PermissionModel)">
            <summary>
            Tạo hoặc cập nhật Permission (theo pattern AgencyController)
            </summary>
            <param name="model">PermissionModel</param>
            <returns>PermissionResult</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService.GetById(System.Int32)">
            <summary>
            Lấy Permission theo ID và chuyển về PermissionModel
            </summary>
            <param name="id">ID của Permission</param>
            <returns>PermissionModel</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IPermissionService.UpdatePermissionRoles(Ladaer.BackEnd.Infrastructures.DTO.Models.Itentity.PermissionRoleModel)">
            <summary>
            Cập nhật danh sách Role của Permission (hàm riêng biệt)
            </summary>
            <param name="permissionId">ID của Permission</param>
            <param name="roleIds">Danh sách Role ID mới</param>
            <returns>PermissionResult</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Identity.IRoleMigrationService">
            <summary>
            Service for migrating from old role naming convention to new Controller.Action pattern
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IRoleMigrationService.CreateNewRolesAsync">
            <summary>
            Tạo tất cả Role mới theo pattern Controller.Action
            </summary>
            <returns>Danh sách Role đã tạo</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IRoleMigrationService.CreateDefaultPermissionGroupsAsync">
            <summary>
            Tạo Permission Groups mặc định tương ứng với các vai trò cũ
            </summary>
            <returns>Danh sách Permission đã tạo</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IRoleMigrationService.MigrateUsersToPermissionGroupsAsync">
            <summary>
            Migration Users từ old roles sang Permission Groups
            </summary>
            <returns>Số lượng User đã migration</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IRoleMigrationService.GetNewRolesToCreate">
            <summary>
            Lấy danh sách Role mới cần tạo
            </summary>
            <returns>Dictionary với key là role name, value là description</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IRoleMigrationService.GetOldRoleToPermissionMapping">
            <summary>
            Lấy mapping từ old roles sang Permission Groups
            </summary>
            <returns>Dictionary với key là old role, value là Permission Group name</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IRoleMigrationService.IsMigrationCompletedAsync">
            <summary>
            Kiểm tra xem migration đã hoàn thành chưa
            </summary>
            <returns>True nếu đã migration xong</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IRoleMigrationService.RunFullMigrationAsync">
            <summary>
            Chạy full migration process
            </summary>
            <returns>Migration result</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Identity.MigrationResult">
            <summary>
            Result of migration process
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserRoleResolver">
            <summary>
            Service tái sử dụng: lấy toàn bộ Role names của user
            (kết hợp UserRole trực tiếp + Role từ Permission nếu có).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Identity.PermissionService">
            <summary>
            Service for managing Permission Groups and Role assignments
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Identity.RoleMigrationService">
            <summary>
            Service for migrating from old role naming convention to new Controller.Action pattern
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Identity.UserRoleResolver">
            <summary>
            Service tái sử dụng: lấy toàn bộ Role names của user
            (kết hợp UserRole trực tiếp + Role từ Permission nếu có).
            Kết quả được cache để giảm tải DB.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService">
            <summary>
            Giao diện cho dịch vụ quản lý người dùng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService.SugUser(System.String,Lada.Framework.Data.Enums.UserType,System.String,System.Nullable{System.Int32},System.Nullable{System.Int32},System.Collections.Generic.List{System.Int32},System.Collections.Generic.List{System.Int32})">
            <summary>
            Gợi ý người dùng dựa trên từ khóa và loại người dùng.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="userType">Loại người dùng.</param>
            <param name="roleName">Tên vai trò (tùy chọn).</param>
            <param name="managerId">ID người quản lý, chỉ lấy staff do manager này quản lý (tùy chọn).</param>
            <param name="userIds">Danh sách Id người dùng được phép trả về (tùy chọn).</param>
            <returns>Danh sách người dùng gợi ý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService.GetDataAccessScopeAsync(System.Int32)">
            <summary>
            Lấy phạm vi truy cập dữ liệu của người dùng.
            </summary>
            <param name="userId">ID của người dùng.</param>
            <returns>Phạm vi truy cập dữ liệu.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService.GetSubordinateIdsAsync(System.Int32)">
            <summary>
            Lấy Id các nhân viên do một người quản lý trực tiếp (không gồm chính người đó).
            </summary>
            <param name="managerId">Id người quản lý.</param>
            <returns>Danh sách Id nhân viên cấp dưới.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService.AutoComplete(System.String,Lada.Framework.Data.Enums.UserType)">
            <summary>
            Tự động hoàn thành tìm kiếm người dùng dựa trên từ khóa và loại người dùng.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="userType">Loại người dùng.</param>
            <returns>Danh sách người dùng gợi ý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService.AutoCompleteByAgency(System.String,System.Int32)">
            <summary>
            Tự động hoàn thành tìm kiếm người dùng dựa trên từ khóa và ID đại lý.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="agencyId">ID của đại lý.</param>
            <returns>Danh sách người dùng gợi ý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService.GetByIdAsync(System.Int32)">
            <summary>
            Lấy thông tin nhân viên theo ID.
            </summary>
            <param name="id">ID của nhân viên.</param>
            <returns>Thông tin nhân viên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService.GetByListIdAsync(System.Collections.Generic.List{System.Int32})">
            <summary>
            Lấy danh sách thông tin nhân viên theo danh sách ID.
            </summary>
            <param name="ids">Danh sách ID của nhân viên.</param>
            <returns>Danh sách thông tin nhân viên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService.GetAgencyIdByIdAsync(System.Int32)">
            <summary>
            Lấy ID của đại lý theo ID của nhân viên.
            </summary>
            <param name="id">ID của nhân viên.</param>
            <returns>ID của đại lý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService.GetRolesAsync(System.Int32)">
            <summary>
            Lấy danh sách quyền của người dùng
            </summary>
            <param name="id">ID của nhân viên.</param>
            <returns>Danh sách quyền.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService.GetUserLogin(System.String)">
            <summary>
            Lấy thông tin người dùng cần đăng nhập
            </summary>
            <param name="userKeyword"></param>
            <returns></returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService.ChangePassword(Ladaer.BackEnd.Infrastructures.DTO.Models.Users.ChangePasswordModel)">
            <summary>
            Đổi mật khẩu cho người dùng
            </summary>
            <param name="model">Thông tin đổi mật khẩu</param>
            <returns>Kết quả đổi mật khẩu</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService.ResetPasswordByAdmin(System.Int32,System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Đặt lại mật khẩu theo quyền quản trị — KHÔNG cần biết mật khẩu cũ.
            </summary>
            <remarks>
            Khác <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService.SetPassword(Ladaer.BackEnd.Infrastructures.DTO.Models.Users.SetPasswordModel)"/>: hàm đó đối chiếu cột <c>User.Password</c> (mật khẩu thô)
            làm mật khẩu hiện tại, nên chỉ chạy được với tài khoản nhân viên do backend này tạo ra.
            Tài khoản khách hàng đăng ký từ Lada.AppBackEnd luôn để cột đó rỗng, dùng đường kia sẽ
            hỏng. Ở đây sinh token đặt lại mật khẩu của Identity nên không phụ thuộc cột mật khẩu thô.
            </remarks>
            <param name="userId">Id tài khoản cần đặt lại mật khẩu.</param>
            <param name="newPassword">Mật khẩu mới.</param>
            <param name="currentUser">Người thực hiện, dùng để đóng dấu cập nhật.</param>
            <returns>Kết quả đặt lại mật khẩu.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService.CreateCustomerAccount(Ladaer.BackEnd.Infrastructures.DTO.Models.Users.CreateCustomerAccountModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo tài khoản đăng nhập kiểu khách hàng (<c>UserType.Customer</c>).
            </summary>
            <remarks>
            Tài khoản khách hàng không thuộc chi nhánh và không có nhóm quyền nội bộ, nên không
            dùng chung đường <c>RegisterStaff</c> — đường đó bắt buộc phải có <c>AgencyId</c> hợp lệ.
            </remarks>
            <param name="model">Tên đăng nhập, mật khẩu và thông tin nhân thân lấy từ hồ sơ khách hàng.</param>
            <param name="currentUser">Người thực hiện.</param>
            <returns>Kết quả tạo tài khoản, <c>UserId</c> là Id tài khoản vừa tạo khi thành công.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService">
            <summary>
            Triển khai dịch vụ quản lý người dùng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService.#ctor(Microsoft.Extensions.Configuration.IConfiguration,Lada.Framework.Data.Repositories.IUserRepository{Lada.Framework.Data.Domains.Identity.User},Microsoft.AspNetCore.Identity.UserManager{Lada.Framework.Data.Domains.Identity.User},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Identity.RefreshToken},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Categories.Agency},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Identity.Permission},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Identity.UserPreference})">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService"/>.
            </summary>
            <param name="userRepository">Đối tượng IUserRepository của User.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService.SugUser(System.String,Lada.Framework.Data.Enums.UserType,System.String,System.Nullable{System.Int32},System.Nullable{System.Int32},System.Collections.Generic.List{System.Int32},System.Collections.Generic.List{System.Int32})">
            <summary>
            Gợi ý người dùng dựa trên từ khóa và loại người dùng.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="userType">Loại người dùng.</param>
            <param name="roleName">Tên vai trò (tùy chọn).</param>
            <returns>Danh sách người dùng gợi ý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService.GetDataAccessScopeAsync(System.Int32)">
            <summary>
            Lấy phạm vi truy cập dữ liệu của người dùng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService.GetSubordinateIdsAsync(System.Int32)">
            <summary>
            Lấy Id các nhân viên do một người quản lý trực tiếp (không gồm chính người đó).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService.AutoComplete(System.String,Lada.Framework.Data.Enums.UserType)">
            <summary>
            Tự động hoàn thành tìm kiếm người dùng dựa trên từ khóa và loại người dùng.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="userType">Loại người dùng.</param>
            <returns>Danh sách người dùng gợi ý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService.AutoCompleteByAgency(System.String,System.Int32)">
            <summary>
            Tự động hoàn thành tìm kiếm người dùng dựa trên từ khóa và ID đại lý.
            </summary>
            <param name="keyword">Từ khóa tìm kiếm.</param>
            <param name="agencyId">ID của đại lý.</param>
            <returns>Danh sách người dùng gợi ý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService.GetByIdAsync(System.Int32)">
            <summary>
            Lấy thông tin nhân viên theo ID.
            </summary>
            <param name="id">ID của nhân viên.</param>
            <returns>Thông tin nhân viên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService.GetByListIdAsync(System.Collections.Generic.List{System.Int32})">
            <summary>
            Lấy danh sách thông tin nhân viên theo danh sách ID.
            </summary>
            <param name="ids">Danh sách ID của nhân viên.</param>
            <returns>Danh sách thông tin nhân viên.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService.GetAgencyIdByIdAsync(System.Int32)">
            <summary>
            Lấy ID của đại lý theo ID của nhân viên.
            </summary>
            <param name="id">ID của nhân viên.</param>
            <returns>ID của đại lý.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService.GetRolesAsync(System.Int32)">
            <summary>
            Lấy danh sách quyền của người dùng từ cả UserRole và PermissionRole
            </summary>
            <param name="id">ID của nhân viên.</param>
            <returns>Danh sách quyền.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService.ChangePassword(Ladaer.BackEnd.Infrastructures.DTO.Models.Users.ChangePasswordModel)">
            <summary>
            Đổi mật khẩu cho người dùng
            </summary>
            <param name="model">Thông tin đổi mật khẩu</param>
            <returns>Kết quả đổi mật khẩu</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService.SetPassword(Ladaer.BackEnd.Infrastructures.DTO.Models.Users.SetPasswordModel)">
            <summary>
            Đổi mật khẩu cho người dùng
            </summary>
            <param name="model">Thông tin đổi mật khẩu</param>
            <returns>Kết quả đổi mật khẩu</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService.ResetPasswordByAdmin(System.Int32,System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Đặt lại mật khẩu theo quyền quản trị — không cần mật khẩu cũ.
            </summary>
            <param name="userId">Id tài khoản cần đặt lại mật khẩu.</param>
            <param name="newPassword">Mật khẩu mới.</param>
            <param name="currentUser">Người thực hiện.</param>
            <returns>Kết quả đặt lại mật khẩu.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService.CreateCustomerAccount(Ladaer.BackEnd.Infrastructures.DTO.Models.Users.CreateCustomerAccountModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo tài khoản đăng nhập kiểu khách hàng.
            </summary>
            <param name="model">Tên đăng nhập, mật khẩu và thông tin nhân thân lấy từ hồ sơ khách hàng.</param>
            <param name="currentUser">Người thực hiện.</param>
            <returns>Kết quả tạo tài khoản, <c>UserId</c> là Id tài khoản vừa tạo khi thành công.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserService.GetAllUserRoles(Lada.Framework.Data.Domains.Identity.User)">
            <summary>
            Lấy tất cả roles của user từ cả UserRole và PermissionRole
            </summary>
            <param name="user">User entity với UserRoles và Permission.PermissionRoles đã được Include</param>
            <returns>Danh sách role names (không trùng lặp)</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserTrackService">
            <summary>
            Service ghi và truy vấn lịch sử thao tác người dùng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserTrackService.CreateAsync(System.Int32,Lada.Framework.Data.Enums.UserTrackAction,System.String,Lada.Framework.Infrastructures.CurrentUser,System.Nullable{System.Decimal},System.String,System.String,System.String,Lada.Framework.Data.Enums.ActionSource)">
            <summary>
            Ghi 1 bản ghi lịch sử
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserTrackService.GetByUserIdAsync(System.Int32,System.Int32)">
            <summary>
            Lấy lịch sử theo UserId
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Identity.UserTrackService.GetEnumDescription(System.Enum)">
            <summary>
            Lấy Description attribute của enum value
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsActor">
            <summary>Người đang thao tác (đóng dấu audit + tra quyền).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsActor.#ctor(System.Int32,System.String)">
            <summary>Người đang thao tác (đóng dấu audit + tra quyền).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsPostAccess">
            <summary>Ai được sửa bài nào: mức công ty sửa mọi bài; mức đơn vị chỉ sửa bài mình là tác giả (plan §3.4).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsNotifyBatches">
            <summary>
            Chia người nhận chuông thành lô theo ĐỘ DÀI chuỗi id (Việc 0 §4.0 dòng "+"): <c>SendToUsersAsync</c> ghi
            <c>string.Join(",", userIds)</c> vào <c>Notification.ScopeValue nvarchar(1024)</c> — lô theo số người cố định
            (500) làm tràn cột và chuông của cả lô lỗi.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsAdminService">
            <summary>
            Người soạn bài Bảng tin nội bộ (plan §3.1–§3.7): thông tin bài, đối tượng, bản đang sửa, đăng / hẹn giờ / đăng lại /
            thu hồi / lưu trữ, ước tính người nhận, xem trước, và hai việc của job đăng theo lịch.
            </summary>
            <remarks>
            Hàng rào: controller gác role <c>InternalNews.Manage | InternalNews.PublishAll</c>; service kiểm PHẠM VI từng dòng
            đối tượng lúc lưu VÀ lúc đăng (§3.11 mục 4) và chỉ cho mức đơn vị sửa bài của chính mình. Bài ngoài phạm vi sửa trả
            404 (không lộ tồn tại); vượt phạm vi đối tượng trả 403.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsAdminService.GetAudienceOptionsAsync(Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsActor)">
            <summary>Nhóm quyền / đơn vị / loại đơn vị cho ô chọn đối tượng, đã lọc theo phạm vi người đăng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsAdminService.SearchAudienceUsersAsync(System.String,Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsActor)">
            <summary>
            Tìm người để chọn đích danh (≥ 2 ký tự, theo họ tên / tên đăng nhập, tối đa 20): nhân viên + người bưu cục còn
            sống, không đang khoá; mức đơn vị chỉ thấy người thuộc cây đơn vị mình quản lý.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsAdminService.ResolveRecipientsAsync(Lada.Framework.Data.Enums.InternalNewsAudienceScope,System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.InternalNews.InternalNewsAudience})">
            <summary>
            Người nhận chuông của một bộ đối tượng + phạm vi bài: còn sống, không đang khoá, khớp resolver (KHÔNG cộng Founder).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsAdminService.PreviewAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsActor)">
            <summary>Bản đang sửa đã lọc, cùng hình chi tiết người đọc — cho nút "Xem trước".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsAdminService.PublishDueAsync(System.DateTimeOffset)">
            <summary>Bài hẹn giờ tới giờ → đăng (đúng đường đăng tay), cùng một phạm vi DI. Trả số bài đã đăng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsAdminService.ListDuePostIdsAsync(System.DateTimeOffset)">
            <summary>Id bài hẹn giờ đã tới giờ — job tách từng bài ra phạm vi DI riêng (một bài lỗi không kéo bài sau).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsAdminService.PublishScheduledAsync(System.Int32,System.DateTimeOffset)">
            <summary>Đăng MỘT bài hẹn giờ đã tới giờ; không đủ điều kiện / mất quyền → về nháp. True = đã đăng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsAdminService.ArchiveExpiredAsync(System.DateTimeOffset)">
            <summary>Job: bài đã đăng quá <c>ExpiresAt</c> → lưu trữ. Trả số bài đã lưu trữ.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAdminService.SystemUserId">
            <summary>Người đóng dấu các lần ghi của job <c>internal-news-schedule</c> (đưa bài về nháp, tự lưu trữ).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAdminService.IsScheduleCancelledBySystem(Lada.Framework.Data.Domains.InternalNews.InternalNewsPost)">
            <summary>
            Bài đang là nháp vì job tới giờ đăng mà không đăng được (người hẹn mất quyền, tệp / đích bị xoá, quá ngày tự lưu
            trữ) — đọc từ dấu người sửa cuối của job, tự tắt khi có người lưu bài lại (nợ BT-9: lý do cụ thể chỉ có ở log).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAdminService.CheckExistingAudiencesAsync(Lada.Framework.Data.Domains.InternalNews.InternalNewsPost,Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope)">
            <summary>
            Người mức đơn vị không được sửa bài mà đối tượng HIỆN CÓ đã vượt phạm vi của mình (vd. người mức công ty mở rộng
            thành "Tất cả") — thông tin bài có hiệu lực ngay khi lưu, nên sửa tiêu đề cũng là sửa một bài toàn công ty.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAdminService.ValidateInfoAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsPostModel,Lada.Framework.Data.Domains.InternalNews.InternalNewsPost)">
            <param name="existing">Bài đang sửa (null = bài mới). Ngày tự lưu trữ chỉ bị kiểm khi người soạn ĐỔI nó — bài
            đã quá hạn / đã lưu trữ vẫn sửa được tiêu đề mà không phải xoá ngày cũ.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAdminService.CheckAudiencesAsync(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudienceModel},Lada.Framework.Data.Enums.InternalNewsAudienceScope,Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope)">
            <summary>
            Phạm vi người đăng TRƯỚC (403), rồi mới tới đích có thật (nhóm / đơn vị / người còn sống), cuối cùng mâu thuẫn với
            phạm vi bài (400, §6.6): kiểm tồn tại trước thì người mức đơn vị dò được Id nào có thật ngoài phạm vi mình qua câu
            báo lỗi khác nhau (review GĐ A).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAdminService.TargetFactsAsync(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudienceModel})">
            <summary>
            Đích đã tra cho luật mâu thuẫn phạm vi (§6.6): đơn vị còn sống được chọn (loại + tên) và người được chọn thuộc phía
            nhượng quyền — phân loại người bằng đúng <see cref="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext.IsLada"/> của resolver, không viết lần hai.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAdminService.IsFranchiseSide(Lada.Framework.Data.Enums.UserType,System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.InternalNews.AgencyTree)">
            <summary>Người nội bộ thuộc phía nhượng quyền theo luật §6.6 (khách hàng không thuộc phía nào — không thấy bài nào).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAdminService.ValidateBlocksAsync(System.Int32,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.DTO.Models.Cms.ProductBlockModel})">
            <summary>Kiểm từng khối theo hồ sơ bảng tin + tệp mà khối Video / Tài liệu tham chiếu phải THUỘC BÀI NÀY.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAdminService.PreparePublishAsync(Lada.Framework.Data.Domains.InternalNews.InternalNewsPost,Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope,System.DateTimeOffset)">
            <summary>
            Kiểm lại TOÀN BỘ trước khi chụp, không tin lần lưu trước: ngày tự lưu trữ còn sau lúc lên bảng tin, đối tượng
            (có ≥ 1 dòng, đúng phạm vi người đăng LÚC NÀY), bộ khối (luật lưu + ≥ 1 khối + tệp còn thuộc bài), lọc HTML lần nữa.
            </summary>
            <param name="goLiveAt">Lúc bài lên bảng tin: bây giờ (đăng ngay / job) hoặc giờ hẹn.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAdminService.NotifyAsync(Lada.Framework.Data.Domains.InternalNews.InternalNewsPost,System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.InternalNews.InternalNewsAudience})">
            <summary>
            Gửi chuông theo lô; lô lỗi thì DỪNG (thực thể Notification hỏng còn kẹt trong DbContext dùng chung làm mọi lô
            sau lỗi theo) và trả đúng số người đã nhận — nơi gọi nói được "đã gửi a/b", không nói sai là "chưa gửi".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAdminService.Sanitized(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.InternalNews.InternalNewsBlock})">
            <summary>Bộ khối đã lọc HTML lần nữa — đúng thứ sẽ vào ảnh chụp.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAdminService.DraftVersion(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.InternalNews.InternalNewsBlock})">
            <summary>Dấu bản đang sửa: tính trên payload ĐÃ LƯU (không lọc lại) để hai lần đọc liền nhau luôn ra cùng dấu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAdminService.ReferencedFilesAsync(System.Int32,System.Collections.Generic.IEnumerable{System.ValueTuple{Lada.Framework.Data.Enums.ProductBlockType,System.String}})">
            <summary>Tệp của bài mà các khối tham chiếu (người đọc chỉ nhận đúng các tệp này).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAdminService.SummarizeAsync(Lada.Framework.Data.Enums.InternalNewsAudienceScope,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudienceModel})">
            <summary>
            Chữ "Chỉ nhân viên LADA: Nhóm Kinh doanh · BC Hải Phòng (+đơn vị con)" / "Gồm cả bưu cục NQ: …" (512 ký tự) —
            tiền tố phạm vi để cột Đối tượng của danh sách nói đủ ai nhận (§6.6).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAdminService.AgencyTypeLabel(Lada.Framework.Data.Domains.Categories.AgencyType)">
            <summary>
            "Mọi bưu cục nhượng quyền" / "Mọi chi nhánh của LADA" — chỉ hạ chữ cái đầu của mô tả, không hạ cả chuỗi (từng ra
            "Mọi phòng ban của lada" ở ô chọn và tóm tắt đối tượng).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope">
            <summary>
            Phạm vi đăng của một người (plan §3.4, §3.13 mục 9, chốt §6.2). <see cref="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope.CanPublishAll"/> (role PublishAll hoặc
            Founder) đăng cho bất kỳ ai; chỉ <see cref="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope.CanManage"/> thì chỉ đăng cho đơn vị trong <see cref="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope.ManageableAgencyIds"/>
            (đơn vị đứng tên <c>Agency.ManagerId</c> + con cháu, cộng riêng đơn vị mình làm việc <c>User.AgencyId</c>) và người
            thuộc các đơn vị đó.
            </summary>
            <param name="ChildrenAgencyIds">
            Đơn vị được chọn KÈM "gồm đơn vị con" — chỉ cây mình đứng tên. Đơn vị mình chỉ làm việc ở thì chọn được nhưng không
            kèm con: không có tập này thì tick "gồm đơn vị con" trên chính <c>User.AgencyId</c> phủ cả cây bên dưới (security
            review GĐ A). <c>null</c> = rỗng.
            </param>
            <param name="ForcedAudienceScope">
            Phạm vi bài mà người này BỊ ÉP (mức đơn vị, §5 câu 12c — <see cref="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAudienceRules.ForcedAudienceScope(System.Boolean,System.Collections.Generic.IEnumerable{System.Nullable{Lada.Framework.Data.Domains.Categories.AgencyType}})"/>);
            <c>null</c> = được chọn. Máy chủ tự đặt lúc lưu, kiểm lại lúc đăng.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope.#ctor(System.Int32,System.String,System.Boolean,System.Boolean,System.Collections.Generic.IReadOnlySet{System.Int32},System.Collections.Generic.IReadOnlySet{System.Int32},System.Nullable{Lada.Framework.Data.Enums.InternalNewsAudienceScope})">
            <summary>
            Phạm vi đăng của một người (plan §3.4, §3.13 mục 9, chốt §6.2). <see cref="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope.CanPublishAll"/> (role PublishAll hoặc
            Founder) đăng cho bất kỳ ai; chỉ <see cref="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope.CanManage"/> thì chỉ đăng cho đơn vị trong <see cref="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope.ManageableAgencyIds"/>
            (đơn vị đứng tên <c>Agency.ManagerId</c> + con cháu, cộng riêng đơn vị mình làm việc <c>User.AgencyId</c>) và người
            thuộc các đơn vị đó.
            </summary>
            <param name="ChildrenAgencyIds">
            Đơn vị được chọn KÈM "gồm đơn vị con" — chỉ cây mình đứng tên. Đơn vị mình chỉ làm việc ở thì chọn được nhưng không
            kèm con: không có tập này thì tick "gồm đơn vị con" trên chính <c>User.AgencyId</c> phủ cả cây bên dưới (security
            review GĐ A). <c>null</c> = rỗng.
            </param>
            <param name="ForcedAudienceScope">
            Phạm vi bài mà người này BỊ ÉP (mức đơn vị, §5 câu 12c — <see cref="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAudienceRules.ForcedAudienceScope(System.Boolean,System.Collections.Generic.IEnumerable{System.Nullable{Lada.Framework.Data.Domains.Categories.AgencyType}})"/>);
            <c>null</c> = được chọn. Máy chủ tự đặt lúc lưu, kiểm lại lúc đăng.
            </param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope.ChildrenAgencyIds">
            <summary>
            Đơn vị được chọn KÈM "gồm đơn vị con" — chỉ cây mình đứng tên. Đơn vị mình chỉ làm việc ở thì chọn được nhưng không
            kèm con: không có tập này thì tick "gồm đơn vị con" trên chính <c>User.AgencyId</c> phủ cả cây bên dưới (security
            review GĐ A). <c>null</c> = rỗng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope.ForcedAudienceScope">
            <summary>
            Phạm vi bài mà người này BỊ ÉP (mức đơn vị, §5 câu 12c — <see cref="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAudienceRules.ForcedAudienceScope(System.Boolean,System.Collections.Generic.IEnumerable{System.Nullable{Lada.Framework.Data.Domains.Categories.AgencyType}})"/>);
            <c>null</c> = được chọn. Máy chủ tự đặt lúc lưu, kiểm lại lúc đăng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope.CanIncludeChildren(System.Int32)">
            <summary>Được chọn đơn vị này kèm "gồm đơn vị con" không.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope.CanChooseAudienceScope">
            <summary>Thấy lựa chọn phạm vi (Chỉ nhân viên LADA / Gồm cả bưu cục nhượng quyền) không.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope.EffectiveAudienceScope(System.Nullable{Lada.Framework.Data.Enums.InternalNewsAudienceScope},System.Nullable{Lada.Framework.Data.Enums.InternalNewsAudienceScope})">
            <summary>
            Phạm vi thật sẽ lưu: bị ép thì lấy phạm vi ép (bỏ qua thứ gửi lên), không gửi thì giữ phạm vi đang có, bài mới
            mặc định <c>LadaOnly</c> (§5 câu 12a).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.AudienceTargetFacts">
            <summary>
            Đích đã tra từ DB cho luật mâu thuẫn phạm vi (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAudienceRules.CheckAudienceScope(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudienceModel},Lada.Framework.Data.Enums.InternalNewsAudienceScope,Ladaer.BackEnd.Infrastructures.Services.InternalNews.AudienceTargetFacts)"/>): loại + tên
            các đơn vị được chọn còn sống, và các người được chọn thuộc phía nhượng quyền (tên hiển thị).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.AudienceTargetFacts.#ctor(System.Collections.Generic.IReadOnlyDictionary{System.Int32,System.ValueTuple{Lada.Framework.Data.Domains.Categories.AgencyType,System.String}},System.Collections.Generic.IReadOnlyDictionary{System.Int32,System.String})">
            <summary>
            Đích đã tra từ DB cho luật mâu thuẫn phạm vi (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAudienceRules.CheckAudienceScope(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudienceModel},Lada.Framework.Data.Enums.InternalNewsAudienceScope,Ladaer.BackEnd.Infrastructures.Services.InternalNews.AudienceTargetFacts)"/>): loại + tên
            các đơn vị được chọn còn sống, và các người được chọn thuộc phía nhượng quyền (tên hiển thị).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.AudienceCheck">
            <summary>Kết quả kiểm các dòng đối tượng: <see cref="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.AudienceCheck.Forbidden"/> = vượt phạm vi đăng (HTTP 403).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.AudienceCheck.#ctor(System.String,System.Boolean)">
            <summary>Kết quả kiểm các dòng đối tượng: <see cref="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.AudienceCheck.Forbidden"/> = vượt phạm vi đăng (HTTP 403).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAudienceRules">
            <summary>
            Luật đối tượng lúc LƯU và lúc ĐĂNG (plan §3.11 mục 4) — hàm thuần: kiểm từng dòng, không tin giao diện đã ẩn ô.
            Nháp lưu trước, đăng sau, quyền có thể đổi giữa hai lúc nên nơi gọi chạy lại khi đăng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAudienceRules.Normalize(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudienceModel})">
            <summary>
            Chuẩn hoá: bỏ trùng, <c>All</c> không mang <c>TargetId</c>, <c>IncludeChildren</c> chỉ giữ cho <c>Agency</c>.
            Trả câu lỗi khi một dòng sai hình (loại lạ, thiếu đích).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAudienceRules.CheckScope(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudienceModel},Lada.Framework.Data.Enums.InternalNewsAudienceScope,Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope,System.Collections.Generic.IReadOnlyDictionary{System.Int32,System.Nullable{System.Int32}})">
            <summary>
            Phạm vi của người đăng với TỪNG dòng, rồi với phạm vi bài <paramref name="audienceScope"/> (mức đơn vị bị ép —
            §5 câu 12c). <paramref name="targetUserAgencyIds"/>: đơn vị của từng người được chọn đích danh (người không còn
            sống thì không có khoá).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAudienceRules.ForcedAudienceScope(System.Boolean,System.Collections.Generic.IEnumerable{System.Nullable{Lada.Framework.Data.Domains.Categories.AgencyType}})">
            <summary>
            Phạm vi bài bị ÉP cho người chỉ có mức đơn vị (§5 câu 12c), theo loại các đơn vị trong phạm vi đăng của họ: có cả
            đơn vị LADA lẫn bưu cục nhượng quyền (trưởng chi nhánh LADA có bưu cục NQ con) → được chọn (<c>null</c>); chỉ bưu
            cục NQ (chủ / trưởng bưu cục NQ) → <c>IncludeFranchise</c>, bài luôn đi trong bưu cục mình; chỉ LADA hoặc rỗng →
            <c>LadaOnly</c>. Mức công ty luôn được chọn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAudienceRules.CheckAudienceScope(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudienceModel},Lada.Framework.Data.Enums.InternalNewsAudienceScope,Ladaer.BackEnd.Infrastructures.Services.InternalNews.AudienceTargetFacts)">
            <summary>
            Luật mâu thuẫn phạm vi (§6.6): bài <c>LadaOnly</c> mà chọn đích chỉ có ở phía nhượng quyền — đơn vị nhượng quyền,
            người thuộc nhượng quyền, loại đơn vị "Mọi bưu cục nhượng quyền" — thì bộ lọc phạm vi loại hết người của đích đó:
            báo rõ thay vì lặng lẽ gửi cho 0 người. Chạy SAU <see cref="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAudienceRules.CheckScope(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudienceModel},Lada.Framework.Data.Enums.InternalNewsAudienceScope,Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope,System.Collections.Generic.IReadOnlyDictionary{System.Int32,System.Nullable{System.Int32}})"/> (403 trước — chống dò Id, §3.13).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAudienceRules.ToModels(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.InternalNews.InternalNewsAudience})">
            <summary>Dòng đối tượng (entity) → model, để luật lúc đăng đọc đúng thứ đã lưu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsAudienceRules.ToRows(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Models.InternalNews.InternalNewsAudienceModel},System.Int32)">
            <summary>Model → dòng chưa lưu, dùng cho đếm người nhận theo đối tượng đang chọn (chưa lưu bài).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsFileUpload">
            <summary>Một tệp đang tải lên — controller đóng gói từ <c>IFormFile</c>. <paramref name="Content"/> phải seek được.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsFileUpload.#ctor(System.IO.Stream,System.Int64,System.String,Lada.Framework.Data.Enums.InternalNewsFileKind,System.Int32,System.String)">
            <summary>Một tệp đang tải lên — controller đóng gói từ <c>IFormFile</c>. <paramref name="Content"/> phải seek được.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsFileService">
            <summary>
            Tài liệu / video của bài bảng tin (plan §3.5, chốt §6.5): ghi vào KHO MEDIA CHUNG
            (<c>Media.RootPath\Files\InternalNews\…</c>), URL trên <c>Media.Domain</c>. Chỉ người sửa được bài (tác giả, hoặc
            mức công ty) mới tải lên / xoá tệp của bài đó.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsFileService.UploadAsync(Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsFileUpload,Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsActor,System.Threading.CancellationToken)">
            <summary>Kiểm loại + magic bytes + kích thước, ghi đĩa RỒI MỚI ghi database; ghi database lỗi thì xoá tệp vừa ghi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsFileService.DeleteAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsActor)">
            <summary>
            Xoá file vật lý TRƯỚC rồi mới xoá dòng: kho này công khai theo URL tới khi cổng media Enforce — file nằm lại sau
            khi dòng đã xoá là rò. Từ chối khi tệp đang được khối nội dung dùng (bản đang sửa hoặc bản đã đăng).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsFileService.FindUsageAsync(Lada.Framework.Data.Domains.InternalNews.InternalNewsFile)">
            <summary>Câu từ chối khi tệp đang được khối dùng (bản đang sửa hoặc ảnh chụp người đọc đang thấy); <c>null</c> = xoá được.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsFileRules">
            <summary>
            Luật nhận tài liệu / video của bài bảng tin (plan §3.5): cùng whitelist, trần kích thước và phép nhận dạng bằng
            magic bytes của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalFileRules"/> — GỌI LẠI chứ không chép, để hai miền không lệch nhau khi
            một bên vá lỗi nhận dạng. Tài liệu 30 MB pdf/xlsx/docx, video 300 MB mp4/webm.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsFileRules.Detect(Lada.Framework.Data.Enums.InternalNewsFileKind,System.String,System.IO.Stream)">
            <summary>Phần mở rộng trong whitelist của loại VÀ nội dung đúng định dạng đó; vị trí đọc trả về đầu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStorageException">
            <summary>Lỗi kho tệp bảng tin — <see cref="P:System.Exception.Message"/> là câu tiếng Việt hiển thị được.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStoragePaths">
            <summary>
            Đường dẫn của tệp bảng tin trong KHO MEDIA CHUNG (chốt §6.5) — hàm thuần, có test chặn thoát thư mục.
            <c>StoragePath</c> lưu tương đối với <c>Media.RootPath</c> và LUÔN bắt đầu bằng <see cref="F:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStoragePaths.Prefix"/>; URL = media
            domain + đúng đường dẫn đó, như mọi ảnh khác của hệ thống (<c>ImageService.GetUrlBySystemPath</c>).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStoragePaths.Prefix">
            <summary>Tiền tố cố định dưới <c>Media.RootPath</c>. Cổng media (đợt riêng) phải coi nó là vùng riêng tư.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStoragePaths.NewStoragePath(System.DateTimeOffset,System.String)">
            <summary><c>Files/InternalNews/{yyyy}/{M}/{guid}.{ext}</c> — tên do máy chủ sinh, không lấy tên gốc.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStoragePaths.Resolve(System.String,System.String)">
            <summary>
            Đường dẫn tuyệt đối của một <c>StoragePath</c>, BẮT BUỘC nằm trong <c>{mediaRoot}\Files\InternalNews\</c>.
            Đường rỗng, tuyệt đối, có ổ đĩa, sai tiền tố hoặc thoát thư mục (<c>..</c>) → ném lỗi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStoragePaths.ToUrl(System.String,System.String)">
            <summary>URL tuyệt đối trên media domain; domain trống → chuỗi rỗng (không bịa host).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsFileStorage">
            <summary>Kho tài liệu / video bảng tin trên ổ đĩa, dưới <c>Media.RootPath</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsFileStorage.SaveAsync(System.IO.Stream,System.String,System.Threading.CancellationToken)">
            <summary>Ghi tệp mới (tên GUID); trả <c>StoragePath</c> tương đối + URL trên media domain. Ghi dở mà lỗi thì xoá tệp dở.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsFileStorage.DeleteAsync(System.String)">
            <summary>Xoá tệp vật lý. <c>false</c> = tệp không còn (không phải lỗi).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsFileStorage">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsHtmlSanitizer">
            <summary>
            Lọc HTML của khối Đoạn văn bản trong bài bảng tin (plan §3.5) — chạy LÚC LƯU khối và LÚC CHỤP ảnh đăng; SPA render
            ảnh chụp bằng <c>v-html</c> nên đây là lớp duy nhất đứng giữa chữ người soạn gõ và trình duyệt người đọc.
            </summary>
            <remarks>
            Cho phép đúng thẻ TinyMCE của bảng tin sinh ra (đoạn, tiêu đề phụ h2–h4, danh sách, đậm/nghiêng/gạch chân, bảng,
            trích dẫn, xuống dòng, link http/https). Cấm hẳn <c>img</c> (ảnh chỉ đi qua khối Ảnh / Bộ ảnh — TinyMCE bảng tin tắt
            nút chèn ảnh), <c>iframe</c> (video đi qua khối Video), <c>script</c>, thuộc tính <c>on*</c>, <c>style</c>,
            <c>class</c>, <c>data-*</c>, scheme <c>javascript:</c>. Link luôn mở tab mới kèm <c>rel="noopener noreferrer"</c>.
            Thẻ ngoài danh sách bị gỡ nhưng GIỮ chữ bên trong (dán từ Word ra &lt;span style&gt; không mất câu); thẻ chạy mã /
            nhúng bị bỏ cả ruột. Instance <see cref="T:Ganss.Xss.HtmlSanitizer"/> mới mỗi lượt (như <c>ContentHtmlSanitizer</c>) nên lớp bọc
            này đăng ký singleton được.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsHtmlSanitizer.Sanitize(System.String)">
            <summary>HTML đã lọc; đầu vào rỗng → chuỗi rỗng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsHtmlSanitizer.SanitizeBlockPayload(Lada.Framework.Data.Enums.ProductBlockType,System.String)">
            <summary>
            Payload khối ở dạng an toàn để lưu / chụp: khối Đoạn văn bản thay <c>html</c> bằng bản đã lọc; loại khác và
            payload không đọc được (validator sẽ báo lỗi) trả nguyên.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsHtmlSanitizer.TagsDroppedWithContent">
            <summary>Thẻ chạy mã / nhúng: bỏ cả nội dung, không "giữ con".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsNavPermissions">
            <summary>
            Role của Bảng tin nội bộ (plan §3.4) và cờ cho giao diện — hàm thuần theo rule <c>quyen-hien-thi</c>: endpoint
            <c>GET api/InternalNews/nav</c> không đòi role, Founder được cộng vào mọi cờ, mặc định <c>false</c>.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsNavPermissions.Manage">
            <summary>Soạn / đăng bài cho người trong đơn vị mình quản lý (trưởng bưu cục, trưởng phòng).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsNavPermissions.PublishAll">
            <summary>Soạn / đăng bài cho bất kỳ ai (Nhân sự, Ban giám đốc).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsNavPermissions.ViewStats">
            <summary>Xem ai đã đọc / đã xác nhận (GĐ D).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsNavPermissions.AdminRoles">
            <summary>Bó role gác MỌI action của <c>InternalNewsAdminController</c>, <c>InternalNewsFileController</c> và ảnh bảng tin.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsNavPermissions.CanManage(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <summary>Có cửa vào màn quản trị bảng tin (đúng bó <see cref="F:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsNavPermissions.AdminRoles"/>, cộng Founder).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsNavPermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String},System.Collections.Generic.IEnumerable{System.Int32})">
            <summary>
            Cờ của người đang đăng nhập. <paramref name="manageableAgencyIds"/> là cây đơn vị người đó được đăng (chỉ có
            nghĩa khi <c>CanManage</c> mà không <c>CanPublishAll</c>) — giao diện dựng ô chọn đơn vị theo đây.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsPostVersion">
            <summary>
            Phiên bản của bài mà người thao tác đã ĐỌC: trạng thái + <c>UpdatedTime</c>. Mọi lần ghi của store, và mọi lần lưu
            thông tin / khối, đều đổi <c>UpdatedTime</c> — nên điều kiện theo cặp này loại được cả "đọc cũ" (job chạy chồng, bấm
            đúp Đăng lại, hai tab) chứ không chỉ "khác trạng thái".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsPostVersion.#ctor(Lada.Framework.Data.Enums.InternalNewsStatus,System.Nullable{System.DateTimeOffset})">
            <summary>
            Phiên bản của bài mà người thao tác đã ĐỌC: trạng thái + <c>UpdatedTime</c>. Mọi lần ghi của store, và mọi lần lưu
            thông tin / khối, đều đổi <c>UpdatedTime</c> — nên điều kiện theo cặp này loại được cả "đọc cũ" (job chạy chồng, bấm
            đúp Đăng lại, hai tab) chứ không chỉ "khác trạng thái".
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsPublishWrite">
            <summary>Ảnh chụp sắp ghi lúc đăng.</summary>
            <param name="FirstPublish">Lần đầu (ghi <c>PublishedAt/By</c>); ngược lại là Đăng lại (ghi <c>RepublishedAt</c>).</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsPublishWrite.#ctor(System.String,System.String,System.DateTimeOffset,System.Int32,System.String,System.Boolean)">
            <summary>Ảnh chụp sắp ghi lúc đăng.</summary>
            <param name="FirstPublish">Lần đầu (ghi <c>PublishedAt/By</c>); ngược lại là Đăng lại (ghi <c>RepublishedAt</c>).</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsPublishWrite.FirstPublish">
            <summary>Lần đầu (ghi <c>PublishedAt/By</c>); ngược lại là Đăng lại (ghi <c>RepublishedAt</c>).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsPostStore">
            <summary>
            Ghi các cột trạng thái / xuất bản của bài bằng MỘT lệnh <c>UPDATE … WHERE Id = @id AND Status = @s AND UpdatedTime = @t</c>
            (plan §3.7): hai lần chạy chồng của job đăng theo lịch, job và người bấm tay, hay hai lần bấm đúp — chỉ một bên ghi
            được, bên kia nhận <c>false</c> và KHÔNG gửi chuông. Các cột này <c>UpdateAsync</c> không ghi được
            (<c>InternalNewsPostMap.StateColumns</c>). Lượt đọc cũng ghi ở đây cho nguyên tử. Tách store để service test được
            bằng repo giả (<c>ExecuteUpdateAsync</c> chỉ chạy trên EF thật), như <c>TopicPublishStore</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsPostStore.TryUnpublishAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsPostVersion,System.DateTimeOffset,System.Int32,System.String)">
            <summary>Về Nháp: xoá ảnh chụp, bỏ lịch; GIỮ <c>PublishedAt</c> (đăng lại sau thu hồi không gửi chuông lần nữa).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsPostStore.TryArchiveAsync(System.Int32,Lada.Framework.Data.Enums.InternalNewsStatus,System.DateTimeOffset,System.Int32,System.String)">
            <summary>Lưu trữ — chỉ theo trạng thái (job hết hạn đọc danh sách Id; lưu trữ không gửi chuông nên không sợ đọc cũ).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsPostStore.MarkReadAsync(System.Int32,System.Int32,System.String,System.Boolean,System.DateTimeOffset)">
            <summary>
            Ghi lượt đọc: lần đầu chèn, lần sau chỉ đổi <c>LastReadAt</c>; <paramref name="acknowledge"/> đặt
            <c>AcknowledgedAt</c> một lần và KHÔNG lần ghi nào xoá nó (hai tab đọc + xác nhận cùng lúc không mất xác nhận).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsService">
            <summary>
            Người đọc Bảng tin nội bộ (plan §3.3, §3.8): feed, chi tiết, đánh dấu đã đọc, xác nhận "Tôi đã đọc và hiểu", số
            bài chưa đọc, cờ điều hướng. MỌI đường đọc đi qua đúng một lớp lọc — <see cref="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver"/>
            — và bài không được xem trả 404 (không lộ tồn tại, plan §3.11 mục 1).
            </summary>
            <remarks>
            Người đọc chỉ thấy bài Đã đăng (chưa quá <c>ExpiresAt</c>) và — khi lọc "Đã lưu trữ" — bài Đã lưu trữ; nội dung
            luôn là ảnh chụp lúc đăng, không bao giờ là bản đang sửa.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsService.FeedAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Feed theo <see cref="T:Lada.Framework.DTO.SmartTable.SmartTableParam"/>: bộ lọc <c>kind</c> (số), <c>unread</c> (true), <c>archived</c> (true),
            <c>keyword</c> (tìm tiêu đề) trong <c>Search.PredicateObject</c>. Bài đang ghim lên đầu, rồi mới đăng trước.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsService.Visible(Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext,System.Boolean,System.DateTimeOffset)">
            <summary>Bài người xem được thấy — cùng một biểu thức cho feed lẫn đếm chưa đọc.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsService.LoadVisibleAsync(System.Int32,System.Int32)">
            <summary>Bài đã đăng / đã lưu trữ mà người này được xem; ngược lại <c>null</c> (nơi gọi trả 404).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsService.UpsertReadAsync(System.Int32,System.Int32,System.String,System.Boolean)">
            <summary>Mỗi người một dòng mỗi bài — ghi nguyên tử ở store (hai tab cùng ghi không mất xác nhận).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStatsOutcome`1">
            <summary>Giá trị hoặc lời từ chối (404 / 403 / 400) của một lời gọi thống kê.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStatsOutcome`1.#ctor(`0,Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsResult)">
            <summary>Giá trị hoặc lời từ chối (404 / 403 / 400) của một lời gọi thống kê.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStatsFile">
            <summary>Tệp .xlsx trả thẳng cho trình duyệt — KHÔNG lưu vào kho media (site công khai theo URL).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStatsFile.#ctor(System.Byte[],System.String,System.Int32)">
            <summary>Tệp .xlsx trả thẳng cho trình duyệt — KHÔNG lưu vào kho media (site công khai theo URL).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStatsPeopleQuery">
            <summary>Bộ lọc danh sách người: <c>status</c> = unread (mặc định) | unacknowledged | all; <c>agencyId</c> 0 = "Không thuộc đơn vị".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStatsPeopleQuery.#ctor(System.String,System.Nullable{System.Int32},System.String,System.Int32,System.Int32)">
            <summary>Bộ lọc danh sách người: <c>status</c> = unread (mặc định) | unacknowledged | all; <c>agencyId</c> 0 = "Không thuộc đơn vị".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsStatsService">
            <summary>
            Thống kê đọc của Bảng tin nội bộ (plan §3.17, GĐ D): ai trong đối tượng hiện tại đã đọc / đã xác nhận, theo đơn vị,
            danh sách người chưa đọc, xuất Excel. Chỉ người có <c>InternalNews.ViewStats</c> (Founder cộng vào) — kiểm ở đây
            lần nữa dù controller đã gác role, để mọi đường gọi service đều qua cùng hàng rào.
            </summary>
            <remarks>
            Người nhắm KHÔNG có luật thứ hai: <see cref="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IInternalNewsAdminService.ResolveRecipientsAsync(Lada.Framework.Data.Enums.InternalNewsAudienceScope,System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.InternalNews.InternalNewsAudience})"/> — cùng nguồn với chuông
            và "ước tính người nhận" (bỏ tài khoản xoá / đang khoá). <c>ViewStats</c> là quyền mức công ty: xem mọi bài đã từng
            đăng (<c>PublishedAt</c> có giá trị — gồm bài đã thu hồi về nháp); bài chưa đăng lần nào / không tồn tại → 404.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStatsService.LoadAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsActor)">
            <summary>Ảnh chụp người nhắm + lượt đọc của một bài — hàng rào quyền và 404 nằm ở đây, một chỗ cho cả 3 lời gọi.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStatsCalculator">
            <summary>Phần tính thuần của thống kê đọc — nhóm theo đơn vị, xếp, lọc danh sách người (test không cần DB).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStatsCalculator.ByAgency(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsStatsPersonItem})">
            <summary>Theo đơn vị đang làm: nhiều người chưa đọc lên trước (người cần nhắc), cùng số thì theo tên; "Không thuộc đơn vị" cuối.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStatsCalculator.SortPeople(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsStatsPersonItem})">
            <summary>Đơn vị (không đơn vị cuối) rồi họ tên — cùng thứ tự cho màn và tệp Excel.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStatsCalculator.Filter(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.InternalNews.InternalNewsStatsPersonItem},System.String,System.Nullable{System.Int32},System.String)">
            <param name="agencyId"><c>null</c> = mọi đơn vị; <c>0</c> = chỉ người "Không thuộc đơn vị".</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsStatsExcelBuilder">
            <summary>
            Tệp Excel của nút "Xuất Excel" ở dialog Thống kê. Hàm thuần, trả byte; mọi ô ghi dạng giá trị (không công thức) nên
            họ tên bắt đầu bằng <c>=</c> không thành công thức. Chỉ người nhắm của bài — người đọc ngoài đối tượng chỉ là con số.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext">
            <summary>
            Người đang xem bảng tin — dựng MỘT lần mỗi request bằng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IViewerContextBuilder"/> (plan §3.3).
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext.AgencyId"/> chỉ có khi đơn vị của người đó còn sống: người thiếu <c>AgencyId</c> hoặc có bưu cục đã xoá
            mềm (Việc 0 §4.0 dòng 2, 5) chỉ khớp được dòng Tất cả / Nhóm quyền / Cá nhân.
            </summary>
            <param name="AgencyAncestorIds">Tổ tiên của <see cref="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext.AgencyId"/> (không gồm chính nó), tối đa 10 cấp.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext.#ctor(System.Int32,System.Boolean,Lada.Framework.Data.Enums.UserType,System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{Lada.Framework.Data.Domains.Categories.AgencyType},System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>
            Người đang xem bảng tin — dựng MỘT lần mỗi request bằng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IViewerContextBuilder"/> (plan §3.3).
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext.AgencyId"/> chỉ có khi đơn vị của người đó còn sống: người thiếu <c>AgencyId</c> hoặc có bưu cục đã xoá
            mềm (Việc 0 §4.0 dòng 2, 5) chỉ khớp được dòng Tất cả / Nhóm quyền / Cá nhân.
            </summary>
            <param name="AgencyAncestorIds">Tổ tiên của <see cref="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext.AgencyId"/> (không gồm chính nó), tối đa 10 cấp.</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext.AgencyAncestorIds">
            <summary>Tổ tiên của <see cref="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext.AgencyId"/> (không gồm chính nó), tối đa 10 cấp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext.IsLada">
            <summary>
            Thuộc LADA theo ĐƠN VỊ (plan §6.6): nhân viên ở đơn vị LADA còn sống hoặc không có đơn vị sống. Người làm ở bưu
            cục nhượng quyền còn sống (tài khoản Nhân viên, BT-10) thì không; tài khoản <c>Franchisee</c> không bao giờ, kể cả
            khi mất đơn vị. Nhân viên có bưu cục NQ đã XOÁ MỀM thì coi như không đơn vị → tính là LADA (plan §3.15 mục 2 —
            đóng bưu cục mà không khoá tài khoản là việc của quản trị).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.AgencyTree">
            <summary>
            Cây <c>Agency</c> còn sống, nạp một lần mỗi request (13 đơn vị trên dev — Việc 0 §4.0 dòng 3). Duyệt giới hạn
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.InternalNews.AgencyTree.MaxDepth"/> cấp và chống vòng: dữ liệu cha–con sai không được làm treo request.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.AgencyTree.AncestorsOf(System.Int32)">
            <summary>Tổ tiên còn sống của <paramref name="agencyId"/>, gần trước xa sau; không gồm chính nó.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.AgencyTree.WithDescendants(System.Collections.Generic.IEnumerable{System.Int32})">
            <summary>Các gốc còn sống cùng mọi con cháu còn sống của chúng (tối đa <see cref="F:Ladaer.BackEnd.Infrastructures.Services.InternalNews.AgencyTree.MaxDepth"/> cấp dưới gốc).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver">
            <summary>
            Luật "ai thấy bài nào" của Bảng tin nội bộ — ĐÚNG MỘT CHỖ (plan §3.3, §6.6). Viết thành biểu thức để cùng một luật
            chạy được cả trong SQL (feed, đếm chưa đọc: <see cref="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver.WhereVisible(System.Linq.IQueryable{Lada.Framework.Data.Domains.InternalNews.InternalNewsPost},System.Linq.IQueryable{Lada.Framework.Data.Domains.InternalNews.InternalNewsAudience},Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext)"/>) lẫn trong bộ nhớ (chi tiết, đánh dấu đọc,
            xác nhận, người nhận chuông, ước tính người nhận: <see cref="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver.CanView(Lada.Framework.Data.Enums.InternalNewsAudienceScope,System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.InternalNews.InternalNewsAudience},Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext)"/> / <see cref="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver.MatchesAny(Lada.Framework.Data.Enums.InternalNewsAudienceScope,System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.InternalNews.InternalNewsAudience},Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext)"/>) — không chép
            luật lần hai (bài học <c>KpiVisibilityResolver</c>).
            </summary>
            <remarks>
            Hai vế, cùng phải đúng (plan §6.6, thay §3.13 mục 1): khớp MỘT dòng đối tượng VÀ phạm vi bài cho qua
            (<c>IncludeFranchise</c>, hoặc người xem thuộc LADA theo đơn vị). "Tất cả" = mọi người nội bộ (Staff + Franchisee),
            phạm vi quyết LADA hay gồm nhượng quyền; bài <c>LadaOnly</c> loại người phía nhượng quyền kể cả khi họ khớp theo nhóm
            quyền (§5 câu 12b). Khách hàng (<c>UserType.Customer</c>) không bao giờ thấy bài nào. Founder thấy mọi bài đã đăng
            nhưng KHÔNG tự vào danh sách nhận chuông (chuông chỉ theo đúng đối tượng của bài).
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver.ViewerKeys">
            <summary>
            Khoá so khớp của người xem, đã quy giá trị thiếu về -1: không id nào bằng -1, và tránh ngữ nghĩa so NULL
            của SQL. Kiểu <c>int?</c> để so thẳng với <c>TargetId</c> (nullable) trong cả SQL lẫn bộ nhớ.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver.RowRule">
            <summary>
            LUẬT DÒNG — viết đúng một lần. Hai tham số để biên dịch MỘT lần cho fan-out, và gắn hằng người xem cho EF.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver.ScopeRule">
            <summary>
            LUẬT PHẠM VI (§6.6) — không phụ thuộc dòng nên tách khỏi <see cref="F:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver.RowRule"/> (trong SQL nó lọc trên bài), nhưng
            chỉ được dùng KÈM luật dòng, qua <see cref="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver.WhereVisible(System.Linq.IQueryable{Lada.Framework.Data.Domains.InternalNews.InternalNewsPost},System.Linq.IQueryable{Lada.Framework.Data.Domains.InternalNews.InternalNewsAudience},Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext)"/> / <see cref="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver.MatchesAny(Lada.Framework.Data.Enums.InternalNewsAudienceScope,System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.InternalNews.InternalNewsAudience},Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext)"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver.IsLadaAgency(System.Nullable{Lada.Framework.Data.Domains.Categories.AgencyType})">
            <summary>
            Đơn vị (còn sống) loại này là của LADA; <c>null</c> = không đơn vị → tính là LADA (§6.6). Danh sách đóng: loại
            đơn vị mới thêm sau này mặc định KHÔNG phải LADA — bài <c>LadaOnly</c> không lọt sang đó khi chưa ai quyết.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver.WhereVisible(System.Linq.IQueryable{Lada.Framework.Data.Domains.InternalNews.InternalNewsPost},System.Linq.IQueryable{Lada.Framework.Data.Domains.InternalNews.InternalNewsAudience},Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext)">
            <summary>
            Bài người xem được thấy — lối SQL DUY NHẤT (feed, đếm chưa đọc): luật phạm vi lọc trên bài, luật dòng lọc qua
            truy vấn con trên <paramref name="audiences"/>. Founder thấy mọi bài của <paramref name="posts"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver.MatchesAny(Lada.Framework.Data.Enums.InternalNewsAudienceScope,System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.InternalNews.InternalNewsAudience},Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext)">
            <summary>
            Phạm vi cho qua VÀ có ít nhất một dòng đối tượng khớp (KHÔNG xét Founder) — tập người nhận chuông / ước tính.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver.CanView(Lada.Framework.Data.Enums.InternalNewsAudienceScope,System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.InternalNews.InternalNewsAudience},Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext)">
            <summary>Người xem đọc được bài (phạm vi + các dòng đối tượng) không. Bài không có dòng nào = chỉ Founder thấy.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.InternalNews.InternalNewsVisibilityResolver.CreateViewer(System.Int32,System.Boolean,Lada.Framework.Data.Enums.UserType,System.Nullable{System.Int32},System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.InternalNews.AgencyTree)">
            <summary>Dựng người xem từ dữ liệu thô — đường duy nhất, dùng chung cho request đọc và cho fan-out chuông.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.IViewerContextBuilder">
            <summary>
            Dựng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.ViewerContext"/> (người đọc) và <see cref="T:Ladaer.BackEnd.Infrastructures.Services.InternalNews.PublisherScope"/> (người đăng) cho Bảng tin nội bộ —
            đọc <c>User</c> + role (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserRoleResolver"/>, role không nằm trong JWT) + cây <c>Agency</c> còn sống.
            Nơi DUY NHẤT dựng hai thứ này, để feed, chi tiết, đếm người nhận và kiểm phạm vi đăng đọc cùng một dữ liệu.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiActualProvider">
             <summary>
             Hợp đồng tính giá trị thực (actual) của một chỉ số KPI, bám đúng pattern
             <c>IWidgetDataProvider</c> của khung Dashboard Widget.
             </summary>
             <remarks>
             Đăng ký DI bằng <c>services.AddTransient&lt;IKpiActualProvider, XxxProvider&gt;()</c>;
             <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiEngineService"/> resolve theo <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiActualProvider.Code"/> = <c>KpiMetric.SourceCode</c>.
            
             Provider **không** tự kiểm tra quyền — lớp gọi (service progress, job chốt kỳ) đã ép phạm vi
             trước khi tới đây. Provider cũng **không** tự bắt exception thành 0: ném ra để engine đánh dấu
             dòng lỗi, vì một chỉ số im lặng trả 0 sẽ thành "không đạt chỉ tiêu" rồi thành mất tiền thưởng.
             </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiActualProvider.Code">
            <summary>
            Trùng <c>KpiMetric.SourceCode</c> — hằng khai ở <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiSourceCodes"/>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiActualProvider.AppliesTo">
            <summary>
            Loại chủ thể mà provider này phục vụ — engine chặn trước khi gọi nếu lệch
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiActualProvider.IsPointInTime">
            <summary>
            Chỉ số này là <b>ảnh chụp tại một thời điểm</b> hay là số <b>cộng dồn cả khoảng</b>.
            </summary>
            <remarks>
            <para>
            Mặc định <c>false</c> — hầu hết chỉ số là số cộng dồn (đếm đơn, cộng tiền): giá trị của
            một khoảng dài bằng tổng các khoảng con, và chỉ tiêu quý bằng Σ chỉ tiêu các tháng.
            </para>
            <para>
            <c>true</c> cho chỉ số kiểu <c>sales.active-customers</c>: nó đếm khách hoạt động
            <b>tại mốc <c>ToDate</c></b> theo cửa sổ trượt 3 tháng (§7.4), nên chạy trên khoảng quý
            ra "khách hoạt động tại cuối quý" chứ không phải tổng ba tháng. Với chỉ số như vậy,
            <b>chỉ tiêu quý cũng KHÔNG được cộng dồn</b> — giao 50 khách mỗi tháng thì mục tiêu quý
            vẫn là 50, không phải 150. Cộng dồn ở vế chỉ tiêu trong khi vế giá trị thực là ảnh chụp
            làm điểm quý chỉ còn khoảng 1/3 điểm thật, điểm năm còn 1/12 — sai một cách hệ thống.
            </para>
            <para>
            Đặt ở đây chứ không phải một danh sách mã cứng trong lớp tổng hợp: bản chất "ảnh chụp hay
            cộng dồn" là của chính cách provider tính, nên nó phải nằm cạnh phép tính đó.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiActualProvider.IsRatio">
            <summary>
            Chỉ số này là <b>tỷ lệ / bình quân</b> (tử số ÷ mẫu số) hay là số đếm/cộng thẳng.
            </summary>
            <remarks>
            <para>
            Mặc định <c>false</c>. <c>true</c> cho chỉ số kiểu <c>driver.delivery-rate</c> (đơn giao
            thành công ÷ đơn được giao) hay "đơn ÷ lái xe": <b>không được cộng thẳng giá trị các
            tháng</b>, cũng không lấy trung bình % — 200% trên mẫu số 10 cộng 50% trên mẫu số 1.000
            không ra 125%. Tổng hợp quý/năm (§7.13) cộng <b>tử số và mẫu số đã đóng dấu</b> rồi chia.
            </para>
            <para>
            Provider khai <c>true</c> thì <b>bắt buộc</b> điền <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualResult.Numerator"/>
            và <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualResult.Denominator"/> — lúc chốt tháng chúng được đóng dấu vào
            <c>KpiResult</c>; thiếu thì lớp tổng hợp ghi rõ "thiếu tử/mẫu tháng X", không đoán, không
            coi là 0.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiActualProvider.GetActualAsync(Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualContext)">
            <summary>
            Tính giá trị thực của chỉ số trong khoảng ngày của ngữ cảnh
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualContext">
            <summary>
            Ngữ cảnh tính giá trị thực.
            </summary>
            <remarks>
            Nhận **khoảng ngày** chứ không phải cặp năm/tháng (plan §3.4): kỳ tháng và màn theo dõi
            trong kỳ dùng khoảng ngày tuỳ ý. Tổng hợp quý/năm thì **không** gọi provider nữa (§7.13) —
            nó cộng từ snapshot <c>KpiResult</c> của các tháng đã chốt.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualContext.SubjectKind">
            <summary>Loại chủ thể: nhân viên hay đơn vị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualContext.SubjectId">
            <summary>Id chủ thể — UserId khi Employee, AgencyId khi Agency</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualContext.FromDate">
            <summary>Đầu khoảng, tính cả mốc này</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualContext.ToDate">
            <summary>Cuối khoảng, tính cả mốc này (thường là cuối ngày)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualContext.ChildAgencyIds">
             <summary>
             Danh sách **đầy đủ** đơn vị phải gộp số khi chủ thể là đơn vị — **gồm cả chính chủ thể**.
             </summary>
             <remarks>
             Để trống là trường hợp thường gặp: provider <c>agency.*</c> tự hỏi
             <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAgencyScopeResolver"/> (khu vực gộp con đệ quy, loại khác chỉ tính chính nó).
            
             Chỉ điền khi bên gọi thật sự muốn đè phạm vi, và khi đó **phải điền cả id của chính chủ thể** —
             điền thiếu là lặng lẽ bỏ rơi doanh số ghi thẳng vào node khu vực.
             </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualContext.ForMonth(Lada.Framework.Data.Enums.KpiSubjectKind,System.Int32,System.Int32,System.Int32)">
            <summary>
            Tạo ngữ cảnh cho một kỳ tháng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualResult">
            <summary>
            Giá trị thực của một chỉ số kèm dữ liệu đối soát.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualResult.Value">
            <summary>Giá trị thực đạt được trong khoảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualResult.DetailJson">
            <summary>
            Breakdown để đối soát về sau — nguồn dữ liệu, khoảng ngày thật đã dùng, số thành phần.
            Ghi vào <c>KpiResult.DetailJson</c> lúc chốt kỳ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualResult.Numerator">
            <summary>
            Tử số của chỉ số dạng tỷ lệ (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiActualProvider.IsRatio"/>); null với chỉ số
            đếm/cộng thẳng. Đóng dấu vào <c>KpiResult.Numerator</c> lúc chốt tháng để tổng hợp quý/năm
            cộng tử–mẫu thay vì cộng %.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualResult.Denominator">
            <summary>Mẫu số của chỉ số dạng tỷ lệ; xem <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualResult.Numerator"/></summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualResult.FromRatio(System.Decimal,System.Decimal,System.String)">
            <summary>
            Kết quả của chỉ số dạng tỷ lệ: giá trị = tử ÷ mẫu (mẫu 0 ⇒ 0), kèm tử/mẫu để đóng dấu
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAgencyScopeResolver">
            <summary>
            Phân giải một chủ thể đơn vị thành danh sách đơn vị phải gộp số khi tính KPI.
            </summary>
            <remarks>
            **Nguồn duy nhất của luật gộp cây** (plan §7.2) — mọi provider <c>agency.*</c> hỏi lớp này
            thay vì tự đệ quy <c>ParentId</c>, để luật "khu vực gộp con, loại khác chỉ tính chính nó"
            chỉ tồn tại ở một chỗ. Cùng tinh thần với <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiVisibilityResolver"/>.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAgencyScopeResolver.ResolveScopeAsync(System.Int32)">
            <summary>
            Danh sách <c>AgencyId</c> phải gộp cho một chủ thể đơn vị — **đã khử trùng lặp** và
            luôn chứa chính nó.
            </summary>
            <remarks>
            Ném <see cref="T:System.InvalidOperationException"/> khi không tìm thấy đơn vị: một chỉ số im lặng
            trả 0 sẽ thành "không đạt chỉ tiêu" rồi thành mất tiền thưởng (xem
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiActualProvider"/>), nên thà báo lỗi rõ ràng còn hơn trả tập rỗng.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAgencyScopeResolver">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAgencyScopeResolver" />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAggregationService">
            <summary>
            Tổng hợp KPI quý/năm (plan §7.1) — tầng đọc của con người, không sinh tiền.
            </summary>
            <remarks>
            <para>
            <b>Luật §7.13 (chốt 2026-08-15, thay §3.4 cũ): điểm quý/năm CỘNG TỪ SNAPSHOT
            <c>KpiResult</c> CỦA CÁC THÁNG ĐÃ CHỐT — tuyệt đối không chạy lại provider.</b> Hệ quả: điểm
            quý/năm luôn khớp với các con số tháng đã đóng dấu (thứ nghiệp vụ nhìn thấy trên phiếu lương)
            và bất biến khi dữ liệu gốc đổi sau khi tháng đã chốt (đơn huỷ, đơn sửa) — đúng tinh thần
            <c>KpiResult</c> là snapshot bất biến (nợ KPI-8, KPI-10).
            </para>
            <para><b>Cách "cộng" phụ thuộc bản chất chỉ số</b> — quyết định bằng thuộc tính của chính
            provider (<c>IsPointInTime</c>, <c>IsRatio</c>), không phải danh sách mã cứng:</para>
            <list type="bullet">
            <item><b>Cộng dồn</b> (số đơn, doanh số, onboard, khách mới): actual = Σ <c>ActualValue</c>,
            mục tiêu = Σ <c>TargetValue</c> <b>của đúng các tháng đã chốt đó</b> — target và actual cùng
            một tập tháng (bài học lỗi 2 GĐ D về lệch mẫu số).</item>
            <item><b>Ảnh chụp</b> (<c>sales.active-customers</c>): actual và mục tiêu đều của <b>tháng
            cuối cùng đã chốt trong kỳ</b>, không Σ (bài học lỗi 1 GĐ D).</item>
            <item><b>Tỷ lệ / bình quân</b>: không cộng thẳng <c>ActualValue</c> — cộng <b>tử số và mẫu số
            đã đóng dấu</b> rồi chia; mục tiêu = bình quân gia quyền theo mẫu số của mục tiêu các tháng
            (mục tiêu % cố định thì ra đúng chính nó). Tháng thiếu tử/mẫu (chốt trước khi có cột, hoặc
            nhập tay đè) ⇒ ghi rõ "thiếu tử/mẫu tháng X", <b>không đoán, không coi là 0</b>.</item>
            </list>
            <para>
            <b>Tháng chưa chốt</b> không góp số — bảng chỉ mang nhãn "còn N tháng chưa chốt"; muốn xem
            tháng đang chạy thì dùng màn theo dõi trong kỳ. <c>KpiPeriodicReviewService.Finalize</c> từ chối
            khi <c>UnclosedMonthCount &gt; 0</c> (đóng KPI-11). <c>ManualValue</c> tự nhiên được tôn trọng
            vì <c>KpiResult.ActualValue</c> đã là giá trị cuối (nhập tay thắng lúc chốt).
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAggregationService.AggregateAsync(Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAggregationQuery,System.Int32)">
            <summary>
            Tổng hợp điểm KPI quý/năm của một chủ thể. Trả <c>null</c> khi chủ thể nằm ngoài phạm vi
            xem của người gọi (§3.6) — không phân biệt với "không có dữ liệu", chống dò IDOR.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAggregationQuery">
            <summary>
            Tham số tổng hợp quý/năm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAggregationQuery.PeriodType">
            <summary>Quarter hoặc Year</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAggregationQuery.PeriodIndex">
            <summary>Quý 1-4 khi PeriodType = Quarter; bỏ qua khi PeriodType = Year</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAggregationService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAggregationService" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAggregationService.DetailNumeratorKey">
            <summary>
            Khoá tử/mẫu trong <c>DetailJson</c> cho tháng chốt trước khi có cột — provider dạng tỷ lệ
            ghi thêm hai khoá này vào breakdown để tổng hợp đọc lại được
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAggregationService.DetailDenominatorKey">
            <summary>Xem <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAggregationService.DetailNumeratorKey"/></summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAggregationService.Combine(Lada.Framework.Data.Domains.Kpi.KpiMetric,System.Collections.Generic.List{System.ValueTuple{Lada.Framework.Data.Domains.Kpi.KpiAssignment,Lada.Framework.Data.Domains.Kpi.KpiResult}},System.Boolean,System.Boolean,Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAggregationItem)">
            <summary>
            Gộp target/actual của các tháng ĐÃ CHỐT theo bản chất chỉ số (§7.13).
            </summary>
            <returns>
            <c>Actual</c> null nghĩa là chưa tính được — kèm <c>Note</c> nói rõ thiếu gì; không có nhánh
            nào trả 0 thay cho "không biết".
            </returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAggregationService.ReadRatioParts(Lada.Framework.Data.Domains.Kpi.KpiResult)">
            <summary>
            Tử/mẫu của một snapshot: ưu tiên cột đóng dấu; tháng chốt trước khi có cột thì đọc
            <c>DetailJson</c> theo khoá <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAggregationService.DetailNumeratorKey"/>/<see cref="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAggregationService.DetailDenominatorKey"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAggregationService.ResolveMonthRange(Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAggregationQuery)">
            <summary>
            Khoảng tháng của kỳ tổng hợp; trả (0, 0) khi tham số kỳ không hợp lệ
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAggregationService.IsVisibleAsync(Lada.Framework.Data.Enums.KpiSubjectKind,System.Int32,System.Int32)">
            <summary>
            Phạm vi XEM theo §3.6 — hỏi đúng lớp <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiVisibilityResolver"/>, không chép luật
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAssignmentService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tìm kiếm chỉ tiêu — không có Kpi.ViewAll/Founder thì server ép lọc về phạm vi
            của mình + cấp dưới trực tiếp + đơn vị mình quản lý (§3.6), không tin FE
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAssignmentService.GetById(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy chỉ tiêu theo Id — null nếu không tồn tại HOẶC ngoài phạm vi xem (không phân biệt, chống dò IDOR)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAssignmentService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Giao/sửa một dòng chỉ tiêu — luật phạm vi §7.3 + validation §3.9c;
            Draft lưu lẻ dòng được, response kèm cảnh báo tổng trọng số (§7.8)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAssignmentService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xoá mềm chỉ tiêu — cùng luật phạm vi với quyền giao (§7.3), chặn khi kỳ đã chốt
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAssignmentService.Assign(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentAssignModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Chuyển cả bộ chỉ tiêu của một chủ thể trong một kỳ sang Assigned —
            chặn cứng khi tổng trọng số ≠ 100%, báo rõ thiếu/thừa bao nhiêu (§7.8)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAssignmentService.CopyFromPreviousPeriod(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiAssignmentCopyModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Copy bộ chỉ tiêu của một chủ thể từ kỳ nguồn sang kỳ đích (Draft) —
            bỏ qua metric đã có ở kỳ đích và metric đã ngừng hoạt động
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAssignmentService.CheckManagementScopeAsync(Lada.Framework.Data.Enums.KpiSubjectKind,System.Int32,System.Int32)">
            <summary>
            Luật §7.3 — uỷ thác cho <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiManagementScopeResolver"/>, nguồn duy nhất của luật.
            </summary>
            <remarks>
            Từ GĐ D luật này còn phục vụ chốt lại kỳ, nhập tay giá trị và đánh giá quý/năm; giữ một
            bản chép riêng ở đây là con đường để bốn đường thao tác lệch nhau dần (§3.10).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAssignmentService.CheckSubjectActiveAsync(Lada.Framework.Data.Enums.KpiSubjectKind,System.Int32)">
            <summary>
            Chủ thể phải tồn tại và đang hoạt động (§3.9c): nhân viên là Staff chưa nghỉ,
            đơn vị ở trạng thái Hoạt động
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAssignmentService.FillDisplayNamesAsync(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiAssignmentItem})">
            <summary>
            Gán tên hiển thị cho SubjectName / AssignedByName — SubjectId đa hình nên không có navigation,
            tra tên theo trang kết quả (tối đa PageSize dòng)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAuditActions">
            <summary>
            Tên hành động ghi vào <c>KpiAuditLog.Action</c> — hằng để không có hai chỗ gõ khác nhau
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAuditService">
            <summary>
            Ghi dấu vết mọi thao tác đổi được tiền của phân hệ KPI (§3.10 — quyết định cách ghi là việc
            của GĐ E; chọn bảng riêng <c>KpiAuditLog</c>).
            </summary>
            <remarks>
            <b>Ghi log không bao giờ được làm hỏng nghiệp vụ</b>: hàm nuốt lỗi và chỉ <c>LogError</c>.
            Một dòng nhật ký không ghi được thì tiếc, nhưng để nó làm sập việc chốt kỳ của cả công ty thì
            tệ hơn hẳn. Ngược lại, thao tác nghiệp vụ phải ghi xong mới trả về Success — thứ tự gọi là
            "làm nghiệp vụ trước, ghi log sau, cùng một lượt request".
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAuditService.WriteAsync(System.String,System.String,System.String,System.Object,System.Object,Lada.Framework.Infrastructures.CurrentUser,System.String)">
            <summary>
            Ghi một dòng dấu vết. <paramref name="oldValue"/>/<paramref name="newValue"/> là object bất
            kỳ, được serialize sang JSON — <b>đừng truyền entity có navigation</b> (vòng tham chiếu).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiAuditService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAuditService" />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiBonusEngineService">
            <summary>
            Quy điểm KPI tháng đã chốt thành tiền thưởng trên phiếu lương (plan §3.5, §7.14).
            </summary>
            <remarks>
            <para>
            <b>Không sửa công thức trong <c>PayrollService</c></b> (§3.5): chỉ thêm bản ghi
            <c>PayrollAdjustment</c> loại thưởng, phiếu lương tự cộng qua <c>TotalBonuses</c> như mọi
            adjustment khác.
            </para>
            <para><b>Bốn chốt chặn phải CÙNG đúng mới sinh tiền</b>, thiếu một cái là không sinh gì và có
            lý do ghi rõ:</para>
            <list type="number">
            <item>Công tắc <c>Kpi.EnableBonus</c> bật (§5 GĐ E, mặc định TẮT).</item>
            <item>Kỳ chính thức — <c>KpiResult.IsTrial = false</c> (§7.9). Kỳ thử nghiệm không sinh gì
            <b>kể cả khi công tắc bật</b>.</item>
            <item>Nhân viên–tháng có dòng cấu hình <c>KpiBonusSetting</c> (§7.14).</item>
            <item>Mẫu bậc thang của dòng đó còn hiệu lực và có bậc phủ đúng điểm.</item>
            </list>
            <para>
            <b>Idempotent theo dòng cấu hình</b>: adjustment mang <c>KpiBonusSettingId</c>, chốt lại kỳ thì
            CẬP NHẬT dòng cũ chứ không sinh trùng (cùng nguyên tắc <c>KpiPeriodCloseService</c> áp cho
            <c>KpiResult</c> theo <c>AssignmentId</c>). Dòng cấu hình không còn đủ điều kiện mà đã sinh
            tiền lần trước ⇒ <b>gỡ</b> khoản đó, nếu không tiền của một lần chạy cũ ở lại mãi.
            </para>
            <para>
            <b>Bảng tính thử (dry-run) chạy được khi công tắc còn tắt</b> — đó là thứ chủ dự án dùng để
            duyệt số ở §5.1 bước 4, trước khi bật công tắc.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiBonusEngineService.PreviewAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusRunModel,System.Int32)">
            <summary>
            Bảng tính thử: hiện tiền <b>sẽ</b> sinh cho một kỳ, KHÔNG ghi gì xuống
            <c>PayrollAdjustment</c>. Chạy được cả khi công tắc tắt.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiBonusEngineService.GenerateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusRunModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Sinh/cập nhật <c>PayrollAdjustment</c> thật cho một kỳ — idempotent theo dòng cấu hình.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiBonusEngineService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiBonusEngineService" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiBonusEngineService.MoneyDecimals">
            <summary>Tiền làm tròn tới đồng — phiếu lương không có hào</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiBonusEngineService.DeletedSettingReason">
            <summary>Lý do của dòng cấu hình đã bị gỡ — dùng để lọc khỏi bảng tính thử</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiBonusEngineService.ComputeAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusRunModel,System.Boolean,System.Int32,System.Boolean)">
            <summary>
            Tính từng dòng cấu hình của kỳ ra tiền hoặc lý do không có tiền — dùng chung cho cả bảng
            tính thử lẫn lần sinh thật, để hai bên không bao giờ lệch nhau một đồng nào.
            </summary>
            <param name="enforceVisibility">
            Bảng tính thử lọc theo phạm vi xem của người mở màn hình (§3.6). Lần sinh thật thì KHÔNG —
            nó chạy cho cả kỳ, và ai gọi được nó đã qua role riêng.
            </param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiBonusEngineService.SubjectScore.IsTrial">
            <summary>Kỳ thử nghiệm nếu BẤT KỲ dòng nào của chủ thể mang cờ đó — fail-closed</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiBonusEngineService.LoadScoresAsync(System.Collections.Generic.List{Lada.Framework.Data.Domains.Kpi.KpiBonusSetting},System.Int32,System.Int32)">
            <summary>
            Điểm tháng của các chủ thể nguồn điểm = Σ <c>WeightedScore</c> các <c>KpiResult</c> ĐÃ CHỐT.
            </summary>
            <remarks>
            Đọc snapshot, <b>không gọi provider</b> — cùng nguyên tắc §7.13 và nợ KPI-8: tiền phải khớp
            với con số đã đóng dấu mà nghiệp vụ nhìn thấy, không phải với dữ liệu gốc lúc chạy.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiBonusEngineService.BuildReason(Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusPreviewItem,Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusRunModel)">
            <summary>
            Diễn giải trên phiếu lương — người nhận phải đọc là hiểu tiền ở đâu ra, không cần mở phần mềm
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiBonusPolicyService">
            <summary>
            CRUD mẫu bậc thang thưởng KPI (§7.5, §7.14) — mẫu dùng chung, KHÔNG nói ai được bao nhiêu tiền.
            </summary>
            <remarks>
            <para>
            <b>Luật quan trọng nhất: các bậc phải liên tục, không chồng, không hở.</b> Một điểm rơi vào hai
            bậc là hai số tiền khác nhau tuỳ thứ tự duyệt — và vì đây là đường sinh tiền, "tuỳ thứ tự
            duyệt" nghĩa là số tiền đổi khi ai đó thêm một bậc mới. Khoảng là nửa mở <c>[Min, Max)</c> nên
            bậc sau bắt đầu đúng tại <c>Max</c> của bậc trước.
            </para>
            <para>
            Cả hai ví dụ bậc thang sẵn có trong repo (<c>SalesCommissionTier</c>, <c>DriverSalaryScale</c>)
            <b>không</b> validate chồng khoảng — đây là khoảng trống có sẵn, đừng chép lại nó.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiBonusPolicyService.GetActiveAsync">
            <summary>Danh sách mẫu đang hiệu lực — cho ô chọn mẫu ở màn cấu hình nhân viên–tháng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiBonusPolicyService.ResolveTier(Lada.Framework.Data.Domains.Kpi.KpiBonusPolicy,System.Decimal)">
            <summary>
            Bậc trúng với một điểm; null khi không bậc nào phủ điểm đó (không suy diễn, không lấy bậc gần nhất)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiBonusPolicyService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiBonusPolicyService" />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiBonusPolicyService.ValidateInput(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusPolicyModel)">
            <summary>
            Validate mẫu và bộ bậc.
            </summary>
            <remarks>
            Ba luật, mỗi luật chặn một cách làm sai số tiền:
            <list type="number">
            <item><b>Không chồng khoảng</b> — một điểm hai số tiền.</item>
            <item><b>Không hở khoảng</b> — điểm rơi vào khe thì người ta không được đồng nào mà chẳng
            có thông báo nào nói vì sao.</item>
            <item><b>Đúng loại giá trị theo <c>Mode</c></b> — mẫu kiểu hệ số mà bậc chỉ điền số tiền
            thì tính ra 0 đồng, im lặng.</item>
            </list>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiBonusPolicyService.Snapshot(Lada.Framework.Data.Domains.Kpi.KpiBonusPolicy)">
            <summary>Ảnh chụp phẳng cho nhật ký — không mang navigation để tránh vòng tham chiếu</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiBonusSettingService">
            <summary>
            Dòng cấu hình thưởng theo từng nhân viên–tháng (§7.14) — nơi tiền thật sự được định.
            </summary>
            <remarks>
            <para>
            <b>Không có dòng ⇒ không sinh tiền</b> cho người đó tháng đó, kể cả khi công tắc bật. Đây là
            chốt chặn thứ tư bên cạnh công tắc, cờ <c>IsTrial</c> và hiệu lực của mẫu.
            </para>
            <para>
            <b>Ai định được tiền</b>: role <c>KpiBonusPolicy.CreateOrUpdate</c> — Nhân sự, Tài chính, BGĐ
            (§7.5, §7.14 ii). Người quản lý trực tiếp giao chỉ tiêu nhưng không tự định tiền cho cấp dưới.
            Phạm vi kiểm thêm ở service: chỉ cấu hình được cho <b>người mình nhìn thấy KPI</b>
            (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiVisibilityResolver"/> §3.6) — HR/Tài chính có <c>Kpi.ViewAll</c> nên phủ cả
            công ty, còn một quản lý được cấp nhầm role thưởng thì vẫn chỉ chạm được người của mình.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiBonusSettingService.BulkAssign(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusSettingBulkModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Gán hàng loạt cho một kỳ — sao chép tháng trước và/hoặc nhận thẳng danh sách. Idempotent:
            chạy lại không nhân đôi, mặc định không đè dòng đã có (§7.14).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiBonusSettingService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiBonusSettingService" />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiBonusSettingService.BuildAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiBonusSettingModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Dựng entity từ model kèm toàn bộ validate; trả <c>error</c> khác null là không ghi gì.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiBonusSettingService.CanTouchUserAsync(System.Int32,System.Int32)">
            <summary>
            Người cấu hình có được chạm tới nhân viên này không.
            </summary>
            <remarks>
            Hỏi lớp XEM (§3.6) chứ không phải lớp THAO TÁC chỉ tiêu (§7.3): người định tiền là
            HR/Tài chính/BGĐ — họ không phải quản lý trực tiếp của ai, nên áp §7.3 ở đây là khoá cứng
            chính những người §7.14 giao việc. Ngược lại, một quản lý bị cấp nhầm role thưởng vẫn chỉ
            chạm được người trong tầm nhìn của mình, không phải cả công ty.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiBonusSettingService.FillDisplayNamesAsync(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiBonusSettingItem})">
            <summary>Điền tên nhân viên và tên chủ thể nguồn điểm — hai truy vấn gộp, không N+1</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiEngineService">
            <summary>
            Engine KPI: phân giải provider theo <c>SourceCode</c> để lấy giá trị thực, và tính điểm từ
            giá trị thực so với chỉ tiêu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiEngineService.RegisteredSourceCodes">
            <summary>
            Mã nguồn dữ liệu của các provider đã đăng ký DI — dùng validate <c>KpiMetric.SourceCode</c>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiEngineService.IsSourceCodeRegistered(System.String)">
            <summary>
            Có provider nào phục vụ mã này không (không phân biệt hoa thường)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiEngineService.GetActualAsync(Lada.Framework.Data.Domains.Kpi.KpiMetric,Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualContext)">
            <summary>
            Lấy giá trị thực của một chỉ số cho một chủ thể trong một khoảng ngày.
            Ném <see cref="T:System.InvalidOperationException"/> nếu chỉ số cấu hình sai (không phải lỗi dữ liệu).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiEngineService.CalculateScore(Lada.Framework.Data.Domains.Kpi.KpiMetric,Lada.Framework.Data.Domains.Kpi.KpiAssignment,System.Decimal)">
            <summary>
            Tính % hoàn thành và điểm trọng số của một chỉ tiêu khi biết giá trị thực
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiEngineService.IsPointInTimeMetric(Lada.Framework.Data.Domains.Kpi.KpiMetric)">
            <summary>
            Chỉ số này là ảnh chụp tại một thời điểm (không cộng dồn được) hay là số cộng dồn cả
            khoảng — hỏi chính provider, xem <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiActualProvider.IsPointInTime"/>.
            </summary>
            <remarks>
            Chỉ số nhập tay hoặc chưa có provider đều trả <c>false</c>: giá trị nhập tay mang ngữ
            nghĩa của riêng tháng người ta nhập, nên cộng các tháng lại là đúng.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiEngineService.IsRatioMetric(Lada.Framework.Data.Domains.Kpi.KpiMetric)">
            <summary>
            Chỉ số này có phải dạng tỷ lệ/bình quân không — hỏi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiActualProvider.IsRatio"/>
            của provider thật; chỉ số nhập tay hoặc chưa có provider thì <c>false</c>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiScore">
            <summary>
            Kết quả chấm điểm một chỉ tiêu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiScore.CompletionPercent">
            <summary>% hoàn thành thô, chưa áp trần (đã làm tròn 2 chữ số)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiScore.CappedCompletionPercent">
            <summary>% hoàn thành sau khi áp trần <c>CapPercent</c> — đây là số dùng để tính điểm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiScore.WeightedScore">
            <summary>Điểm đã nhân trọng số: <c>Weight/100 × CappedCompletionPercent</c></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiScore.InvalidTargetReason">
            <summary>
            Lý do khi điểm bị chấm 0 vì dữ liệu chỉ tiêu không hợp lệ — null nếu chấm bình thường
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiEngineService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiEngineService" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiEngineService.ScoreDecimals">
            <summary>Số chữ số thập phân giữ lại ở mọi bước chấm điểm</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiEngineService.CalculateScore(Lada.Framework.Data.Domains.Kpi.KpiMetric,Lada.Framework.Data.Domains.Kpi.KpiAssignment,System.Decimal)">
             <summary>
             Chấm điểm một chỉ tiêu.
             </summary>
             <remarks>
             Công thức theo plan §3.1: điểm = trọng số × min(% hoàn thành, trần).
            
             Ba chốt an toàn, vì đây là đường dẫn tới tiền thưởng ở GĐ E:
             <list type="bullet">
             <item><b>Chỉ tiêu ≤ 0 thì chấm 0, không chia</b>. Validation §3.9c đã chặn từ đầu vào,
             nhưng dữ liệu cũ hoặc nhập tay vẫn lọt được. Chọn chấm 0 (fail closed) thay vì chấm đạt:
             một chỉ tiêu hỏng mà tự cho điểm tối đa là tiền tự sinh, còn chấm 0 thì người quản lý thấy
             ngay và sửa lại chỉ tiêu.</item>
             <item><b>% hoàn thành không bao giờ âm</b>. Chỉ số dạng tiền có thể ra giá trị thực âm
             (hoàn, điều chỉnh) — kẹp sàn về 0 để một chỉ tiêu âm không ăn mòn điểm các chỉ tiêu khác.</item>
             <item><b>Trần áp trước khi nhân trọng số</b>, đúng thứ tự của §3.1.</item>
             </list>
            
             Với chiều "càng thấp càng tốt", giá trị thực bằng 0 được coi là hoàn hảo và ăn trọn trần.
             Lưu ý cho GĐ D/E: nếu nguồn dữ liệu hỏng và trả về 0, chỉ số chiều này sẽ ăn điểm tối đa —
             job chốt kỳ phải đánh dấu dòng lỗi provider thay vì để nó lặng lẽ thành 0 (§3.9d).
             </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiManagementScopeResolver">
            <summary>
            Nguồn duy nhất của luật "ai được THAO TÁC chỉ tiêu của ai" (plan §7.3).
            </summary>
            <remarks>
            <para>
            Khác <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiVisibilityResolver"/> — lớp kia trả lời "ai XEM được KPI của ai" (§3.6).
            Hai tập không trùng nhau và cố ý tách: người có <c>Kpi.ViewAll</c> xem được cả công ty nhưng
            không vì thế mà giao/chốt được chỉ tiêu cho người ngoài phạm vi quản lý của mình.
            </para>
            <para>
            Tách ra thành lớp riêng ở GĐ D vì từ giai đoạn này có <b>ba</b> đường thao tác cùng dùng một
            luật: giao chỉ tiêu (GĐ A), chốt lại kỳ + nhập tay giá trị, và đánh giá quý/năm. §3.10 đã chỉ
            đích danh rủi ro "đường thứ hai chép lại luật rồi lệch dần" — và GĐ C đã cắn phải đúng lớp
            lỗi đó ở phía phân quyền đọc.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiManagementScopeResolver.CheckAsync(Lada.Framework.Data.Enums.KpiSubjectKind,System.Int32,System.Int32)">
            <summary>
            Kiểm người này có được thao tác chỉ tiêu của chủ thể đó không.
            Trả <c>null</c> nghĩa là được phép; trả chuỗi là thông báo lỗi tiếng Việt để hiển thị thẳng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiManagementScopeResolver.OutOfScopeMessage(Lada.Framework.Data.Enums.KpiSubjectKind)">
            <summary>
            Thông báo duy nhất cho mọi lý do "không thao tác được với chủ thể này" — dùng lại khi bên
            gọi muốn gộp ca "không tồn tại" vào cùng một câu trả lời (§3.10 chống dò).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiManagementScopeResolver.GetManageableSubjectsAsync(Lada.Framework.Data.Enums.KpiSubjectKind,System.Int32,System.String,System.Int32)">
            <summary>
            Liệt kê các chủ thể người này giao được chỉ tiêu — nguồn của ô chọn chủ thể ở màn giao
            chỉ tiêu (GĐ F).
            </summary>
            <remarks>
            <para>
            Cùng một luật với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiManagementScopeResolver.CheckAsync(Lada.Framework.Data.Enums.KpiSubjectKind,System.Int32,System.Int32)"/>, viết một lần ở đây thay vì để màn hình tự dựng
            danh sách bằng <c>User/Search</c>: màn KPI đi hỏi danh bạ nhân sự đúng là bẫy §8 mà GĐ C
            đã cắn phải. Bất biến phải giữ: mọi phần tử trả về đều phải làm
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiManagementScopeResolver.CheckAsync(Lada.Framework.Data.Enums.KpiSubjectKind,System.Int32,System.Int32)"/> trả <c>null</c> — không bao giờ rộng hơn.
            </para>
            <para>
            Chỗ duy nhất HẸP hơn <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiManagementScopeResolver.CheckAsync(Lada.Framework.Data.Enums.KpiSubjectKind,System.Int32,System.Int32)"/>: chỉ liệt kê người dùng
            <see cref="F:Lada.Framework.Data.Enums.UserType.Staff"/>. Chủ thể KPI cá nhân là nhân viên, còn bảng <c>User</c> ôm cả
            khách hàng — hẹp hơn thì an toàn, rộng hơn mới là lỗi.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiManagementScopeResolver">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiManagementScopeResolver" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiManagementScopeResolver.MaxSubjectOptions">
            <summary>Trần cứng số dòng trả về, chặn cả khi bên gọi truyền số lớn</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiManagementScopeResolver.CheckAsync(Lada.Framework.Data.Enums.KpiSubjectKind,System.Int32,System.Int32)">
            <summary>
            Luật §7.3: Employee → người thao tác phải là quản lý trực tiếp
            (<c>UserPreference.ManagerId</c>); Agency → phải là quản lý của node CHA trong cây Agency,
            node gốc chỉ Founder; Founder bypass; HR không có quyền mặc định (không nới ngầm).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiManagementScopeResolver.GetManageableSubjectsAsync(Lada.Framework.Data.Enums.KpiSubjectKind,System.Int32,System.String,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiManagementScopeResolver.OutOfScopeMessage(Lada.Framework.Data.Enums.KpiSubjectKind)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiMetricService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh mục chỉ số KPI
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiMetricService.GetById(System.Int32)">
            <summary>
            Lấy chỉ số theo Id — null nếu không tồn tại
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiMetricService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiMetricModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo hoặc cập nhật chỉ số — validate §3.9c: metric Auto phải có SourceCode hợp lệ,
            Code không trùng, không đổi Code/ApplicableTo khi đã có chỉ tiêu tham chiếu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiMetricService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xoá mềm chỉ số — chặn khi đã có chỉ tiêu tham chiếu (tắt IsActive thay vì xoá)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodCloseService">
            <summary>
            Chốt kỳ KPI: biến số đang trôi của kỳ thành snapshot bất biến trong <c>KpiResult</c> (plan §3.4).
            </summary>
            <remarks>
            <para>
            <b>Ba điều lớp này phải đúng, vì GĐ E sẽ nhân số ở đây ra tiền:</b>
            </para>
            <list type="number">
            <item><b>Không bao giờ quy lỗi về 0.</b> Nguồn dữ liệu hỏng hay chỉ số nhập tay chưa nhập thì
            dòng đó **không chốt**: không ghi <c>KpiResult</c>, không đổi trạng thái chỉ tiêu, ghi lý do vào
            tổng kết. Một dòng chốt với giá trị 0 đọc ra là "không đạt chỉ tiêu" và sẽ thành trừ tiền
            thưởng của người ta vì một stored procedure hỏng (§3.9d).</item>
            <item><b>Một dòng lỗi không làm hỏng kỳ của người khác.</b> Vòng lặp bắt lỗi từng dòng, không
            có đường nào cho một exception thoát ra làm sập cả lần chạy.</item>
            <item><b>Idempotent.</b> Chốt lại kỳ **cập nhật** <c>KpiResult</c> cũ theo <c>AssignmentId</c>,
            không sinh bản ghi trùng — cùng nguyên tắc mà GĐ E sẽ áp cho <c>PayrollAdjustment</c>.</item>
            </list>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodCloseService.CloseAllAsync(System.Int32,System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Chốt kỳ cho **toàn hệ thống** — đường của job Hangfire chạy mùng 1 hằng tháng.
            </summary>
            <remarks>
            Chỉ đụng chỉ tiêu đang ở trạng thái <c>Assigned</c>: bản nháp chưa giao thì chưa có gì để
            chốt, và kỳ đã chốt rồi thì chỉ đường chốt lại thủ công mới được sửa (§3.4).
            Không có assignment nào ⇒ no-op có log, không ném (§3.9d).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodCloseService.CloseSubjectAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodCloseModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Chốt (hoặc chốt lại) kỳ của **một chủ thể** — đường thủ công, kiểm phạm vi §7.3.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodCloseService.SaveManualValueAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiManualValueModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Nhập tay giá trị thực cho một chỉ tiêu trước khi chốt kỳ; job không ghi đè giá trị này
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodCloseService.GetRecloseWindowAsync(System.Int32,System.Int32,System.Nullable{Lada.Framework.Data.Enums.KpiSubjectKind},System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tình trạng cửa sổ chốt lại của một kỳ — để màn chốt kỳ nói được "còn N ngày" trước khi
            người dùng bấm, thay vì chỉ báo lỗi sau khi bấm.
            </summary>
            <remarks>
            Chỉ ĐỌC, không đổi gì. Truyền chủ thể thì trả thêm <c>IsClosed</c>, và phần đó chỉ được
            trả khi chủ thể nằm trong phạm vi §7.3 của người gọi — ngoài phạm vi thì để <c>null</c>
            chứ không báo lỗi khác đi, để endpoint không thành công cụ dò chủ thể (§3.10).
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriodCloseService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodCloseService" />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriodCloseService.CloseAssignmentsAsync(System.Collections.Generic.List{Lada.Framework.Data.Domains.Kpi.KpiAssignment},System.Int32,System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Vòng chốt dùng chung cho cả job lẫn đường thủ công.
            </summary>
            <remarks>
            Mỗi dòng là một giao dịch độc lập về mặt hậu quả: lỗi của dòng này không được chạm tới
            dòng khác. Vì vậy không gom <c>UpdateAsync</c> cả lô ở cuối — một lô có dòng hỏng thì
            hoặc mất hết hoặc ghi cả dòng hỏng, cả hai đều sai với §3.9d.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriodCloseService.RunBonusAsync(System.Int32,System.Int32,Lada.Framework.Infrastructures.CurrentUser,Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodCloseSummary,System.Nullable{Lada.Framework.Data.Enums.KpiSubjectKind},System.Int32)">
             <summary>
             Chạy engine thưởng sau khi chốt xong (plan §3.5).
             </summary>
             <remarks>
             Đặt sau vòng chốt và bọc try/catch: <b>tiền không được làm hỏng việc chốt kỳ</b>. Engine tự
             giữ bốn chốt chặn (công tắc, IsTrial, dòng cấu hình, mẫu còn hiệu lực) nên gọi vô điều kiện
             ở đây là an toàn — và cần thiết, vì chạy lại chính là đường CẬP NHẬT khoản đã sinh khi chốt
             lại kỳ. Không chốt được dòng nào thì không gọi.
            
             <b>Phạm vi phải khớp phạm vi của lệnh chốt</b>: chốt một chủ thể ⇒ chỉ chạy thưởng cho
             dòng cấu hình lấy điểm từ chủ thể đó; chỉ job hệ thống (<c>CloseAllAsync</c>) mới chạy cả kỳ.
             </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriodCloseService.ResolveActualAsync(Lada.Framework.Data.Domains.Kpi.KpiAssignment,Lada.Framework.Data.Domains.Kpi.KpiMetric,Lada.Framework.Data.Domains.Kpi.KpiResult,System.Int32,System.Int32)">
            <summary>
            Lấy giá trị thực để chốt: ưu tiên giá trị nhập tay, sau đó mới tới engine.
            </summary>
            <remarks>
            Trả về <c>error</c> khác null nghĩa là **không chốt dòng này**. Không có nhánh nào trả về
            giá trị 0 thay cho lỗi — đó là toàn bộ lý do hàm này tồn tại tách khỏi vòng lặp.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriodCloseService.BuildManualDetailJson(Lada.Framework.Data.Domains.Kpi.KpiResult,System.Int32,System.Int32)">
            <summary>
            Breakdown đối soát cho dòng nhập tay — dòng engine tính thì ghi nguyên văn DetailJson của
            provider, không chế lại (§3.4).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriodCloseService.BuildRecloseMessage(Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiRecloseWindowItem)">
            <summary>
            Một câu tiếng Việt duy nhất cho băng thông báo của màn chốt kỳ, đúng theo trạng thái.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodicReviewService">
            <summary>
            Bản đánh giá KPI định kỳ quý/năm của người quản lý (§7.1).
            </summary>
            <remarks>
            Quý để **điều chỉnh cho đúng hướng**, năm làm **cơ sở tăng lương, thăng chức** — cả hai là
            tầng đọc + kết luận của con người, KHÔNG tự sinh tiền. Điểm hiển thị là số sống do
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAggregationService"/> tính lại mỗi lần mở màn hình; chỉ lúc chuyển
            <c>Final</c> mới đóng dấu vào <c>AggregatedScore</c>.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodicReviewService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tìm kiếm bản đánh giá — ép phạm vi xem §3.6 server-side như mọi đường đọc KPI khác
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodicReviewService.GetById(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy một bản đánh giá kèm bảng tổng hợp điểm của kỳ — null nếu không tồn tại HOẶC ngoài
            phạm vi xem (không phân biệt, chống dò IDOR)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodicReviewService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodicReviewModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo/sửa bản đánh giá ở trạng thái Draft — luật phạm vi thao tác §7.3
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodicReviewService.Finalize(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodicReviewFinalizeModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Chuyển bản đánh giá sang Final và snapshot điểm tổng hợp tại thời điểm đó
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodicReviewService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xoá mềm bản đánh giá còn Draft — bản đã Final là căn cứ nhân sự, không xoá
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriodicReviewDetail">
            <summary>
            Bản đánh giá kèm bảng tổng hợp điểm của kỳ — thứ màn hình cần để người quản lý viết nhận xét.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriodicReviewDetail.Aggregation">
            <summary>
            Bảng tổng hợp SỐ SỐNG của kỳ; null khi không tính được. Bản đã Final vẫn hiện bảng này để
            đối chiếu, nhưng điểm chính thức là <c>Review.AggregatedScore</c> đã đóng dấu.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriodicReviewService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodicReviewService" />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriodicReviewService.Finalize(Ladaer.BackEnd.Infrastructures.DTO.Models.Kpi.KpiPeriodicReviewFinalizeModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Chốt bản đánh giá và snapshot điểm tổng hợp.
            </summary>
            <remarks>
            Điểm được TÍNH LẠI ngay tại đây rồi mới đóng dấu, không nhận số từ client: bản đánh giá
            năm là căn cứ tăng lương/thăng chức (§7.1), cho gửi điểm lên là mở đường sửa căn cứ đó
            bằng một request.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriodicReviewService.FillDisplayNamesAsync(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiPeriodicReviewItem})">
            <summary>
            Gán tên chủ thể và tên người đánh giá — SubjectId đa hình nên không có navigation property
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodLockService">
            <summary>
            Trả lời câu hỏi "kỳ này đã chốt chưa" cho các luồng NGHIỆP VỤ nằm ngoài phân hệ KPI mà lại
            đóng dấu mốc thời gian nuôi một chỉ số KPI.
            </summary>
            <remarks>
            <para>
            Sinh ra để trả nợ <c>KPI-7</c>. <c>Candidate.OnboardedTime</c> bị đóng dấu lại mỗi lần hồ sơ
            quay vòng trạng thái (Onboard → Rejected → Onboard), nên một hồ sơ đã đếm cho kỳ tháng 7 có
            thể bị xoá dấu rồi đóng dấu lại vào tháng 8 — tức **dịch công của kỳ cũ sang kỳ đang chạy**.
            </para>
            <para>
            §3.4 đã chốt: số của kỳ đã chốt là snapshot bất biến. Vậy nên mốc đang nằm trong một kỳ đã
            chốt thì **đóng băng**, không cho luồng nghiệp vụ xoá hay dời đi nữa. Trạng thái hồ sơ vẫn
            đổi được bình thường — chỉ riêng cái mốc là bất động.
            </para>
            <para>
            Cố ý là một interface hẹp chứ không phải cho <c>CandidateService</c> phụ thuộc thẳng vào
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodCloseService"/>: miền tuyển dụng chỉ cần biết một sự thật ("kỳ khoá chưa"),
            không cần và không nên với tới được đường chốt kỳ.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodLockService.IsOnboardPeriodClosedAsync(System.DateTimeOffset)">
            <summary>
            Kỳ chứa thời điểm này đã chốt cho các chỉ số đếm hồ sơ nhận việc chưa
            (<c>hr.onboard-count</c>, <c>agency.onboard-count</c>).
            </summary>
            <remarks>
            Chỉ khoá khi thật sự có chỉ tiêu onboard đã chốt trong kỳ đó — không khoá theo kiểu
            "tháng đã qua thì cấm sửa", vì như vậy là bắt miền tuyển dụng trả giá cho một phân hệ
            mà họ có thể chưa dùng.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriodLockService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodLockService" />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiConfigKeys">
            <summary>
            Tên khoá <c>AppConfig</c> của phân hệ KPI — seed bằng migration, không hardcode giá trị.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiConfigKeys.EffectiveFrom">
            <summary>Mốc áp dụng KPI chính thức, dạng <c>yyyy-MM-dd</c> (§7.9)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiConfigKeys.RecloseWindowDays">
            <summary>Số ngày đầu tháng sau còn cho chốt lại kỳ vừa qua (§3.4)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiConfigKeys.EnableBonus">
            <summary>
            Công tắc sinh thưởng thành <c>PayrollAdjustment</c> (§5 GĐ E) — mặc định TẮT, chỉ chủ dự
            án bật ở bước 4 của §5.1
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodSettings">
            <summary>
            Đọc hai khoá cấu hình điều khiển luồng chốt kỳ, và trả lời hai câu hỏi rút ra từ chúng.
            </summary>
            <remarks>
            Tách khỏi service chốt kỳ để kiểm được bằng test đơn vị mà không dựng cả engine, và để chỉ
            có **một** nơi diễn giải chuỗi cấu hình thành ngày/số. §3.10 xếp <c>Kpi.EffectiveFrom</c> vào
            nhóm "chuỗi cấu hình đổi được tiền" — mỗi nơi tự parse một kiểu là mỗi nơi sai một kiểu.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodSettings.GetEffectiveFromAsync">
            <summary>
            Mốc áp dụng KPI chính thức; <c>null</c> khi chưa cấu hình hoặc giá trị không đọc được
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodSettings.IsTrialPeriodAsync(System.Int32,System.Int32)">
            <summary>
            Kỳ tháng này là kỳ thử nghiệm (chốt trước mốc) hay kỳ chính thức.
            </summary>
            <remarks>
            <b>Fail-closed</b>: chưa cấu hình mốc, hoặc mốc ghi sai định dạng ⇒ coi là kỳ thử nghiệm.
            Nhầm về phía "thử nghiệm" chỉ làm chậm việc trả thưởng và người vận hành thấy ngay;
            nhầm về phía "chính thức" là tiền tự sinh ở GĐ E trước khi có ai duyệt (§5.1 bước 4).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodSettings.GetRecloseWindowDaysAsync">
            <summary>
            Số ngày cửa sổ chốt lại; rơi về mặc định an toàn nếu cấu hình thiếu/sai
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodSettings.IsBonusEnabledAsync">
             <summary>
             Công tắc sinh thưởng đang bật hay tắt.
             </summary>
             <remarks>
             <b>Fail-closed</b>: khoá thiếu, giá trị rác, hay ghi kiểu "1"/"yes" đều ra <c>false</c> —
             chỉ đúng chuỗi <c>true</c> (không phân biệt hoa thường, cắt khoảng trắng) mới bật. Nhầm về
             phía tắt thì người vận hành thấy ngay là chưa có tiền; nhầm về phía bật là tiền tự sinh
             trước khi có ai duyệt (§5.1 bước 4).
            
             Đọc qua đây, <b>đừng parse chỗ khác</b>: mỗi nơi tự diễn giải một kiểu là mỗi nơi sai một
             kiểu. Lưu ý <c>AppConfig</c> có hai lớp cache song song — đổi khoá phải làm mới cả hai,
             nếu không công tắc bật mà một giờ sau mới có hiệu lực (bẫy GĐ D).
             </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriodSettings">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiPeriodSettings" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriodSettings.DefaultRecloseWindowDays">
            <summary>Cửa sổ chốt lại mặc định khi cấu hình thiếu hoặc ghi sai (ngày)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriod">
            <summary>
            Quy đổi kỳ KPI (năm/tháng, quý, năm) thành khoảng ngày — dùng chung cho chốt kỳ và tổng hợp.
            </summary>
            <remarks>
            Mọi mốc dùng offset +07:00 cứng, khớp <c>KpiActualContext.ForMonth</c> của GĐ B: giờ máy chủ
            có thể là UTC khi chạy container, còn kỳ KPI thì luôn là kỳ theo giờ Việt Nam. Để trôi theo
            giờ máy chủ là số của ngày mùng 1 nhảy sang kỳ trước.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriod.Offset">
            <summary>Múi giờ của kỳ KPI: +07:00</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriod.MonthStart(System.Int32,System.Int32)">
            <summary>Thời điểm đầu một kỳ tháng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriod.MonthEnd(System.Int32,System.Int32)">
            <summary>Thời điểm cuối một kỳ tháng (tick cuối cùng)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriod.PreviousMonthOf(System.DateTimeOffset)">
            <summary>
            Kỳ tháng liền trước một thời điểm — job chốt kỳ chạy mùng 1 để chốt tháng vừa qua.
            </summary>
            <remarks>
            <b>Quy thời điểm về +07:00 trước khi đọc năm/tháng.</b> Job chạy 5:15 sáng giờ Việt Nam
            ngày mùng 1, tức 22:15 UTC ngày cuối tháng trước. Trên máy chủ chạy giờ UTC — kiểu triển
            khai container thông thường — đọc thẳng <c>moment.Month</c> sẽ ra tháng CŨ, rồi lùi thêm
            một tháng nữa thành chốt nhầm kỳ trước nữa: tháng 7 bị chốt lại (ghi đè snapshot) còn
            tháng 8 không ai chốt.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriod.CurrentMonthOf(System.DateTimeOffset)">
            <summary>
            Kỳ tháng đang chạy tại một thời điểm — cùng luật quy đổi với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriod.PreviousMonthOf(System.DateTimeOffset)"/>.
            </summary>
            <remarks>
            Tồn tại để nơi nào cần "kỳ hiện tại" cũng đi qua đúng một chỗ. Đọc thẳng
            <c>DateTimeOffset.Now.Month</c> trên máy chủ chạy UTC là lệch hẳn một kỳ trong 7 tiếng
            đầu mỗi ngày mùng 1 — cùng họ với lỗi job chốt kỳ của GĐ D.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiPeriod.QuarterMonths(System.Int32)">
            <summary>Các tháng thuộc một quý (1-4)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiProgressService">
            <summary>
            Theo dõi KPI **trong kỳ**: tính giá trị thực tại thời điểm gọi, không snapshot (plan §3.4).
            </summary>
            <remarks>
            Khác hẳn chốt kỳ (GĐ D): ở đây không ghi gì xuống DB, số đọc lúc nào là số lúc đó. Chấp nhận
            chậm hơn vì mỗi dòng gọi lại stored procedure báo cáo — đổi lại số luôn khớp màn báo cáo.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiProgressService.GetProgressAsync(Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiProgressQuery,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy tiến độ KPI của một kỳ, gộp theo chủ thể.
            Phạm vi xem ép server-side theo §3.6 — tham số lọc của client chỉ thu hẹp được, không nới ra.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiProgressQuery">
            <summary>
            Tham số màn theo dõi KPI.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiProgressQuery.PeriodYear">
            <summary>Năm của kỳ; ≤ 0 thì lấy năm hiện tại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiProgressQuery.PeriodMonth">
            <summary>Tháng của kỳ (1-12); ngoài khoảng thì lấy tháng hiện tại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiProgressQuery.SubjectKind">
            <summary>Lọc thêm theo loại chủ thể (tuỳ chọn)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiProgressQuery.SubjectId">
            <summary>
            Lọc thêm theo một chủ thể cụ thể (tuỳ chọn).
            Chỉ **thu hẹp** kết quả: chủ thể ngoài phạm vi xem thì trả rỗng chứ không mở thêm quyền.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiProgressService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiProgressService" />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiProgressService.ResolveActualAsync(Lada.Framework.Data.Domains.Kpi.KpiAssignment,Lada.Framework.Data.Domains.Kpi.KpiMetric,System.Int32,System.Int32,System.Collections.Generic.Dictionary{System.String,System.ValueTuple{System.Nullable{System.Decimal},System.String}},System.Collections.Generic.Dictionary{System.Int32,Lada.Framework.Data.Domains.Kpi.KpiResult})">
            <summary>
            Lấy giá trị thực của một dòng, quy mọi trục trặc thành ghi chú thay vì ném lỗi.
            </summary>
            <remarks>
            <para>
            Một chỉ số hỏng không được làm sập cả màn theo dõi (§3.9d) — người quản lý vẫn phải xem
            được các chỉ tiêu còn lại. Dòng hỏng để <c>ActualValue</c> null kèm ghi chú, tuyệt đối
            không quy về 0.
            </para>
            <para>
            <b>Kỳ ĐÃ CHỐT đọc thẳng <c>KpiResult</c>, không chạy lại provider.</b> Đây là chốt chặn
            phơi nhiễm của nợ <c>KPI-8</c>: hai chỉ số <c>agency.*</c> gom nhân sự theo
            <c>User.AgencyId</c> **tại thời điểm chạy**, nên mở lại một kỳ đã qua sau khi lái xe
            chuyển bưu cục sẽ ra số khác lần chốt — bưu cục cũ tụt, bưu cục mới tự nhiên có thêm công
            của tháng mà người đó chưa thuộc về. Snapshot bất biến của §3.4 chỉ có tác dụng nếu màn
            hình thật sự đọc nó; gọi lại provider là vô hiệu hoá chính cái snapshot vừa ghi.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiProgressService.FillSubjectNamesAsync(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Kpi.KpiProgressItem})">
            <summary>
            Gán tên hiển thị cho chủ thể — SubjectId đa hình nên không có navigation property
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiSourceCodes">
             <summary>
             Danh sách mã nguồn dữ liệu tự động của KPI (plan §3.3).
             </summary>
             <remarks>
             Đây là **danh mục tên mã** để seed migration và để provider khai <c>Code</c> mà không gõ chuỗi
             rời rạc. Nó KHÔNG còn là căn cứ validate: từ GĐ B, <c>KpiMetricService</c> hỏi
             <c>IKpiEngineService.IsSourceCodeRegistered</c> — tức hỏi provider nào thật sự chạy được —
             nên mã nằm trong danh sách này mà chưa có provider thì vẫn bị từ chối lúc lưu chỉ số.
            
             Trạng thái provider tại 2026-08-14 (cuối GĐ B):
             đã có 6 mã cá nhân (<c>driver.pickup-count</c>, <c>driver.delivery-count</c>,
             <c>sales.revenue</c>, <c>sales.order-count</c>, <c>sales.new-customers</c>,
             <c>hr.onboard-count</c>); <c>driver.delivery-rate</c> tạm bỏ qua theo §7.11a (nợ KPI-6);
             <c>sales.active-customers</c> và nhóm <c>agency.*</c> để GĐ C.
             </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiSourceCodes.All">
            <summary>
            Toàn bộ mã hợp lệ — dùng validate lúc lưu KpiMetric SourceType = Auto
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiVisibilityResolver">
            <summary>
            Nguồn duy nhất của luật "ai xem được KPI của ai" (plan §3.6).
            </summary>
            <remarks>
            Tách riêng vì phân hệ KPI có nhiều đường đọc cùng một tập dữ liệu — danh sách chỉ tiêu, màn
            theo dõi trong kỳ, kết quả kỳ, xuất Excel — và §3.10 chỉ đích danh rủi ro: **đường đọc thứ hai
            quên lọc phạm vi là bài kinh điển**. Mỗi đường tự chép lại luật thì sớm muộn cũng lệch nhau,
            nên mọi đường phải hỏi đúng lớp này.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiVisibilityResolver.CanReadKpiAsync(System.Int32)">
            <summary>
            Người này có được phép đọc dữ liệu KPI hay không — cổng vào của cả miền.
            </summary>
            <remarks>
            <para>
            Khác <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiVisibilityResolver.CanViewAllAsync(System.Int32)"/>: hàm này trả lời "có được xem KPI KHÔNG", còn hàm kia
            trả lời "xem được của AI". Mọi đường đọc KPI **không đi qua controller** (widget
            dashboard, job, export) phải hỏi hàm này trước, vì lớp <c>[Authorize(Roles = ...)]</c>
            chỉ gác đường HTTP.
            </para>
            <para>
            Điều kiện chép đúng bằng cổng của <c>GET /api/kpi/progress</c> — <b>đường đọc mới không
            bao giờ được rộng hơn đường đọc sẵn có của chính miền đó</b> (plan §8). Widget dashboard
            gác bằng <b>nhóm quyền</b> (<c>DashboardWidgetPermission</c>), một trục hoàn toàn khác
            role; không có hàm này thì người thuộc nhóm quyền được mở widget sẽ đọc được KPI của cấp
            dưới trong khi màn KPI vẫn trả 403 cho họ — đúng bẫy "mượn lớp phân quyền của miền này
            để gác dữ liệu của miền khác" mà GĐ C và GĐ D đã cắn.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiVisibilityResolver.CanViewAllAsync(System.Int32)">
            <summary>
            Người này xem được KPI của tất cả mọi người không (Founder hoặc có quyền Kpi.ViewAll)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiVisibilityResolver.GetVisibleUserIdsAsync(System.Int32)">
            <summary>
            Tập nhân viên người này xem được KPI: chính mình + cấp dưới trực tiếp
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiVisibilityResolver.GetVisibleAgencyIdsAsync(System.Int32)">
            <summary>
            Tập đơn vị người này xem được KPI: đơn vị mình quản lý + đơn vị con của chúng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiVisibilityResolver.GetDirectManagerIdAsync(System.Int32)">
            <summary>
            Quản lý trực tiếp của một nhân viên
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiVisibilityResolver.IsFounderAsync(System.Int32)">
            <summary>
            Người này có phải Founder không (Founder bỏ qua mọi ràng buộc phạm vi)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiVisibilityResolver">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiVisibilityResolver" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiVisibilityResolver.RoleAssignmentSearch">
            <summary>Role gác <c>GET /api/kpi/progress</c> — cổng đọc KPI của cả miền</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiVisibilityResolver.CanReadKpiAsync(System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiVisibilityResolver.GetDirectManagerIdAsync(System.Int32)">
            <summary>
            Quản lý trực tiếp của một nhân viên — đọc <c>UserPreference.ManagerId</c>, KHÔNG phải
            <c>User.ManagerId</c>.
            </summary>
            <remarks>
            Đo trên DB dev 2026-08-14: 131 nhân viên đang hoạt động, <b>0</b> người có
            <c>User.ManagerId &gt; 0</c>, 46 người có <c>UserPreference.ManagerId &gt; 0</c>.
            Cột <c>User.ManagerId</c> chỉ còn nghĩa cũ "sale quản lý khách hàng" và không luồng nào
            ghi cho nhân viên — dùng nhầm nó thì mọi chỉ tiêu chỉ Founder giao được.
            Toàn hệ thống (UserService, PayrollService, LeaveService) đều đọc UserPreference.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiVisibilityResolver.GetVisibleUserIdsAsync(System.Int32)">
            <summary>
            Phạm vi xem theo §3.6: chính mình + cấp dưới trực tiếp (theo UserPreference.ManagerId)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiVisibilityResolver.GetVisibleAgencyIdsAsync(System.Int32)">
            <summary>
            Phạm vi xem theo §3.6: các đơn vị mình trực tiếp quản lý **và các đơn vị con của chúng**.
            </summary>
            <remarks>
            Phần "đơn vị con" là bắt buộc để khớp với quyền giao §7.3: quản lý node cha giao được
            chỉ tiêu cho node con, nên phải xem được chính chỉ tiêu mình vừa giao. Bản đầu chỉ lấy
            <c>ManagerId == userId</c> — bấm thật 2026-08-14 lộ ra quản lý khu vực giao cho bưu cục con
            xong thì màn danh sách của họ trống trơn.
            Tập này khớp đúng tập §7.3 cho phép thao tác, không nới rộng hơn.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.AgencyDriverProductivityProvider">
             <summary>
             Năng suất lái xe của cả bưu cục / khu vực trong kỳ (<c>agency.driver-productivity</c>):
             tổng số đơn **lấy + giao** do người của đơn vị thực hiện.
             </summary>
             <remarks>
             **Đơn vị đo là "đơn", không phải "đơn/người"** — theo đúng danh mục chỉ số đã seed ở GĐ A.
             Vì là tổng chứ không phải trung bình, chỉ số này **không có mẫu số**, nên lái xe mới chưa chạy
             đơn nào chỉ đóng góp 0 chứ không làm lệch số của người khác.
            
             **Cách nhận diện lái xe — quyết định §7.12b.** `HrPermissionMappings` rỗng nên không tra được
             chức danh; thay vào đó truyền **toàn bộ nhân sự của đơn vị** vào SP báo cáo và để dữ liệu vận
             hành tự lọc: ai không lấy/giao đơn nào thì SP không trả dòng nào. Với một chỉ số dạng TỔNG,
             cách này ra **đúng cùng con số** với cách gom theo danh sách chức danh của HR — người không
             phải lái xe cộng vào 0. Vì vậy nợ `KPI-5` không còn chặn chỉ số này.
            
             Tái dùng đúng <c>sp_GetDriverProductivityReportByDate</c> mà hai chỉ số lái xe cá nhân đang
             gọi (§3.9a): số của bưu cục vì thế luôn bằng tổng số của từng lái xe trên màn báo cáo, không
             bao giờ lệch âm thầm.
            
             Một đơn vừa được người của đơn vị lấy vừa được người của đơn vị giao sẽ tính **hai công** —
             đúng ý nghĩa "khối lượng việc đã làm", và giống hệt cách cộng
             <c>driver.pickup-count + driver.delivery-count</c> của từng cá nhân.
             </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.AgencyOnboardCountProvider">
             <summary>
             Số ứng viên nhận việc trong kỳ tính cho cả bưu cục / khu vực (<c>agency.onboard-count</c>).
             </summary>
             <remarks>
             Cùng định nghĩa "nhận việc" với <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.HrOnboardCountProvider"/> (trạng thái
             <c>Onboard</c>, mốc kỳ <c>Candidate.OnboardedTime</c>), chỉ khác ở chỗ gom theo **đơn vị của
             người phụ trách tuyển** thay vì theo từng người (plan §3.3).
            
             Hồ sơ chưa gán <c>RecruiterId</c> không tính cho đơn vị nào — giống hệt luật của chỉ số cá
             nhân, để tổng của các bưu cục không bao giờ vượt tổng của các cá nhân.
            
             Không đếm trùng khi gộp khu vực: một hồ sơ có đúng một người tuyển, người đó thuộc đúng một
             đơn vị, nên hồ sơ chỉ rơi vào một bưu cục trong phạm vi.
             </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.AgencyRevenueProvider">
             <summary>
             Doanh số của một bưu cục / khu vực trong kỳ (<c>agency.revenue</c>).
             </summary>
             <remarks>
             Nguồn: <c>sp_GetAgencyRevenueStatistics</c> qua <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Report.OperationReports.IBranchReportService"/>, nhóm theo
             <c>Order.SaleAgencyId</c> (plan §7.7), doanh thu = <c>OrderFin.TotalFeeAfterVat</c>.
            
             ⚠️ **Không cộng dồn được với <c>sales.revenue</c>.** Chỉ số của sale cố ý dùng công thức của SP
             báo cáo đang chạy: thiếu 3 khoản phí và tính theo **thời điểm thu tiền** (ngoại lệ §7.11b).
             Chỉ số này theo **ngày lên đơn** và đủ 7 khoản. Ai cộng hai con số lại sẽ ra một số vô nghĩa.
            
             Không đếm trùng khi gộp khu vực: SP trả **một dòng cho mỗi bưu cục**, mỗi đơn chỉ thuộc đúng
             một <c>SaleAgencyId</c>, nên cộng các dòng lại không thể tính một đơn hai lần.
             </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.AgencyScopedProviderBase">
             <summary>
             Nền dùng chung của mọi provider có chủ thể là đơn vị (<c>agency.*</c>): phân giải phạm vi gộp
             một lần, đúng một chỗ.
             </summary>
             <remarks>
             Luật gộp (plan §7.2) nằm ở <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiAgencyScopeResolver"/> chứ không ở đây — lớp này chỉ
             bảo đảm **mọi** provider đơn vị đều đi qua nó. Nếu để từng provider tự đệ quy cây thì chỉ cần
             một provider quên là khu vực ra số của riêng node cha, và không ai phát hiện vì con số vẫn
             "trông hợp lý".
            
             Đặt việc phân giải ở provider chứ không ở <c>KpiEngineService</c> để mọi đường gọi đều tự đúng:
             GĐ D thêm job chốt kỳ sẽ không phải nhớ tự expand cây.
             </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.AgencyScopedProviderBase.ResolveScopeAsync(Ladaer.BackEnd.Infrastructures.Services.Kpi.KpiActualContext)">
            <summary>
            Danh sách đơn vị phải gộp cho ngữ cảnh này — đã khử trùng lặp.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.DriverProductivityProviderBase">
             <summary>
             Nền dùng chung của hai chỉ số năng suất lái xe — cùng gọi một stored procedure.
             </summary>
             <remarks>
             **Tái dùng đúng SP mà màn báo cáo năng suất lái xe đang chạy**
             (<c>sp_GetDriverProductivityReportByDate</c>, qua <c>IDriverReportService</c>), truyền y hệt bộ
             tham số mà màn đó truyền. Đây là cách duy nhất bảo đảm tiêu chí §3.9a: số trên màn KPI và số
             trên màn báo cáo không bao giờ lệch nhau âm thầm. Viết lại query bằng EF trông sạch hơn nhưng
             sẽ trôi khỏi SP ngay lần đầu ai đó sửa SP.
            
             Gọi thẳng SP thay vì gọi qua <c>IDriverReportService</c> vì service đó nhận
             <c>SmartTableParam</c> và tự lọc theo quyền của người đang đăng nhập — hai thứ sai ngữ cảnh ở
             đây, nơi chủ thể là lái xe được chấm KPI chứ không phải người đang xem.
            
             Ngữ nghĩa kỳ (kế thừa từ SP, ghi lại để khỏi đoán): đơn tính vào kỳ theo
             <c>OrderTimeTrack.PickupTime</c> / <c>DeliveryDate</c> — mốc lái xe làm việc thật, không phải
             ngày tạo đơn. Không lọc trạng thái đơn, vì đã lấy hàng/giao hàng là đã có công.
             </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.DriverProductivityProviderBase.SumOf(Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Operations.DriverProductivityReportByDateItem)">
            <summary>Cộng cột nào của báo cáo lại thành giá trị thực</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.DriverProductivityProviderBase.SourceColumnName">
            <summary>Tên cột báo cáo, ghi vào DetailJson để người đối soát biết nhìn vào đâu</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.DriverPickupCountProvider">
            <summary>
            Số đơn lái xe đã lấy hàng trong kỳ (<c>driver.pickup-count</c>).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.DriverDeliveryCountProvider">
            <summary>
            Số đơn lái xe đã giao thành công trong kỳ (<c>driver.delivery-count</c>).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.HrOnboardCountProvider">
             <summary>
             Số ứng viên nhận việc trong kỳ, tính cho người phụ trách tuyển (<c>hr.onboard-count</c>).
             </summary>
             <remarks>
             Đếm theo <c>Candidate.RecruiterId</c> (plan §7.6), **không** theo <c>CreatedBy</c>: đo trên DB
             dev 2026-08-14 thì 96% hồ sơ 6 tháng gần nhất do đúng một tài khoản nhập hộ, nên
             <c>CreatedBy</c> là dấu vết người nhập liệu chứ không phải người tuyển.
            
             Mốc kỳ là <c>OnboardedTime</c> — cột thêm cùng giai đoạn này. Không dùng <c>UpdatedTime</c> vì
             nó đổi theo mọi lần sửa hồ sơ, sửa một dòng ghi chú là số của cả kỳ nhảy sang kỳ khác.
            
             Hồ sơ chưa gán người tuyển (<c>RecruiterId</c> trống — 94/663 hồ sơ trên DB dev, phần lớn là
             ứng viên tự nộp) **không tính cho ai**. Đó là lý do màn Candidate có bộ lọc "chưa có người
             phụ trách" để nhân sự nhận hồ sơ về mình trước khi chốt kỳ.
             </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.SalesActiveCustomersProvider">
             <summary>
             Số khách hàng đang hoạt động của một sale tại ngày chốt kỳ (<c>sales.active-customers</c>).
             </summary>
             <remarks>
             Định nghĩa "hoạt động" chốt ở plan §7.4: có ít nhất một đơn **tạo trong 3 tháng gần nhất**
             tính đến ngày chốt **và** đơn đó đã giao thành công. Cửa sổ **trượt 3 tháng**, không bó theo
             kỳ tháng — nên chỉ số này là ảnh chụp **tại một thời điểm**, khác các chỉ số khác vốn cộng dồn
             cả kỳ. Mốc chụp là <c>ToDate</c> (cuối kỳ).
            
             Dùng **cùng một SP** với danh sách khách không hoạt động mà người quản lý nhìn thấy, để con số
             và danh sách không bao giờ lệch nhau — xem <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerActivityService"/>.
            
             ⚠️ Đây **không phải** cơ chế "nhả quản lý" khách hàng — việc đó là nợ `KPI-1`, làm ở đợt riêng
             (§7.4). Ở đây chỉ đếm và liệt kê, không đụng <c>Customer.ManagerId</c>.
             </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.SalesActiveCustomersProvider.IsPointInTime">
            <summary>
            Chỉ số ảnh chụp — xem <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.IKpiActualProvider.IsPointInTime"/>. Hệ quả ở tầng tổng
            hợp quý/năm: chỉ tiêu quý KHÔNG cộng dồn ba tháng, mà lấy chỉ tiêu của tháng cuối kỳ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.SalesNewCustomersProvider">
             <summary>
             Số khách hàng mới sale mở được trong kỳ (<c>sales.new-customers</c>).
             </summary>
             <remarks>
             Định nghĩa theo plan §3.3: khách có <c>CreatedTime</c> nằm trong kỳ và <c>ManagerId</c> là sale
             đang được chấm. Không có SP báo cáo tương ứng nên query bằng EF — nhẹ và đủ.
            
             Đếm theo <c>ManagerId</c> **hiện tại**, không phải người mở khách lúc đó: khách chuyển tay sang
             sale khác thì số kỳ cũ đổi theo. Chấp nhận được vì §5 đã chốt không tính KPI cho kỳ quá khứ,
             còn trong kỳ đang chạy thì chuyển tay là hiếm và người quản lý thấy ngay trên màn theo dõi.
            
             <c>Repository.Query()</c> đã lọc sẵn xoá mềm — khách đã xoá không tính cho ai, đúng ý muốn.
             </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.SalesRevenueProviderBase">
             <summary>
             Nền dùng chung của hai chỉ số doanh số/sản lượng sale — cùng gọi một stored procedure.
             </summary>
             <remarks>
             **Quyết định chủ dự án 2026-08-14 (plan §7.11b): khớp SP báo cáo đang chạy**
             (<c>sp_GetOrderRevenueStatisticsBySale_Optimized</c>, cùng SP của màn "Thống kê doanh thu theo
             sale"), để số trên màn KPI khớp từng đồng với màn báo cáo mà quản lý đang dùng (tiêu chí §3.9a).
            
             Ngữ nghĩa kế thừa từ SP — phải nói rõ vì nó KHÁC nguyên tắc <c>TotalFeeAfterVat</c> ở §7.7/§8,
             và đây là ngoại lệ có chủ ý chỉ áp cho nhóm <c>sales.*</c>:
             <list type="bullet">
             <item>Doanh thu = <c>Fee + CodFee + PickupSubFee + DeliverySubFee − Discount</c>; KHÔNG gồm
             <c>GoodsAttributeFee</c>, <c>InsuranceFee</c>, <c>ReturnFee</c>.</item>
             <item>Đơn rơi vào kỳ theo **thời điểm thu được tiền** (suy từ <c>PayFeeType</c>), không phải
             ngày tạo đơn ⇒ đơn tạo cuối tháng mà tháng sau mới thu thì tính cho kỳ sau; đơn chưa thu tiền
             không tính cho ai.</item>
             <item>Đơn huỷ (<c>Status = 8</c>) bị loại khỏi cả doanh thu lẫn sản lượng.</item>
             </list>
            
             SP nhận tham số kiểu DATE và tự cộng một ngày vào <c>@EndDate</c>, nên truyền thẳng phần ngày
             của khoảng là đúng — kỳ tính trọn cả ngày cuối.
             </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.SalesRevenueProviderBase.ValueOf(Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueBySaleItem)">
            <summary>Lấy cột nào của báo cáo làm giá trị thực</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.SalesRevenueProviderBase.SourceColumnName">
            <summary>Tên cột báo cáo, ghi vào DetailJson để người đối soát biết nhìn vào đâu</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.SalesRevenueProvider">
            <summary>
            Doanh số sale trong kỳ (<c>sales.revenue</c>).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Kpi.Providers.SalesOrderCountProvider">
            <summary>
            Sản lượng đơn của sale trong kỳ (<c>sales.order-count</c>).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyMediaPublishPreconditions">
            <summary>
            Điều kiện công bố #5 (plan §3.3): ≥ 1 ảnh bìa chụp thật, đã duyệt, có alt; mềm: &lt; 6 ảnh đã duyệt.
            Chỉ tính ảnh <see cref="M:Lada.Framework.Infrastructures.Services.Network.AgencyPublicMedia.IsPublic(Lada.Framework.Data.Domains.Network.AgencyMedia)"/> — ảnh Branch.Manager tải lên chờ duyệt không làm hồ sơ "đủ ảnh".
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyMediaPublishPreconditions.RecommendedPhotoCount">
            <summary>Số ảnh đã duyệt khuyến nghị — dưới mức này chỉ cảnh báo.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentPublishPreconditions">
            <summary>
            Điều kiện công bố #6 (giới thiệu 150–400 từ, không trùng ≥ 80 % với hồ sơ khác) và #10 (cổng chặn nội dung), cùng
            luật "không số điện thoại trong nội dung" của đặc tả §10.3 — áp lên mọi chữ lên web: Intro, hỏi đáp, thông báo tạm
            ngưng, alt + chú thích của ảnh đã duyệt (plan §3.3).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublicText">
            <summary>Một đoạn chữ của hồ sơ bưu cục sẽ lên trang công khai, kèm tên trường để báo lỗi đúng chỗ.</summary>
            <param name="Field">Tên trường theo DTO: <c>Intro</c>, <c>Faq[0].Q</c>, <c>PausedMessage</c>, <c>Media[12].Caption</c>…</param>
            <param name="Text">Văn bản thuần (Intro đã bỏ thẻ HTML).</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublicText.#ctor(System.String,System.String)">
            <summary>Một đoạn chữ của hồ sơ bưu cục sẽ lên trang công khai, kèm tên trường để báo lỗi đúng chỗ.</summary>
            <param name="Field">Tên trường theo DTO: <c>Intro</c>, <c>Faq[0].Q</c>, <c>PausedMessage</c>, <c>Media[12].Caption</c>…</param>
            <param name="Text">Văn bản thuần (Intro đã bỏ thẻ HTML).</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublicText.Field">
            <summary>Tên trường theo DTO: <c>Intro</c>, <c>Faq[0].Q</c>, <c>PausedMessage</c>, <c>Media[12].Caption</c>…</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublicText.Text">
            <summary>Văn bản thuần (Intro đã bỏ thẻ HTML).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPhoneHit">
            <summary>Một số điện thoại tìm thấy trong nội dung.</summary>
            <param name="Field">Trường chứa số.</param>
            <param name="Line">Dòng (từ 1) trong văn bản thuần của trường.</param>
            <param name="Column">Ký tự (từ 1) trong dòng đó.</param>
            <param name="Value">Chuỗi số khớp, nguyên văn.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPhoneHit.#ctor(System.String,System.Int32,System.Int32,System.String)">
            <summary>Một số điện thoại tìm thấy trong nội dung.</summary>
            <param name="Field">Trường chứa số.</param>
            <param name="Line">Dòng (từ 1) trong văn bản thuần của trường.</param>
            <param name="Column">Ký tự (từ 1) trong dòng đó.</param>
            <param name="Value">Chuỗi số khớp, nguyên văn.</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPhoneHit.Field">
            <summary>Trường chứa số.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPhoneHit.Line">
            <summary>Dòng (từ 1) trong văn bản thuần của trường.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPhoneHit.Column">
            <summary>Ký tự (từ 1) trong dòng đó.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPhoneHit.Value">
            <summary>Chuỗi số khớp, nguyên văn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPhoneHit.Position">
            <summary>"dòng 2, ký tự 15".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyFaqItem">
            <summary>Một câu hỏi thường gặp của bưu cục (<c>AgencyProfile.FaqJson</c> = mảng <c>[{"Q":"…","A":"…"}]</c>, chữ thuần).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyIntroFingerprint">
            <summary>Dấu vân tay trigram của một đoạn giới thiệu — tính một lần, so với mọi hồ sơ khác.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyIntroDuplicate">
            <summary>Kết quả so trùng: hồ sơ giống nhất và tỷ lệ phần trăm (làm tròn xuống).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyIntroDuplicate.#ctor(System.Int32,System.String,System.Int32)">
            <summary>Kết quả so trùng: hồ sơ giống nhất và tỷ lệ phần trăm (làm tròn xuống).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyIntroCorpus">
            <summary>
            Bộ intro của mọi hồ sơ, nạp MỘT lần cho cả lượt (Get / SetStatus / Search lọc "thiếu điều kiện đăng") — không mỗi hồ
            sơ một truy vấn. Việc 0 A2: dev có 0 intro; mạng lưới vài chục bưu cục nên so từng cặp trong bộ nhớ là đủ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyIntroCorpus.FindDuplicate(System.Int32,System.Collections.Generic.IReadOnlySet{System.String})">
            <summary>Hồ sơ KHÁC có intro giống ≥ ngưỡng nhất; null nếu không có.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules">
            <summary>
            Luật nội dung hồ sơ bưu cục — hàm thuần, dùng chung cho kiểm lúc ghi (<c>Update</c>, nhân sự, ảnh) và điều kiện công
            bố #5/#6/#10 (docs/plan-buu-cuc.md §3.3, đặc tả §10.3).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.IntroMaxLength">
            <summary>Trần độ dài HTML của Intro (400 từ tiếng Việt kèm thẻ ≈ 3–5 nghìn ký tự) — chặn payload rác.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.DuplicatePercent">
            <summary>Trùng từ ngưỡng này trở lên là <c>DUPLICATE_INTRO</c> (đặc tả §9.2 "trùng ≥ 80%").</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.PhonePattern">
            <remarks>
            Pattern:<br/>
            <code>(?&lt;![\\d+.,])(\\+84|0)\\s?\\d{2,4}\\)?[\\s.\\-]?\\d{3,4}[\\s.\\-]?\\d{3,4}(?![\\d]|[.,]\\d)</code><br/>
            Explanation:<br/>
            <code>
            ○ Zero-width negative lookbehind.<br/>
                ○ Match a character in the set [+,.\d] right-to-left.<br/>
            ○ 1st capture group.<br/>
                ○ Match with 2 alternative expressions.<br/>
                    ○ Match the string "+84".<br/>
                    ○ Match '0'.<br/>
            ○ Match a whitespace character atomically, optionally.<br/>
            ○ Match a Unicode digit greedily at least 2 and at most 4 times.<br/>
            ○ Match ')' atomically, optionally.<br/>
            ○ Match a character in the set [-.\s] greedily, optionally.<br/>
            ○ Match a Unicode digit greedily at least 3 and at most 4 times.<br/>
            ○ Match a character in the set [-.\s] greedily, optionally.<br/>
            ○ Match a Unicode digit greedily at least 3 and at most 4 times.<br/>
            ○ Zero-width negative lookahead.<br/>
                ○ Match with 2 alternative expressions, atomically.<br/>
                    ○ Match a Unicode digit.<br/>
                    ○ Match a sequence of expressions.<br/>
                        ○ Match a character in the set [,.].<br/>
                        ○ Match a Unicode digit.<br/>
            </code>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.ScriptOrStyle">
            <remarks>
            Pattern:<br/>
            <code>&lt;\\s*(script|style)\\b[^&gt;]*&gt;.*?&lt;\\s*/\\s*\\1\\s*&gt;</code><br/>
            Options:<br/>
            <code>RegexOptions.IgnoreCase | RegexOptions.Singleline</code><br/>
            Explanation:<br/>
            <code>
            ○ Match '&lt;'.<br/>
            ○ Match a whitespace character atomically any number of times.<br/>
            ○ 1st capture group.<br/>
                ○ Match a character in the set [Ss].<br/>
                ○ Match with 2 alternative expressions.<br/>
                    ○ Match a sequence of expressions.<br/>
                        ○ Match a character in the set [Cc].<br/>
                        ○ Match a character in the set [Rr].<br/>
                        ○ Match a character in the set [Ii].<br/>
                        ○ Match a character in the set [Pp].<br/>
                        ○ Match a character in the set [Tt].<br/>
                    ○ Match a sequence of expressions.<br/>
                        ○ Match a character in the set [Tt].<br/>
                        ○ Match a character in the set [Yy].<br/>
                        ○ Match a character in the set [Ll].<br/>
                        ○ Match a character in the set [Ee].<br/>
            ○ Match if at a word boundary.<br/>
            ○ Match a character other than '&gt;' atomically any number of times.<br/>
            ○ Match '&gt;'.<br/>
            ○ Match any character lazily any number of times.<br/>
            ○ Match '&lt;'.<br/>
            ○ Match a whitespace character atomically any number of times.<br/>
            ○ Match '/'.<br/>
            ○ Match a whitespace character greedily any number of times.<br/>
            ○ Match the same text as matched by the 1st capture group.<br/>
            ○ Match a whitespace character atomically any number of times.<br/>
            ○ Match '&gt;'.<br/>
            </code>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.BlockBreak">
            <remarks>
            Pattern:<br/>
            <code>&lt;\\s*br\\s*/?\\s*&gt;|&lt;\\s*/\\s*(p|div|li|h[1-6]|tr|blockquote|section|table|ul|ol|dt|dd|pre|figure|figcaption)\\s*&gt;</code><br/>
            Options:<br/>
            <code>RegexOptions.IgnoreCase</code><br/>
            Explanation:<br/>
            <code>
            ○ Match '&lt;'.<br/>
            ○ Atomic group.<br/>
                ○ Match a whitespace character atomically any number of times.<br/>
                ○ Match with 2 alternative expressions, atomically.<br/>
                    ○ Match a sequence of expressions.<br/>
                        ○ Match an empty string.<br/>
                        ○ Match a character in the set [Rr].<br/>
                        ○ Match a whitespace character greedily any number of times.<br/>
                        ○ Match '/' atomically, optionally.<br/>
                        ○ Match a whitespace character atomically any number of times.<br/>
                        ○ Match '&gt;'.<br/>
                    ○ Match a sequence of expressions.<br/>
                        ○ Match an empty string.<br/>
                        ○ Match a whitespace character atomically any number of times.<br/>
                        ○ 1st capture group.<br/>
                            ○ Match with 15 alternative expressions.<br/>
                                ○ Match a character in the set [Pp].<br/>
                                ○ Match a sequence of expressions.<br/>
                                    ○ Match a character in the set [Dd].<br/>
                                    ○ Match a character in the set [Ii].<br/>
                                    ○ Match a character in the set [Vv].<br/>
                                ○ Match a sequence of expressions.<br/>
                                    ○ Match a character in the set [Ll].<br/>
                                    ○ Match a character in the set [Ii].<br/>
                                ○ Match a sequence of expressions.<br/>
                                    ○ Match a character in the set [Hh].<br/>
                                    ○ Match a character in the set [1-6].<br/>
                                ○ Match a sequence of expressions.<br/>
                                    ○ Match a character in the set [Tt].<br/>
                                    ○ Match a character in the set [Rr].<br/>
                                ○ Match a sequence of expressions.<br/>
                                    ○ Match a character in the set [Bb].<br/>
                                    ○ Match a character in the set [Ll].<br/>
                                    ○ Match a character in the set [Oo].<br/>
                                    ○ Match a character in the set [Cc].<br/>
                                    ○ Match a character in the set [Kk\u212A].<br/>
                                    ○ Match a character in the set [Qq].<br/>
                                    ○ Match a character in the set [Uu].<br/>
                                    ○ Match a character in the set [Oo].<br/>
                                    ○ Match a character in the set [Tt].<br/>
                                    ○ Match a character in the set [Ee].<br/>
                                ○ Match a sequence of expressions.<br/>
                                    ○ Match a character in the set [Ss].<br/>
                                    ○ Match a character in the set [Ee].<br/>
                                    ○ Match a character in the set [Cc].<br/>
                                    ○ Match a character in the set [Tt].<br/>
                                    ○ Match a character in the set [Ii].<br/>
                                    ○ Match a character in the set [Oo].<br/>
                                    ○ Match a character in the set [Nn].<br/>
                                ○ Match a sequence of expressions.<br/>
                                    ○ Match a character in the set [Tt].<br/>
                                    ○ Match a character in the set [Aa].<br/>
                                    ○ Match a character in the set [Bb].<br/>
                                    ○ Match a character in the set [Ll].<br/>
                                    ○ Match a character in the set [Ee].<br/>
                                ○ Match a sequence of expressions.<br/>
                                    ○ Match a character in the set [Uu].<br/>
                                    ○ Match a character in the set [Ll].<br/>
                                ○ Match a sequence of expressions.<br/>
                                    ○ Match a character in the set [Oo].<br/>
                                    ○ Match a character in the set [Ll].<br/>
                                ○ Match a sequence of expressions.<br/>
                                    ○ Match a character in the set [Dd].<br/>
                                    ○ Match a character in the set [Tt].<br/>
                                ○ Match a character in the set [Dd] exactly 2 times.<br/>
                                ○ Match a sequence of expressions.<br/>
                                    ○ Match a character in the set [Pp].<br/>
                                    ○ Match a character in the set [Rr].<br/>
                                    ○ Match a character in the set [Ee].<br/>
                                ○ Match a sequence of expressions.<br/>
                                    ○ Match a character in the set [Ff].<br/>
                                    ○ Match a character in the set [Ii].<br/>
                                    ○ Match a character in the set [Gg].<br/>
                                    ○ Match a character in the set [Uu].<br/>
                                    ○ Match a character in the set [Rr].<br/>
                                    ○ Match a character in the set [Ee].<br/>
                                ○ Match a sequence of expressions.<br/>
                                    ○ Match a character in the set [Ff].<br/>
                                    ○ Match a character in the set [Ii].<br/>
                                    ○ Match a character in the set [Gg].<br/>
                                    ○ Match a character in the set [Cc].<br/>
                                    ○ Match a character in the set [Aa].<br/>
                                    ○ Match a character in the set [Pp].<br/>
                                    ○ Match a character in the set [Tt].<br/>
                                    ○ Match a character in the set [Ii].<br/>
                                    ○ Match a character in the set [Oo].<br/>
                                    ○ Match a character in the set [Nn].<br/>
                        ○ Match a whitespace character atomically any number of times.<br/>
                        ○ Match '&gt;'.<br/>
            </code>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.AnyTag">
            <remarks>
            Pattern:<br/>
            <code>&lt;[^&gt;]*&gt;</code><br/>
            Explanation:<br/>
            <code>
            ○ Match '&lt;'.<br/>
            ○ Match a character other than '&gt;' atomically any number of times.<br/>
            ○ Match '&gt;'.<br/>
            </code>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.NonAlphaNum">
            <remarks>
            Pattern:<br/>
            <code>[^a-z0-9]+</code><br/>
            Explanation:<br/>
            <code>
            ○ Match a character in the set [^0-9a-z] atomically at least once.<br/>
            </code>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.HtmlToText(System.String)">
            <summary>
            HTML (TinyMCE) → văn bản thuần để đếm từ, dò số, chạy cổng chặn: thẻ khối và <c>&lt;br&gt;</c> thành xuống dòng
            (vị trí "dòng n" khớp đoạn văn người dùng thấy), bỏ mọi thẻ khác, giải mã entity, <c>&amp;nbsp;</c> thành khoảng
            trắng, Unicode FormC. Số bị cắt bởi thẻ inline (<c>0912 &lt;b&gt;345&lt;/b&gt; 678</c>) vẫn liền lại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.CountWords(System.String)">
            <summary>Số từ = số cụm cách nhau bởi khoảng trắng có ít nhất một chữ hoặc số (tiếng Việt: mỗi âm tiết một từ, như bộ đếm TinyMCE).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.FindPhones(System.String,System.String)">
            <summary>Mọi số điện thoại trong <paramref name="plainText"/>, kèm dòng/ký tự.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.PhoneMessage(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPhoneHit)">
            <summary>Câu tiếng Việt cho một số điện thoại tìm thấy.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.Trigrams(System.String)">
            <summary>
            Tập trigram theo cách <c>pg_trgm</c> (đặc tả gốc viết cho PostgreSQL): bỏ dấu, viết thường, mọi ký tự ngoài
            [a-z0-9] thành ranh giới từ, mỗi từ đệm hai khoảng trắng đầu và một khoảng trắng cuối rồi lấy mọi cụm 3 ký tự.
            Trigram KÝ TỰ chứ không phải cụm 3 từ: đổi 10 % số từ rải đều làm mất ~30 % cụm 3 từ, nên "giống 90 %" theo cụm từ
            chỉ còn ~55 % — lọt ngưỡng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.Overlap(System.Collections.Generic.IReadOnlySet{System.String},System.Collections.Generic.IReadOnlySet{System.String})">
            <summary>|A ∩ B| và |A ∪ B|.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.IsDuplicate(System.Int32,System.Int32)">
            <summary>Jaccard ≥ 80 % — so bằng số nguyên (<c>giao × 100 ≥ hợp × 80</c>) để 4/5 không lệch vì dấu phẩy động.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.Fingerprint(System.Int32,System.String,System.String)">
            <summary>Dấu vân tay của một intro HTML.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.ParseFaq(System.String)">
            <summary>
            Đọc <c>FaqJson</c>: null/rỗng → danh sách rỗng; không phải mảng các object có <c>Q</c>, <c>A</c> là chuỗi
            (không phân biệt hoa thường tên khoá) → null.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.ValidateFaq(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Network.AgencyFaqItem})">
            <summary>Lỗi tiếng Việt nếu danh sách hỏi đáp sai luật; null nếu hợp lệ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.SerializeFaq(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Network.AgencyFaqItem})">
            <summary>Hỏi đáp dạng chuẩn để lưu: <c>[{"Q":"…","A":"…"}]</c> đã cắt khoảng trắng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.FaqTexts(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Network.AgencyFaqItem})">
            <summary>Các đoạn chữ của hỏi đáp: <c>Faq[i].Q</c>, <c>Faq[i].A</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.MediaTexts(System.Int32,System.String,System.String)">
            <summary>Các đoạn chữ của một ảnh lên web: <c>Media[id].AltText</c>, <c>Media[id].Caption</c> (id = 0 khi chưa lưu).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.FindPhones(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublicText})">
            <summary>Số điện thoại trong nhiều đoạn chữ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.GateErrors(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublicText})">
            <summary>Lỗi CỨNG của cổng chặn nội dung (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentGateText"/>) trên nhiều đoạn chữ; luật mềm bỏ qua.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyContentRules.GateMessage(Ladaer.BackEnd.Infrastructures.Services.ContentStore.ContentStoreIssue)">
            <summary>"[GATE_01_HOTLINE_CU] Intro (dòng 2): Hotline cũ…".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyMediaFileStore">
            <summary>
            Vị trí file ảnh hồ sơ bưu cục trên đĩa (nợ BC-14, BC-16 — plan §3.12).
            </summary>
            <remarks>
            <para><b>BC-14 — chọn "chỉ file đã duyệt nằm trong thư mục phục vụ + xoá file vật lý khi gỡ".</b> Ảnh chờ duyệt nằm ở
            thư mục riêng KHÔNG được site media phục vụ (<c>Network:PendingMediaRoot</c>, trống = <c>&lt;Media.RootPath&gt;-cho-duyet</c>,
            cùng cấp chứ không lồng bên trong gốc media); duyệt → dời sang <c>Media.RootPath</c> cùng đường dẫn tương đối; bỏ duyệt →
            dời ngược lại; gỡ ảnh → xoá file ở cả hai nơi. Lý do chọn phương án này thay vì chỉ xoá khi gỡ: ảnh Branch.Manager tải lên
            chưa ai duyệt mà đã có URL công khai thì ai cầm URL (chính họ, hoặc bất kỳ ai họ gửi) đều mở được — "chờ duyệt" chỉ là cờ
            trong DB. Portal vẫn cần xem ảnh chờ duyệt để duyệt → <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyMediaFileStore.PreviewUrl(Lada.Framework.Data.Domains.Network.AgencyMedia)"/> cấp URL qua API ký HMAC, hết hạn sau
            <see cref="!:PreviewLifetime"/>, nên SPA không phải đổi gì (vẫn đọc <c>Url</c> vào <c>&lt;img&gt;</c>).</para>
            <para><b>BC-16 — ảnh Open Graph JPEG sinh lúc ảnh vào thư mục phục vụ</b> (tải lên đã duyệt / duyệt), không lúc công bố
            hay lúc render: ảnh OG có thể đổi sau khi công bố (tab SEO chọn ảnh khác), còn website là tiến trình khác, có thể khác máy,
            không có quyền ghi thư mục media. Sinh cho mọi ảnh đã duyệt (≤ 60 ảnh/bưu cục) thì ảnh nào được chọn làm OG cũng đã có
            sẵn bản <c>{tên}-og.jpg</c> đúng quy ước <c>AgencyPublicMedia.OgUrl</c>; bỏ duyệt/gỡ thì xoá theo.</para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyMediaFileStore.PlaceNewAsync(System.String,System.Boolean)">
            <summary>
            Ảnh vừa xử lý (đang ở thư mục phục vụ): đã duyệt → sinh bản OG; chờ duyệt → dời sang thư mục chờ duyệt.
            Trả câu lỗi tiếng Việt nếu không dời được — khi đó ảnh KHÔNG được ghi nhận.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyMediaFileStore.MoveAsync(System.String,System.Boolean)">
            <summary>Đổi vị trí theo trạng thái duyệt mới. Ném khi dời lỗi — service trả lỗi trước khi ghi DB.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyMediaFileStore.DeleteAllAsync(System.String)">
            <summary>Xoá file ở cả hai nơi + bản OG. Không ném (dọn file là việc phụ, DB đã đúng).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyMediaFileStore.ResolveExistingAsync(System.String)">
            <summary>Đường dẫn tuyệt đối của file đang tồn tại (thư mục chờ duyệt trước, rồi thư mục phục vụ); null nếu không thấy.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyMediaFileStore.PreviewUrl(Lada.Framework.Data.Domains.Network.AgencyMedia)">
            <summary>URL xem trước ảnh chờ duyệt qua API, ký HMAC, hết hạn sau <see cref="!:PreviewLifetime"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyMediaFileStore.ValidatePreviewToken(Lada.Framework.Data.Domains.Network.AgencyMedia,System.String)">
            <summary>Kiểm vé xem trước: đúng ảnh, đúng bưu cục, chưa hết hạn, chữ ký khớp.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyMediaFileStore.ProcessKey">
            <summary>Khoá HMAC ngẫu nhiên theo tiến trình khi appsettings trống — vé mất hiệu lực khi API khởi động lại (portal Get lại là có vé mới).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyMediaFileStore.PendingRoot(System.String,System.String)">
            <summary>Thư mục chờ duyệt: <c>Network:PendingMediaRoot</c>, trống thì cùng cấp gốc media kèm hậu tố.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyMediaFileStore.OgPath(System.String)">
            <summary><c>{tên}.webp</c> → <c>{tên}-og.jpg</c> (quy ước của <c>ImageService.GenerateOgImageFromWebpAsync</c>).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyMediaFileStore.PathsAsync(System.String,System.Boolean)">
            <summary>
            (tuyệt đối trong thư mục phục vụ, tuyệt đối trong thư mục chờ duyệt). <c>SystemPath</c> lưu tương đối dưới
            <c>Media.RootPath</c>; đường dẫn tuyệt đối cũ (cấu hình lạ) coi như đã nằm trong thư mục phục vụ.
            </summary>
            <param name="forPlacing">true = đường ĐẶT file vào thư mục chờ duyệt / dời giữa hai nơi — kiểm hai gốc tách rời.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileErrorCodes">
            <summary>
            Mã lỗi máy của API hồ sơ bưu cục và HTTP status tương ứng (docs/plan-buu-cuc.md §3.3).
            </summary>
            <remarks>
            Tên giữ đúng đặc tả §9.2 (<c>BRANCH_NOT_FOUND</c>, <c>VERSION_CONFLICT</c>…); các mã <c>INVALID_*</c>,
            <c>FORBIDDEN</c>, <c>PROFILE_ALREADY_EXISTS</c>, <c>STAFF_NOT_FOUND</c>, <c>VALIDATION_ERROR</c> là mã thêm khi code A1
            để lỗi kiểm dữ liệu có tên máy thay vì chỉ có câu tiếng Việt.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileErrorCodes.MediaNotFound">
            <summary>Id ảnh không có trong bưu cục này (kể cả khi là ảnh của bưu cục khác — không lộ tồn tại).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileErrorCodes.VersionNotFound">
            <summary>Số phiên bản không có trong lịch sử của bưu cục này.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileErrorCodes.InvalidMedia">
            <summary>File tải lên không phải JPEG/PNG/WebP thật, quá 10 MB, quá nhiều điểm ảnh, hoặc xử lý ảnh thất bại.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileErrorCodes.InvalidSlug">
            <summary>Slug không khớp <c>^[a-z0-9-]{3,120}$</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileErrorCodes.ChangeRequestNotFound">
            <summary>Id đề xuất không có (hoặc thuộc bưu cục ngoài phạm vi — không lộ tồn tại). GĐ D.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileErrorCodes.ChangeRequestClosed">
            <summary>Đề xuất đã duyệt / từ chối / bị thay bằng đề xuất mới — kể cả khi người khác vừa xử lý cùng lúc. GĐ D.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileErrorCodes.NoChanges">
            <summary>Đề xuất không đổi gì so với hồ sơ hiện tại — không tạo đề xuất rỗng cho người duyệt. GĐ D.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileErrorCodes.ToHttpStatus(System.String)">
            <summary>HTTP status của một mã lỗi; mã lạ rơi về 400.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileResult`1">
            <summary>
            Vỏ trả lời của API hồ sơ bưu cục: kế thừa <see cref="T:Lada.Framework.DTO.BaseResult"/> (FE vẫn đọc <c>Result === 1</c>) và thêm mã
            lỗi máy để controller đổi ra 403/404/409/422 — plan §3.3 "Làm rõ khi code A1".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileResult`1.ErrorCode">
            <summary>Mã lỗi máy (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileErrorCodes"/>); null khi thành công.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileResult`1.Data">
            <summary>Dữ liệu khi thành công.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileResult`1.Fields">
            <summary>Tên nhóm trường / trường gây lỗi (FORBIDDEN_FIELD, lỗi kiểm dữ liệu).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileResult`1.Missing">
            <summary>Mã điều kiện công bố cứng còn thiếu (PUBLISH_PRECONDITION_FAILED).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileResult`1.Warnings">
            <summary>Mã điều kiện mềm chưa đạt — không chặn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileResult`1.Current">
            <summary>Bản hiện tại của hồ sơ khi VERSION_CONFLICT.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileResult`1.Notices">
            <summary>
            Câu tiếng Việt báo phần server đã tự xử lý dù thao tác thành công: HTML Intro bị lọc bớt thẻ (<c>Update</c>),
            dòng dữ liệu cũ vi phạm luật hiện hành bị bỏ qua khi khôi phục (<c>Versions/Restore</c>).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyManageOwnMode">
            <summary>Branch.Manager (<c>AgencyProfile.ManageOwn</c>) được làm gì với một nhóm trường của bưu cục mình.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyManageOwnMode.Forbidden">
            <summary>Không được sửa — 403.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyManageOwnMode.Direct">
            <summary>Sửa trực tiếp.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyManageOwnMode.Proposal">
            <summary>
            Không sửa thẳng (ghi trực tiếp vẫn 403 <c>FORBIDDEN_FIELD</c>) mà gửi đề xuất <c>ChangeRequest/Create</c>, người có
            <c>ChangeRequestReview</c> duyệt thì mới áp vào hồ sơ (GĐ D) — xem <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy.CanPropose(Lada.Framework.Data.Domains.Network.AgencyFieldGroup,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)"/>.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyManageOwnMode.UploadPending">
            <summary>
            Ảnh (GĐ A2): tải lên luôn thành chờ duyệt + sắp xếp thư viện ảnh (Gallery). Không sửa/xoá/duyệt ảnh, không sắp
            xếp vai khác — xem <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy.CanUploadMedia(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)"/>, <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy.CanReorderMedia(Lada.Framework.Data.Domains.Network.AgencyMediaRole,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)"/>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyFieldRule">
            <summary>Một dòng của bảng chính sách nhóm trường.</summary>
            <param name="Group">Nhóm trường.</param>
            <param name="WriteRoles">Role nào (một trong) được sửa trực tiếp nhóm này trong phạm vi của người đó.</param>
            <param name="ManageOwn">Quyền của Branch.Manager trên bưu cục của mình.</param>
            <param name="ViaUpdate">Nhóm ghi qua <c>POST Update</c> (true) hay qua endpoint riêng (Hours, Routes, Staff, Media, SetStatus).</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyFieldRule.#ctor(Lada.Framework.Data.Domains.Network.AgencyFieldGroup,System.Collections.Generic.IReadOnlyList{System.String},Ladaer.BackEnd.Infrastructures.Services.Network.AgencyManageOwnMode,System.Boolean)">
            <summary>Một dòng của bảng chính sách nhóm trường.</summary>
            <param name="Group">Nhóm trường.</param>
            <param name="WriteRoles">Role nào (một trong) được sửa trực tiếp nhóm này trong phạm vi của người đó.</param>
            <param name="ManageOwn">Quyền của Branch.Manager trên bưu cục của mình.</param>
            <param name="ViaUpdate">Nhóm ghi qua <c>POST Update</c> (true) hay qua endpoint riêng (Hours, Routes, Staff, Media, SetStatus).</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyFieldRule.Group">
            <summary>Nhóm trường.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyFieldRule.WriteRoles">
            <summary>Role nào (một trong) được sửa trực tiếp nhóm này trong phạm vi của người đó.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyFieldRule.ManageOwn">
            <summary>Quyền của Branch.Manager trên bưu cục của mình.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyFieldRule.ViaUpdate">
            <summary>Nhóm ghi qua <c>POST Update</c> (true) hay qua endpoint riêng (Hours, Routes, Staff, Media, SetStatus).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy">
            <summary>
            Chính sách ghi theo nhóm trường của hồ sơ bưu cục — bảng hằng đúng plan §3.4, mỗi dòng một ca test (T7).
            Server là nơi quyết định; cờ <c>Permissions.CanEditGroups</c> trả cho SPA tính từ cùng bảng này.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy.CanWrite(Lada.Framework.Data.Domains.Network.AgencyFieldGroup,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)">
            <summary>
            Người dùng (đã phân giải phạm vi) có được ghi trực tiếp nhóm trường này trên bưu cục trong phạm vi của họ không.
            Không kiểm bưu cục cụ thể — đó là việc của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope.EnsureCanAccess(System.Int32)"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy.CanUploadMedia(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)">
            <summary>Tải ảnh lên được: có quyền ghi nhóm Media, hoặc Branch.Manager ở chế độ "tải lên chờ duyệt".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy.CanSelfApproveUpload(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)">
            <summary>
            Ảnh tải lên có được tự lên web ngay không. Chỉ người phạm vi toàn mạng lưới có quyền ghi nhóm Media — người phạm
            vi Own (Branch.Manager, kể cả khi được gán thêm role Media) tải gì cũng chờ duyệt: ManageOwn là role giới hạn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy.CanReorderMedia(Lada.Framework.Data.Domains.Network.AgencyMediaRole,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)">
            <summary>Sắp xếp ảnh của vai <paramref name="role"/>: quyền ghi nhóm Media → mọi vai; Branch.Manager → chỉ Gallery.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy.CanPropose(Lada.Framework.Data.Domains.Network.AgencyFieldGroup,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)">
            <summary>
            Gửi được đề xuất sửa nhóm này (GĐ D): Branch.Manager (phạm vi Own) với nhóm ở chế độ <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyManageOwnMode.Proposal"/>
            mà KHÔNG ghi thẳng được — ai ghi thẳng được (kể cả Branch.Manager được gán thêm role của nhóm) thì dùng Lưu, không
            đi đường vòng qua người duyệt.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy.Proposable(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)">
            <summary>Các nhóm trường người dùng gửi đề xuất được — nguồn của <c>Permissions.CanProposeGroups</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy.Allowed(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)">
            <summary>Các nhóm trường người dùng được ghi — nguồn của <c>Permissions.CanEditGroups</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNaming">
            <summary>
            Tên hiển thị, tên đầy đủ và slug của hồ sơ bưu cục (đặc tả §10.3, plan §3.3 "Slug").
            </summary>
            <remarks>
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNaming.SuggestDisplayName(System.String,System.String)"/> và <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNaming.BuildSlug(System.String,System.Int32)"/> phải cho cùng kết quả với script
            <c>SeedHoSoBuuCucChoChiNhanhDangHoatDong.sql</c> — đổi luật ở một bên thì đổi cả bên kia.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNaming.BrandPrefix">
            <summary>Tiền tố thương hiệu — một nguồn với trang công khai (<see cref="F:Lada.Framework.Infrastructures.Services.Network.AgencyPublicName.BrandPrefix"/>).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNaming.BannedUnsigned">
            <summary>Cụm cấm trong tên hiển thị, so trên dạng không dấu viết thường (bắt cả khi gõ không dấu).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNaming.SlugRegex">
            <remarks>
            Pattern:<br/>
            <code>^[a-z0-9-]{3,120}$</code><br/>
            Explanation:<br/>
            <code>
            ○ Match if at the beginning of the string.<br/>
            ○ Match a character in the set [-0-9a-z] atomically at least 3 and at most 120 times.<br/>
            ○ Match if at the end of the string or if before an ending newline.<br/>
            </code>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNaming.NonSlugChars">
            <remarks>
            Pattern:<br/>
            <code>[^a-z0-9]+</code><br/>
            Explanation:<br/>
            <code>
            ○ Match a character in the set [^0-9a-z] atomically at least once.<br/>
            </code>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNaming.Spaces">
            <remarks>
            Pattern:<br/>
            <code>\\s+</code><br/>
            Explanation:<br/>
            <code>
            ○ Match a whitespace character atomically at least once.<br/>
            </code>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNaming.FullName(System.String)">
            <summary>"LADA Express – {DisplayName}".</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNaming.ReservedSlugs">
            <summary>
            Đoạn đường dẫn cố định của website dưới <c>/buu-cuc/</c> (GĐ C: <c>tinh/{slug}</c>, <c>gan-toi</c>, <c>tim</c>,
            <c>su-kien</c>) — hồ sơ mang slug này sẽ không bao giờ mở được trang chi tiết.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNaming.SuggestDisplayName(System.String,System.String)">
            <summary>
            Gợi ý tên hiển thị từ tên <c>Agency</c>: lặp bỏ tiền tố "LADA Express"/"LADA"/"Chi nhánh"/"Bưu cục"/"Trung tâm"
            (không phân biệt hoa thường) khi theo sau là khoảng trắng, "-", "–" hoặc ":"; bỏ dấu phân cách dính đầu; không
            bỏ nếu tiền tố là toàn bộ tên; rỗng thì dùng mã. "Trung tâm Hải Phòng" → "Hải Phòng".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNaming.ValidateDisplayName(System.String)">
            <summary>Lỗi tiếng Việt nếu tên hiển thị không hợp lệ; null nếu hợp lệ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNaming.BuildSlug(System.String,System.Int32)">
            <summary>
            Slug từ tên hiển thị: <c>ConvertToUnsign</c> → viết thường → mọi chuỗi ký tự ngoài [a-z0-9] thành "-" →
            tối đa 120 ký tự → cắt "-" hai đầu → ngắn hơn 3 ký tự thì <c>buu-cuc-{agencyId}</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNaming.WithSuffix(System.String,System.Int32)">
            <summary>Slug thứ n khi trùng: cắt gốc cho vừa 120 ký tự rồi thêm "-n".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNavFlags">
            <summary>
            Cờ mức trang cho SPA (rule <c>quyen-hien-thi</c>): SPA không biết role, chỉ đọc cờ <c>=== true</c>. Mỗi cờ đọc ĐÚNG bó role
            của endpoint nó gác — test <c>AgencyProfilePermissionFlagsTests</c> đối chiếu bằng reflection với <c>[Authorize(Roles)]</c>.
            </summary>
            <param name="CanSearch">Trang danh sách — <c>POST Search</c>.</param>
            <param name="CanViewDetail">Mở chi tiết một hồ sơ — <c>GET Get/{agencyId}</c>. Tách khỏi CanSearch: người chỉ có Search thấy danh sách nhưng Get trả 403.</param>
            <param name="CanCreateProfile">Nút "Tạo hồ sơ" — <c>POST CreateProfile</c> (hộp thoại đọc <c>Lookups</c>, cũng mở cho Update).</param>
            <param name="CanReport">Trang báo cáo bưu cục + menu — <c>GET Report</c> [Report, ManageOwn] (Branch.Manager xem bưu cục mình).</param>
            <param name="CanBulkExceptions">Nút "Ngoại lệ giờ hàng loạt" — <c>POST Hours/Exceptions/BulkUpsert</c> [Hours, ManageOwn].</param>
            <param name="CanSetStatus">
            Hàng động "Tạm ngưng / Mở lại" trên danh sách — <c>POST SetStatus</c> tới Paused/Published đòi role <c>SetStatus</c>
            (role <c>Close</c> mở được endpoint nhưng chỉ để đóng). <c>SmartTableResult</c> không có chỗ cho cờ từng dòng nên cờ ở mức
            trang; trạng thái nguồn không hợp lệ thì server trả <c>INVALID_TRANSITION</c> — đó là lời từ chối theo đối tượng, không
            phải theo quyền (rule <c>quyen-hien-thi</c> §Ranh giới).
            </param>
            <param name="CanOpenAgencyAdmin">
            Link "Sửa ở Quản lý chi nhánh" — màn <c>/quan-ly-chi-nhanh</c> lúc mở gọi <c>Agency/GetTree</c> rồi <c>Agency/Search</c> KHÔNG
            khai <c>boQuaChuyenHuong403</c>: thiếu một trong hai role là bị đá sang trang "không có quyền".
            </param>
            <param name="CanOpenCoverage">
            Link "Sửa vùng phủ" — màn <c>/cap-nhat-vung-phu</c> lúc mở gọi <c>AgencyLocation/GetAvailableLocationsTree</c> +
            <c>GetAgencyCoverage</c>, nút Lưu gọi <c>AddLocation</c>/<c>RemoveLocation</c>; không lời gọi nào khai
            <c>boQuaChuyenHuong403</c> — link tên "Sửa" nên cờ gác cả thao tác sửa, không chỉ phần đọc. (<c>searchCityFilter</c> gọi
            <c>Location/LoSug</c> trong <c>coverage.vue</c> là code chết — template không có ô lọc tỉnh.) Role <c>AgencyLocation.*</c>
            chưa từng seed (nợ BC-13) ⇒ hôm nay chỉ Founder thấy link.
            </param>
            <param name="CanExportReport">Nút "Xuất CSV" của trang báo cáo — <c>GET Report/Export</c> [Export, ManageOwn].</param>
            <param name="CanViewChangeRequests">
            Dải "N đề xuất chờ duyệt" + hộp thoại hàng đợi — <c>GET ChangeRequest/List</c> [ChangeRequestReview, ManageOwn]:
            người duyệt thấy mọi bưu cục, Branch.Manager thấy đề xuất của bưu cục mình (trạng thái, lý do từ chối).
            </param>
            <param name="CanReviewChangeRequests">
            Nút Duyệt / Từ chối trong hàng đợi — <c>POST ChangeRequest/Approve|Reject</c> [ChangeRequestReview]. Người phạm vi Own
            (Branch.Manager được gán thêm role duyệt) KHÔNG duyệt được — kể cả đề xuất của chính bưu cục mình (tự duyệt là
            lách đường duyệt), cùng luật <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy.CanSelfApproveUpload(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)"/>.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNavFlags.#ctor(System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
            <summary>
            Cờ mức trang cho SPA (rule <c>quyen-hien-thi</c>): SPA không biết role, chỉ đọc cờ <c>=== true</c>. Mỗi cờ đọc ĐÚNG bó role
            của endpoint nó gác — test <c>AgencyProfilePermissionFlagsTests</c> đối chiếu bằng reflection với <c>[Authorize(Roles)]</c>.
            </summary>
            <param name="CanSearch">Trang danh sách — <c>POST Search</c>.</param>
            <param name="CanViewDetail">Mở chi tiết một hồ sơ — <c>GET Get/{agencyId}</c>. Tách khỏi CanSearch: người chỉ có Search thấy danh sách nhưng Get trả 403.</param>
            <param name="CanCreateProfile">Nút "Tạo hồ sơ" — <c>POST CreateProfile</c> (hộp thoại đọc <c>Lookups</c>, cũng mở cho Update).</param>
            <param name="CanReport">Trang báo cáo bưu cục + menu — <c>GET Report</c> [Report, ManageOwn] (Branch.Manager xem bưu cục mình).</param>
            <param name="CanBulkExceptions">Nút "Ngoại lệ giờ hàng loạt" — <c>POST Hours/Exceptions/BulkUpsert</c> [Hours, ManageOwn].</param>
            <param name="CanSetStatus">
            Hàng động "Tạm ngưng / Mở lại" trên danh sách — <c>POST SetStatus</c> tới Paused/Published đòi role <c>SetStatus</c>
            (role <c>Close</c> mở được endpoint nhưng chỉ để đóng). <c>SmartTableResult</c> không có chỗ cho cờ từng dòng nên cờ ở mức
            trang; trạng thái nguồn không hợp lệ thì server trả <c>INVALID_TRANSITION</c> — đó là lời từ chối theo đối tượng, không
            phải theo quyền (rule <c>quyen-hien-thi</c> §Ranh giới).
            </param>
            <param name="CanOpenAgencyAdmin">
            Link "Sửa ở Quản lý chi nhánh" — màn <c>/quan-ly-chi-nhanh</c> lúc mở gọi <c>Agency/GetTree</c> rồi <c>Agency/Search</c> KHÔNG
            khai <c>boQuaChuyenHuong403</c>: thiếu một trong hai role là bị đá sang trang "không có quyền".
            </param>
            <param name="CanOpenCoverage">
            Link "Sửa vùng phủ" — màn <c>/cap-nhat-vung-phu</c> lúc mở gọi <c>AgencyLocation/GetAvailableLocationsTree</c> +
            <c>GetAgencyCoverage</c>, nút Lưu gọi <c>AddLocation</c>/<c>RemoveLocation</c>; không lời gọi nào khai
            <c>boQuaChuyenHuong403</c> — link tên "Sửa" nên cờ gác cả thao tác sửa, không chỉ phần đọc. (<c>searchCityFilter</c> gọi
            <c>Location/LoSug</c> trong <c>coverage.vue</c> là code chết — template không có ô lọc tỉnh.) Role <c>AgencyLocation.*</c>
            chưa từng seed (nợ BC-13) ⇒ hôm nay chỉ Founder thấy link.
            </param>
            <param name="CanExportReport">Nút "Xuất CSV" của trang báo cáo — <c>GET Report/Export</c> [Export, ManageOwn].</param>
            <param name="CanViewChangeRequests">
            Dải "N đề xuất chờ duyệt" + hộp thoại hàng đợi — <c>GET ChangeRequest/List</c> [ChangeRequestReview, ManageOwn]:
            người duyệt thấy mọi bưu cục, Branch.Manager thấy đề xuất của bưu cục mình (trạng thái, lý do từ chối).
            </param>
            <param name="CanReviewChangeRequests">
            Nút Duyệt / Từ chối trong hàng đợi — <c>POST ChangeRequest/Approve|Reject</c> [ChangeRequestReview]. Người phạm vi Own
            (Branch.Manager được gán thêm role duyệt) KHÔNG duyệt được — kể cả đề xuất của chính bưu cục mình (tự duyệt là
            lách đường duyệt), cùng luật <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy.CanSelfApproveUpload(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)"/>.
            </param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNavFlags.CanSearch">
            <summary>Trang danh sách — <c>POST Search</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNavFlags.CanViewDetail">
            <summary>Mở chi tiết một hồ sơ — <c>GET Get/{agencyId}</c>. Tách khỏi CanSearch: người chỉ có Search thấy danh sách nhưng Get trả 403.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNavFlags.CanCreateProfile">
            <summary>Nút "Tạo hồ sơ" — <c>POST CreateProfile</c> (hộp thoại đọc <c>Lookups</c>, cũng mở cho Update).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNavFlags.CanReport">
            <summary>Trang báo cáo bưu cục + menu — <c>GET Report</c> [Report, ManageOwn] (Branch.Manager xem bưu cục mình).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNavFlags.CanBulkExceptions">
            <summary>Nút "Ngoại lệ giờ hàng loạt" — <c>POST Hours/Exceptions/BulkUpsert</c> [Hours, ManageOwn].</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNavFlags.CanSetStatus">
            <summary>
            Hàng động "Tạm ngưng / Mở lại" trên danh sách — <c>POST SetStatus</c> tới Paused/Published đòi role <c>SetStatus</c>
            (role <c>Close</c> mở được endpoint nhưng chỉ để đóng). <c>SmartTableResult</c> không có chỗ cho cờ từng dòng nên cờ ở mức
            trang; trạng thái nguồn không hợp lệ thì server trả <c>INVALID_TRANSITION</c> — đó là lời từ chối theo đối tượng, không
            phải theo quyền (rule <c>quyen-hien-thi</c> §Ranh giới).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNavFlags.CanOpenAgencyAdmin">
            <summary>
            Link "Sửa ở Quản lý chi nhánh" — màn <c>/quan-ly-chi-nhanh</c> lúc mở gọi <c>Agency/GetTree</c> rồi <c>Agency/Search</c> KHÔNG
            khai <c>boQuaChuyenHuong403</c>: thiếu một trong hai role là bị đá sang trang "không có quyền".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNavFlags.CanOpenCoverage">
            <summary>
            Link "Sửa vùng phủ" — màn <c>/cap-nhat-vung-phu</c> lúc mở gọi <c>AgencyLocation/GetAvailableLocationsTree</c> +
            <c>GetAgencyCoverage</c>, nút Lưu gọi <c>AddLocation</c>/<c>RemoveLocation</c>; không lời gọi nào khai
            <c>boQuaChuyenHuong403</c> — link tên "Sửa" nên cờ gác cả thao tác sửa, không chỉ phần đọc. (<c>searchCityFilter</c> gọi
            <c>Location/LoSug</c> trong <c>coverage.vue</c> là code chết — template không có ô lọc tỉnh.) Role <c>AgencyLocation.*</c>
            chưa từng seed (nợ BC-13) ⇒ hôm nay chỉ Founder thấy link.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNavFlags.CanExportReport">
            <summary>Nút "Xuất CSV" của trang báo cáo — <c>GET Report/Export</c> [Export, ManageOwn].</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNavFlags.CanViewChangeRequests">
            <summary>
            Dải "N đề xuất chờ duyệt" + hộp thoại hàng đợi — <c>GET ChangeRequest/List</c> [ChangeRequestReview, ManageOwn]:
            người duyệt thấy mọi bưu cục, Branch.Manager thấy đề xuất của bưu cục mình (trạng thái, lý do từ chối).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileNavFlags.CanReviewChangeRequests">
            <summary>
            Nút Duyệt / Từ chối trong hàng đợi — <c>POST ChangeRequest/Approve|Reject</c> [ChangeRequestReview]. Người phạm vi Own
            (Branch.Manager được gán thêm role duyệt) KHÔNG duyệt được — kể cả đề xuất của chính bưu cục mình (tự duyệt là
            lách đường duyệt), cùng luật <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy.CanSelfApproveUpload(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)"/>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissions">
            <summary>Cờ trên một hồ sơ cụ thể — ẩn/hiện tab, ô nhập, nút trạng thái.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissions.CanEditGroups">
            <summary>Nhóm trường được ghi (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy.Allowed(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)"/>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissions.CanSetStatus">
            <summary>Đích <c>SetStatus</c> vừa có quyền vừa hợp lệ từ trạng thái hiện tại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissions.CanUploadMedia">
            <summary>Nút tải ảnh — <c>POST Media/Upload</c>. Branch.Manager: true (ảnh thành chờ duyệt).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissions.CanSelfApproveUpload">
            <summary>
            Ảnh tải lên có được chọn "lên web ngay" không — false thì FE ẩn ô chọn, ảnh nào cũng chờ duyệt.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissions.CanReorderGallery">
            <summary>
            Kéo sắp xếp thư viện ảnh (Gallery) — <c>POST Media/Reorder</c>. Sắp xếp vai khác, sửa, gỡ ảnh đòi nhóm
            <c>Media</c> trong <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissions.CanEditGroups"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissions.CanReviewChangeRequest">
            <summary>
            Duyệt / từ chối đề xuất của bưu cục này — <c>ChangeRequest/Approve|Reject</c>: role <c>ChangeRequestReview</c> VÀ phạm
            vi toàn mạng lưới (người phạm vi Own không tự duyệt đề xuất của bưu cục mình).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissions.CanProposeGroups">
            <summary>
            Nhóm trường gửi được đề xuất thay vì Lưu (GĐ D, <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileFieldPolicy.Proposable(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)"/>) — thẻ nhóm hiện
            nút "Gửi đề xuất" thay nút Lưu. Không giao với <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissions.CanEditGroups"/>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissionFlags">
            <summary>
            Tính cờ quyền bằng hàm thuần từ phạm vi đã phân giải — mỗi cờ một ca test (nợ NavPermissions 9/11 của kho nội dung).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissionFlags.Nav(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)">
            <summary>
            Cờ mức trang — mỗi cờ đọc đúng bó role <c>[Authorize(Roles)]</c> của endpoint nó gác (reflection test).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissionFlags.AgencyAdminPageRoles">
            <summary>Role mà màn <c>/quan-ly-chi-nhanh</c> cần ngay lúc mở (<c>AgencyController.GetTree</c>, <c>.Search</c>).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissionFlags.CoveragePageRoles">
            <summary>
            Role mà màn <c>/cap-nhat-vung-phu</c> cần để đọc VÀ sửa (<c>AgencyLocationController.GetAvailableLocationsTree</c>,
            <c>.GetAgencyCoverage</c>, <c>.AddLocation</c>, <c>.RemoveLocation</c>).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissionFlags.CanReview(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)">
            <summary>
            Duyệt đề xuất: role <c>ChangeRequestReview</c> + phạm vi toàn mạng lưới. Service ép cùng hàm này
            (<c>AgencyProfileService.ApproveChangeRequest</c>) — cờ và hàng rào không thể lệch nhau.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfilePermissionFlags.ForProfile(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope,Lada.Framework.Data.Domains.Network.AgencyPublishStatus)">
            <summary>Cờ trên hồ sơ đang ở <paramref name="status"/>. Người ngoài phạm vi không bao giờ tới được đây (403 trước).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileSearchFilter">
            <summary>Bộ lọc danh sách hồ sơ bưu cục, đọc từ <c>SmartTableParam.Search.PredicateObject</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileSearchFilter.ProvinceId">
            <summary>Tỉnh bộ 2 cấp — so với <c>Agency.CityId</c> (bưu cục còn địa chỉ bộ 3 cấp sẽ không khớp, nợ BC-10).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileSearchFilter.RegionId">
            <summary>Node khu vực (<c>AgencyType.Region</c>) — lọc theo con cháu trong cây <c>ParentId</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileSearchFilter.MissingPublishCondition">
            <summary>Chỉ hồ sơ còn thiếu điều kiện công bố cứng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileSearchFilter.From(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Khoá hỗ trợ: <c>globalSearch</c>, <c>provinceId</c>, <c>publishStatus</c>, <c>agencyType</c>, <c>regionId</c>,
            <c>missingPublishCondition</c>. Giá trị sai kiểu bị bỏ qua (coi như không lọc) thay vì ném.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileSearchRow">
            <summary>Dòng thô của truy vấn danh sách (trước khi gắn điều kiện công bố).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileSearchRow.ParentId">
            <summary>Cha của chi nhánh — tra khu vực bắt đầu từ đây (chi nhánh xoá mềm không có trong cây sống).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyTreeNode">
            <summary>Một node của cây chi nhánh (bảng <c>Agency</c> cỡ chục dòng — nạp cả cây vào bộ nhớ).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyServicePageRow">
            <summary>Một trang tuyến dịch vụ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyRowCount">
            <summary>Số dòng gộp theo bưu cục (xã vùng phủ, tuyến).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileQueries">
            <summary>
            Hình truy vấn EF của phân hệ hồ sơ bưu cục, tách khỏi service để test dịch SQL bằng <c>ToQueryString()</c> (T8) —
            repository giả chạy LINQ to Objects nên không bắt được lỗi dịch (memory bay-test-in-memory-khong-bat-loi-dich-ef).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileQueries.Search(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.AgencyProfile},System.Linq.IQueryable{Lada.Framework.Data.Domains.Categories.Agency},System.Linq.IQueryable{Lada.Framework.Data.Domains.Categories.Location},Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileSearchFilter,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope,System.Int32[])">
            <summary>
            Danh sách hồ sơ sau lọc — phạm vi Own ép <c>AgencyId</c> NGAY trong truy vấn, không lọc sau. <paramref name="agencies"/>
            nên gồm cả chi nhánh đã xoá mềm (<c>QueryAll</c>) để hồ sơ của chúng không biến khỏi danh sách.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileQueries.Sort(System.Linq.IQueryable{Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileSearchRow},Lada.Framework.DTO.SmartTable.Sort)">
            <summary>Sắp theo <c>Sort.Predicate</c> (không phân biệt hoa thường), mặc định tên hiển thị; luôn thêm AgencyId cho ổn định.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileQueries.CoverageCounts(System.Linq.IQueryable{Lada.Framework.Data.Domains.Categories.Location},System.Int32[])">
            <summary>Số xã bộ 2 cấp (Level 3, LevelType 2) trong vùng phủ của từng bưu cục.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileQueries.RouteCounts(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.AgencyRoute},System.Int32[])">
            <summary>Số tuyến (sống) của từng bưu cục.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileQueries.ServicePages(System.Linq.IQueryable{Lada.Framework.Data.Domains.Cms.UrlRecord},System.Linq.IQueryable{Lada.Framework.Data.Domains.Cms.Product})">
            <summary>
            Trang tuyến = <c>Product</c> có <c>UrlRecord.Slug</c> bắt đầu <c>dich-vu/</c> (cùng luật
            <c>ContentServicePageService</c>). <c>UrlRecord.ProductId</c> là <c>int?</c> nên khoá nối ép kiểu tường minh.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileQueries.NearestRegion(System.Collections.Generic.IReadOnlyDictionary{System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyTreeNode},System.Int32)">
            <summary>
            Node <c>Region</c> gần nhất đi ngược cây từ <paramref name="parentId"/> (cha của chi nhánh — không xét chính chi nhánh);
            null nếu lên tới gốc mà không gặp khu vực nào. Chống vòng như <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileQueries.Descendants(System.Collections.Generic.IEnumerable{System.ValueTuple{System.Int32,System.Int32}},System.Int32)"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileQueries.Descendants(System.Collections.Generic.IEnumerable{System.ValueTuple{System.Int32,System.Int32}},System.Int32)">
            <summary>Node gốc cùng mọi con cháu trong cây <c>ParentId</c> — chống vòng như <c>KpiAgencyScopeResolver</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileRoles">
            <summary>Tên role của miền hồ sơ bưu cục — một chỗ duy nhất, controller và policy đọc cùng hằng.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileRoles.All">
            <summary>Đủ 18 role seed ở <c>SeedRoleHoSoBuuCuc.sql</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScopeKind">
            <summary>Loại phạm vi bưu cục một người dùng được thao tác.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScopeKind.None">
            <summary>Không bưu cục nào — mọi lời gọi 403.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScopeKind.Own">
            <summary>Chỉ bưu cục của chính mình (<c>User.AgencyId</c>).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScopeKind.All">
            <summary>Mọi bưu cục.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileAccessDeniedException">
            <summary>Người dùng bị từ chối vì bưu cục nằm ngoài phạm vi — service đổi thành 403 <c>FORBIDDEN</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileWriteConflictException">
            <summary>
            Hai lần ghi cùng lúc từ một phiên bản: DB từ chối người sau (concurrency token <c>VersionNo</c> hoặc unique
            <c>(AgencyId, VersionNo)</c>) — service đổi thành 409 <c>VERSION_CONFLICT</c>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope">
            <summary>
            Phạm vi đã phân giải của một người dùng: loại phạm vi, bưu cục của họ và danh sách role (đọc từ DB).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope.OwnAgencyId">
            <summary><c>User.AgencyId</c> khi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope.Kind"/> = Own; 0 với loại khác.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope.HasRole(System.String)">
            <summary>Có role (Founder coi như có mọi role — cùng luật <c>ServerRoleAuthorizationHandler</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope.IsOwnBranchManager">
            <summary>
            Branch.Manager đúng nghĩa: <c>ManageOwn</c> VÀ phạm vi Own. Chỉ vai này được <c>ManageOwn</c> thay cho role báo cáo /
            xuất file / đọc hàng đợi (GĐ D, review): người có <c>ManageOwn</c> + <c>Update</c> mang phạm vi toàn mạng lưới — để
            <c>ManageOwn</c> thay role ở đó là cho họ đọc số và CSV của MỌI bưu cục dù chưa từng được gán <c>Report</c>/<c>Export</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope.EnsureCanAccess(System.Int32)">
            <summary>Ném <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileAccessDeniedException"/> nếu bưu cục ngoài phạm vi. Gọi ở MỌI method nhận agencyId.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope.EnsureAny">
            <summary>Ném nếu người dùng không có phạm vi nào (dùng cho lời gọi không nhận agencyId như Search/Lookups).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileScopeResolver">
            <summary>
            Dựng phạm vi bưu cục của người dùng cho phân hệ hồ sơ bưu cục (docs/plan-buu-cuc.md §3.4).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileScopeResolver.ResolveAsync(System.Int32)">
            <summary>Phạm vi của một người dùng — fail-closed: không xác định được thì <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScopeKind.None"/>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScopeResolver">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileScopeResolver" />
            <remarks>
            Luật, theo thứ tự ưu tiên:
            <list type="number">
            <item><c>Founder</c> → mọi bưu cục.</item>
            <item><c>AgencyProfile.Update</c> → mọi bưu cục (Network.Admin/Editor).</item>
            <item><c>AgencyProfile.ManageOwn</c> → chỉ <c>User.AgencyId</c>; không có AgencyId thì không gì cả. ManageOwn là role
              GIỚI HẠN: người có nó mà không có Update thì vẫn bị giới hạn kể cả khi được gán thêm role khác của miền
              (Hours, Routes, Report…) — nếu không, Branch.Manager có sẵn Search/Get sẽ đọc được mọi bưu cục (IDOR).</item>
            <item>Có bất kỳ role <c>AgencyProfile.*</c> nào khác → mọi bưu cục (người xem/báo cáo toàn mạng lưới).</item>
            <item>Còn lại → không gì cả.</item>
            </list>
            Plan §3.4 chỉ ghi ba nhánh (Update / chỉ ManageOwn / không gì); nhánh 4 là làm rõ khi code A1, ghi ở plan §3.4.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService">
            <summary>
            Ngoại lệ giờ cho nhiều bưu cục một lần — nghỉ lễ, đổi giờ cả mạng lưới (docs/plan-buu-cuc.md §3.5
            <c>Hours/Exceptions/BulkUpsert</c>, GĐ D; đặc tả §14 ca 11). Cùng luật với <c>Hours/Exceptions/Upsert</c> một ngày.
            </summary>
            <summary>
            Đề xuất–duyệt (docs/plan-buu-cuc.md §3.4 cột "đề xuất", §3.14, GĐ D): Branch.Manager không sửa thẳng các nhóm
            Geo / Content / Routes / ServiceArea / Staff mà gửi đề xuất; người có <c>ChangeRequestReview</c> (phạm vi toàn mạng
            lưới) duyệt thì đề xuất được áp vào hồ sơ qua ĐÚNG đường ghi sẵn có (<c>UpdateCoreAsync</c>, <c>SetRoutesCoreAsync</c>,
            <c>UpsertStaffCoreAsync</c>, <c>DeleteStaffCoreAsync</c>) — cùng chuẩn hoá, lọc HTML, luật số điện thoại / cổng chặn /
            trùng intro, chạy LẠI lúc duyệt vì dữ liệu có thể đã cũ — và sinh một phiên bản mới; từ chối thì hồ sơ không đổi.
            </summary>
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService" />
            <remarks>
            Chia file partial cùng thư mục: file này (đọc, sửa hồ sơ, trạng thái, giờ/tuyến/nhân sự, helper ghi),
            <c>AgencyProfileService.Media.cs</c> (ảnh), <c>AgencyProfileService.Versions.cs</c> (slug, lịch sử, khôi phục),
            <c>AgencyProfileService.ChangeRequests.cs</c> (đề xuất–duyệt, GĐ D), <c>AgencyProfileService.BulkExceptions.cs</c>
            (ngoại lệ giờ hàng loạt, GĐ D).
            </remarks>
            <summary>
            Ảnh hồ sơ bưu cục (plan §3.5 dòng Media, §3.12 "Upload") — theo mẫu <c>TruckMaintenanceMediaService</c>: kiểm phạm vi
            bưu cục → đọc magic bytes → <c>IUnifiedMediaService.ProcessImageAsync</c> (WebP, bỏ EXIF/GPS) → ghi bảng riêng miền.
            </summary>
            <remarks>
            <para>Khác mẫu có chủ đích: <see cref="T:Lada.Framework.Data.Domains.Network.AgencyMedia"/> tự giữ <c>SystemPath/Url/Width/Height</c>, không qua bảng
            <c>Media</c> dùng chung (plan §3.2); mỗi thao tác ghi qua <c>CommitAsync</c> nên có phiên bản + nhật ký như mọi nhóm
            trường khác.</para>
            <para><b>Mọi <c>mediaId</c> tra kèm <c>AgencyId</c></b> (bài học nhân sự A1): Id ảnh của bưu cục khác coi như không tồn
            tại → 404 <c>MEDIA_NOT_FOUND</c>, không lộ, không sửa chéo.</para>
            </remarks>
            <summary>Slug (plan §3.3 "Slug") và lịch sử phiên bản / khôi phục (plan §3.5 dòng Versions, T12–T13).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.MaxBulkAgencies">
            <summary>Tối đa bưu cục một lần áp (mạng lưới hôm nay 5, trần rộng cho nhượng quyền sau này).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.MaxBulkDays">
            <summary>Tối đa số ngày một lần áp (Tết dài nhất ~9 ngày; trần một tháng).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun">
            <summary>
            Một lượt ghi đi qua luồng đề xuất. <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun.DryRun"/>: chỉ kiểm dữ liệu và đo "có đổi gì" lúc GỬI đề xuất (không
            ghi gì, không kiểm khoá phiên bản — đề xuất không phải một lần ghi). Còn lại: áp đề xuất đã duyệt, chạy
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun.OnCommit"/> trong cùng transaction với phiên bản mới.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun.ChangeNote">
            <summary>Ghi chú phiên bản khi áp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun.OnCommit">
            <summary>Ghi thêm trong transaction áp (đánh dấu đề xuất đã duyệt + nhật ký); nhận hồ sơ đã tăng phiên bản.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun.Changed">
            <summary>Kết quả: đề xuất có đổi gì so với hồ sơ hiện tại không (lượt kiểm) / đã ghi (lượt áp).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun.NormalizedUpdate">
            <summary>Payload nhóm ghi qua Update sau chuẩn hoá (toạ độ làm tròn, Intro đã lọc HTML, hỏi đáp dạng chuẩn).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ChangePayload">
            <summary>
            Nội dung một đề xuất, lưu JSON ở <c>AgencyChangeRequest.PayloadJson</c> — chỉ các trường của nhóm đề xuất.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.PayloadFor(Lada.Framework.Data.Domains.Network.AgencyFieldGroup,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestCreateModel)">
            <summary>Nội dung đề xuất lấy từ model — chỉ các trường của nhóm; chữ đã cắt khoảng trắng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ApplyNormalized(Lada.Framework.Data.Domains.Network.AgencyFieldGroup,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ChangePayload,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel)">
            <summary>Lưu bản đã chuẩn hoá (Intro đã lọc HTML, toạ độ làm tròn) — người duyệt thấy đúng thứ sẽ được ghi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.RunProposalAsync(System.Int32,Lada.Framework.Data.Domains.Network.AgencyFieldGroup,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ChangePayload,System.Nullable{System.Int32},System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun)">
            <summary>Chạy nội dung đề xuất qua đường ghi của nhóm (kiểm hoặc áp tuỳ <paramref name="run"/>).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.CanReadChangeRequests(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)">
            <summary>
            Đọc được hàng đợi: người duyệt (role <c>ChangeRequestReview</c>) hoặc Branch.Manager (<c>ManageOwn</c>, phạm vi
            ép ở truy vấn). Cùng bó role với <c>[Authorize]</c> của <c>ChangeRequest/List</c> và cờ <c>CanViewChangeRequests</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.SaveReviewAsync(Lada.Framework.Data.Domains.Network.AgencyChangeRequest,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,System.String,System.Object,System.DateTimeOffset)">
            <summary>
            Lưu đề xuất đã xử lý mà không đụng hồ sơ (từ chối / đã có sẵn giá trị) + nhật ký, một transaction. Người khác vừa
            xử lý cùng lúc (concurrency token <c>Status</c>) → trả 409 <c>CHANGE_REQUEST_CLOSED</c>; thành công → null.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.IsClosedNowAsync(System.Int32)">
            <summary>Đọc lại trạng thái từ DB (không qua entity đang theo dõi) — sau một lần ghi hỏng vì ghi đồng thời.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.BuildChangeRequestItemsAsync(System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Network.AgencyChangeRequest})">
            <summary>
            Dòng hàng đợi kèm bảng so sánh. "Hiện tại" đọc từ hồ sơ ĐANG lưu (không phải lúc gửi) — người duyệt so với thứ
            sắp bị ghi đè. Một lượt nạp cho cả trang.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.SummaryOf(Lada.Framework.Data.Domains.Network.AgencyChangeRequest,System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Network.AgencyStaffDisplay})">
            <summary>Một dòng tóm tắt cho hàng đợi và thẻ nhóm ("Đổi toạ độ", "Thêm nhân sự Nguyễn Văn A"…).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ChangesOf(Lada.Framework.Data.Domains.Network.AgencyFieldGroup,Lada.Framework.Data.Domains.Network.AgencyProfile,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ChangePayload,System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Network.AgencyRoute},System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Network.AgencyStaffDisplay},System.Collections.Generic.IReadOnlyDictionary{System.Int32,System.String})">
            <summary>Bảng so sánh chữ thuần theo nhóm — FE hiện bằng nội suy văn bản (không <c>v-html</c>).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.Relay``1(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileResult{Ladaer.BackEnd.Infrastructures.DTO.Items.Network.AgencyProfileDetailItem})">
            <summary>
            Chuyển kết quả của đường ghi sang vỏ của luồng đề xuất. <b>Bỏ <c>Current</c></b> (review GĐ D): 409 của đường ghi kèm
            hồ sơ đầy đủ (số nội bộ, email, vé xem ảnh chờ duyệt) — người chỉ có role duyệt không gọi được <c>Get</c> thì cũng
            không được đọc vòng qua Approve. Hàng đợi tự nạp lại bằng <c>ChangeRequest/List</c>.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ConfigPublicEnabled">
            <summary>Cờ bật trang công khai <c>/buu-cuc</c> (migration <c>ChenCauHinhBuuCuc</c>, mặc định false — plan §3.6).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.UpdateCoreAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun)">
            <summary>
            Thân của <c>Update</c>. <paramref name="run"/> null = người gọi sửa thẳng (kiểm quyền nhóm, khoá phiên bản). Khác
            null = luồng đề xuất (GĐ D) đã tự kiểm quyền: <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun.DryRun"/> chỉ kiểm dữ liệu lúc gửi đề xuất
            (không ghi); ngược lại áp đề xuất đã duyệt — CÙNG chuẩn hoá, lọc HTML, luật số điện thoại / cổng chặn / trùng intro
            như sửa thẳng (dữ liệu có thể đã cũ từ lúc gửi), ghi kèm <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun.OnCommit"/> trong cùng transaction.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ApplyGroup(Lada.Framework.Data.Domains.Network.AgencyProfile,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel,Lada.Framework.Data.Domains.Network.AgencyFieldGroup,System.Collections.Generic.Dictionary{System.String,System.Object})">
            <summary>
            Ghi các trường của một nhóm từ <paramref name="input"/> (đã chuẩn hoá + kiểm) vào hồ sơ; trường đổi giá trị thì ghi
            vào <paramref name="changes"/> dạng <c>{ From, To }</c>. Dùng chung cho <c>Update</c> và <c>Versions/Restore</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.PrepareContent(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel,System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.Network.AgencyFieldGroup})">
            <summary>
            Chuẩn bị nhóm Content trước khi kiểm: <c>Intro</c> qua <see cref="M:Ladaer.BackEnd.Infrastructures.Services.ContentStore.IContentHtmlSanitizer.SanitizeRichText(System.String)"/>
            (cùng lớp Ganss của bài viết, chính sách chữ định dạng: giữ chữ, không thuộc tính/link/ảnh — số điện thoại không giấu
            được vào <c>href="tel:"</c>/<c>title</c>, luật số chạy trên chữ thuần mới đủ). Hồ sơ LƯU bản đã lọc, không lưu HTML
            thô. <c>FaqJson</c> hợp lệ thì ghi lại dạng chuẩn <c>[{"Q","A"}]</c> (chữ thuần — trang công khai phải encode).
            Trả câu báo nếu bộ lọc đã cắt bớt thứ gì.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.SetRoutesCoreAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyRoutesSetModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun)">
            <summary>Thân của <c>Routes/Set</c> — <paramref name="run"/> như <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.UpdateCoreAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun)"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.UpsertStaffCoreAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyStaffUpsertModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun)">
            <summary>Thân của <c>Staff/Upsert</c> — <paramref name="run"/> như <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.UpdateCoreAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun)"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.DeleteStaffCoreAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyStaffDeleteModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun)">
            <summary>Thân của <c>Staff/Delete</c> — <paramref name="run"/> như <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.UpdateCoreAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun)"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ReorderStaff(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyStaffReorderModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>
            Sắp lại thứ tự nhân sự hiển thị — một lần ghi, một phiên bản (khuôn <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ReorderMedia(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaReorderModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)"/>). Phải gửi đủ đúng tập
            nhân sự hiện có; id lạ (kể cả của bưu cục khác) → <c>STAFF_NOT_FOUND</c>, không lộ tồn tại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.Normalize(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel)">
            <summary>Bản đã chuẩn hoá của payload: chuỗi cắt khoảng trắng (rỗng → null), số điện thoại về E.164, toạ độ 6 chữ số.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ValidateUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel,System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.Network.AgencyFieldGroup},System.Int32,System.Boolean)">
            <param name="revealDuplicate">
            Câu <c>DUPLICATE_INTRO</c> có nêu tên + Id + % của hồ sơ trùng không. False cho người phạm vi Own (review GĐ D): từ
            GĐ D Branch.Manager chạy được luật trùng intro trên chữ TỰ GÕ (lượt kiểm đề xuất, không giới hạn số lần) — nêu tên/%
            là cho họ dò nội dung intro chưa công bố của bưu cục ngoài phạm vi.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.AddContentIssues(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.Issue},System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublicText})">
            <summary>Số điện thoại (<c>PHONE_IN_CONTENT</c>, đặc tả §10.3) và luật cứng cổng chặn (<c>CONTENT_GATE</c>) trên các đoạn chữ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.BuildPublishContextsAsync(System.Int32[])">
            <summary>Nạp một lượt dữ liệu điều kiện công bố cho nhiều bưu cục.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.LoadIntroCorpusAsync">
            <summary>Dấu vân tay intro của mọi hồ sơ chưa xoá — một truy vấn, tính trigram trong bộ nhớ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.CallClicks30dAsync(System.Int32[])">
            <summary>
            Lượt bấm gọi 30 ngày gần nhất tính tới hết hôm qua (giờ Việt Nam) — nguồn <c>AgencyWebEventDaily</c>; hôm nay chưa
            gộp (job 01:10). Một truy vấn cho cả trang danh sách.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.CommitAsync(Lada.Framework.Data.Domains.Network.AgencyProfile,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,System.String,System.Object,System.String,System.Boolean,System.Func{System.Threading.Tasks.Task})">
            <summary>
            Một lần ghi thành công: <c>VersionNo++</c>, (tuỳ) <c>ContentUpdatedAt</c>, ghi bảng con, lưu hồ sơ, snapshot phiên bản
            mới và nhật ký — trong MỘT transaction (plan §3.3 "Khoá lạc quan").
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.WriteVersionAsync(Lada.Framework.Data.Domains.Network.AgencyProfile,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,System.String,System.Object,System.String,System.Boolean,System.Func{System.Threading.Tasks.Task})">
            <summary>
            Phần ghi của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.CommitAsync(Lada.Framework.Data.Domains.Network.AgencyProfile,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,System.String,System.Object,System.String,System.Boolean,System.Func{System.Threading.Tasks.Task})"/> KHÔNG mở transaction — người gọi giữ transaction. Tách ra cho ngoại lệ giờ
            hàng loạt (GĐ D): nhiều hồ sơ, mỗi hồ sơ một phiên bản + nhật ký, tất cả trong MỘT transaction (áp đủ hoặc không gì).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.WithRun(System.Func{System.Threading.Tasks.Task},Lada.Framework.Data.Domains.Network.AgencyProfile,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProposalRun)">
            <summary>
            Ghép phần ghi bảng con của một thao tác với phần ghi của luồng duyệt đề xuất (đánh dấu đề xuất đã duyệt + nhật ký)
            — cả hai chạy trong transaction của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.CommitAsync(Lada.Framework.Data.Domains.Network.AgencyProfile,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,System.String,System.Object,System.String,System.Boolean,System.Func{System.Threading.Tasks.Task})"/>, sau khi <c>VersionNo</c> đã tăng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ProbeResult(System.Collections.Generic.List{System.String})">
            <summary>Kết quả lượt kiểm đề xuất: không dựng hồ sơ (không ai đọc), chỉ mang câu báo lọc HTML.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.CloneForProbe(Lada.Framework.Data.Domains.Network.AgencyProfile)">
            <summary>Bản sao các trường <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ApplyGroup(Lada.Framework.Data.Domains.Network.AgencyProfile,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel,Lada.Framework.Data.Domains.Network.AgencyFieldGroup,System.Collections.Generic.Dictionary{System.String,System.Object})"/> ghi — để lượt kiểm đề xuất đo "có đổi gì" mà không sửa entity đang theo dõi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.IsWriteConflict(System.Exception)">
            <summary>
            Lần ghi bị DB từ chối vì người khác vừa ghi cùng phiên bản: <c>DbUpdateConcurrencyException</c> (concurrency token
            <c>VersionNo</c>, <c>Repository.UpdateAsync</c> giữ nó làm inner) hoặc trùng <c>UX_AgencyProfileVersion_AgencyId_VersionNo</c>
            (<c>Repository.InsertAsync</c> chỉ giữ chuỗi lỗi nên phải dò theo tên index).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.AllocateSlugAsync(System.String,System.Int32)">
            <summary>Slug chưa bị hồ sơ khác (sống) hay lịch sử slug (kể cả dòng xoá mềm) chiếm; trùng thì thêm "-2", "-3"…</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ToVietnamDate(System.DateTime)">
            <summary>
            Ngày theo lịch Việt Nam của một giá trị <c>DateTime</c> nhận từ JSON. "2026-09-02" (Unspecified) giữ nguyên ngày;
            "2026-09-01T17:00:00Z" — cách <c>JSON.stringify</c> ghi 00:00 ngày 02/09 giờ VN — là ngày 02/09, không phải 01/09.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.MaxMediaBytes">
            <summary>Trần dung lượng một ảnh (plan §3.5). <c>[RequestSizeLimit]</c> controller chỉ chặn cả request.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.MaxMediaPixels">
            <summary>
            Trần điểm ảnh đọc từ header TRƯỚC khi giải mã: 10 MB PNG nén tốt có thể bung ra hàng tỷ điểm ảnh (bom giải nén).
            64 MP phủ ảnh chụp điện thoại ở chế độ mặc định (12–50 MP).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.MaxMediaPerAgency">
            <summary>Số ảnh tối đa một bưu cục (chưa xoá) — chặn tải lên vô hạn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.GetMediaPreviewFile(System.Int32,System.String)">
            <summary>
            File để API trả cho <c>GET Media/Preview/{mediaId}</c> (ảnh chờ duyệt không có URL công khai — BC-14). Vé ký HMAC do
            <c>Get</c> cấp cho người đã qua phạm vi bưu cục; sai vé / hết hạn / ảnh đã gỡ → null (controller 404, không lộ gì).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ValidateMediaText(Lada.Framework.Data.Domains.Network.AgencyMediaRole,System.String,System.String,System.Int32)">
            <summary>Vai, alt (bắt buộc), chú thích; số điện thoại + cổng chặn trên alt và chú thích — chữ này lên web.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.DetectImage(System.ReadOnlySpan{System.Byte})">
            <summary>Loại ảnh theo chữ ký đầu file; null nếu không phải JPEG/PNG/WebP.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.CheckImageHeader(System.Byte[],Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.DetectedImage)">
            <summary>
            Đọc header bằng Magick (không giải mã điểm ảnh): định dạng phải khớp chữ ký, kích thước khác 0 và không vượt
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.MaxMediaPixels"/>. Trả câu lỗi hoặc null.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ToStoredMediaPathAsync(System.String)">
            <summary>
            Đường dẫn lưu vào <c>AgencyMedia.SystemPath</c>: tương đối dưới AppConfig <c>Media.RootPath</c> (đổi ổ đĩa không
            phải sửa dữ liệu); nằm ngoài gốc (cấu hình lạ) thì giữ nguyên đường dẫn tuyệt đối.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.RestorableGroups">
            <summary>Nhóm trường khôi phục được — đúng tám nhóm ghi qua <c>Update</c>; trạng thái công bố thì không.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.TolerantSnapshotSerializer">
            <summary>Đọc ảnh chụp cũ: thuộc tính lạ bỏ qua, thuộc tính thiếu mang giá trị mặc định.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ChangeSlug(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileChangeSlugModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <inheritdoc />
            <remarks>
            <para>Slug mới trùng hồ sơ sống khác, hoặc trùng <c>AgencySlugHistory</c> của bưu cục KHÁC (kể cả dòng xoá mềm) →
            409 <c>SLUG_TAKEN</c>: link cũ ngoài internet đang 301 về bưu cục đó, cấp lại là đổi đích của link.</para>
            <para><b>Quay về đúng một slug cũ của CHÍNH bưu cục này: cho phép</b> (chốt A2 2026-09-17, plan §3.3) — link cũ vốn
            trỏ chính bưu cục này nên sống lại không đổi đích của link nào; cấm thì một lần gõ nhầm là mất vĩnh viễn slug đẹp.
            Dòng lịch sử của slug đó bị xoá mềm (slug đang sống không còn là "slug cũ"); đổi đi lần nữa thì dòng được dựng lại
            — không chèn dòng mới vì unique <c>OldSlug</c> không lọc xoá mềm.</para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.SlugHistoryWrites">
            <summary>Các lần ghi <c>AgencySlugHistory</c> chờ chạy trong transaction của <c>CommitAsync</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.MoveSlugToHistoryAsync(System.Int32,System.String,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,System.DateTimeOffset)">
            <summary>
            Đưa slug đang dùng vào lịch sử để 301: chưa có dòng → chèn; có dòng (kể cả xoá mềm) của chính bưu cục → dựng lại
            và đóng dấu giờ đổi mới; dòng thuộc bưu cục khác (không xảy ra nếu dữ liệu đúng bất biến) → giữ nguyên, không cướp.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.RestoreVersion(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileRestoreModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <inheritdoc />
            <remarks>
            <para>Tạo phiên bản MỚI từ nội dung phiên bản cũ (T13: đang ở 3, khôi phục 2 → phiên bản 4 = nội dung 2); lịch sử
            cũ giữ nguyên. Khôi phục: tám nhóm trường của hồ sơ, giờ tuần, ngoại lệ giờ, tuyến, nhân sự hiển thị.</para>
            <para><b>KHÔNG khôi phục</b> — có chủ đích:</para>
            <list type="bullet">
            <item><c>PublishStatus</c>, <c>PublishedAt</c>, <c>ClosedAt</c>, <c>RedirectToAgencyId</c>: trạng thái chỉ đổi qua máy
              trạng thái — khôi phục mà đưa hồ sơ về Published là lách điều kiện công bố.</item>
            <item><c>Slug</c>: chỉ đổi qua <c>ChangeSlug</c> để slug cũ vào lịch sử 301; khôi phục âm thầm đổi slug là làm gãy link.</item>
            <item>Ảnh: dòng ảnh có file vật lý và quyết định duyệt riêng — ảnh đã gỡ/bỏ duyệt có thể vì lý do nhạy cảm, khôi phục
              không được đưa nó quay lại web.</item>
            <item><c>ContentUpdatedAt</c>: là dấu thời gian hệ thống — lần khôi phục chính là một lần đổi nội dung mới.</item>
            </list>
            <para><b>Dữ liệu cũ vi phạm luật hiện hành</b> (tên có chữ "LADA", số sai đầu số, intro có số điện thoại, tuyến trỏ
            trang đã xoá, nhân sự thiếu tên…) không làm hỏng cả lượt: nhóm trường / dòng đó giữ nguyên hiện tại và có một câu
            trong <c>Notices</c>. Ảnh chụp thiếu hẳn một phần (thuộc tính hay mảng vắng mặt trong JSON cũ) → phần đó giữ nguyên
            hiện tại chứ không bị coi là "rỗng".</para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ParsedSnapshot">
            <summary>Ảnh chụp đã đọc kèm JSON gốc — để biết phần nào VẮNG MẶT (khác với "rỗng").</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ParsedSnapshot.#ctor(Newtonsoft.Json.Linq.JObject,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileSnapshot)">
            <summary>Ảnh chụp đã đọc kèm JSON gốc — để biết phần nào VẮNG MẶT (khác với "rỗng").</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.RestoreProfileFieldsAsync(Lada.Framework.Data.Domains.Network.AgencyProfile,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ParsedSnapshot,System.Int32,System.Collections.Generic.Dictionary{System.String,System.Object},System.Collections.Generic.List{System.String})">
            <summary>
            Tám nhóm trường: dựng payload như một lần <c>Update</c> từ ảnh chụp (thuộc tính vắng mặt lấy giá trị hiện tại), kiểm
            TỪNG nhóm bằng đúng <c>ValidateUpdateAsync</c>; nhóm vi phạm luật hiện hành giữ nguyên + một câu báo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.RestoreHoursAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ParsedSnapshot,System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,System.DateTimeOffset,System.Collections.Generic.Dictionary{System.String,System.Object},System.Collections.Generic.List{System.String},System.Collections.Generic.List{System.Func{System.Threading.Tasks.Task}})">
            <summary>Giờ tuần: ngày có trong ảnh chụp và hợp lệ → ghi; ngày không có → gỡ; ngày sai luật → giữ hiện tại.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.RestoreExceptionsAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ParsedSnapshot,System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,System.DateTimeOffset,System.Collections.Generic.Dictionary{System.String,System.Object},System.Collections.Generic.List{System.String},System.Collections.Generic.List{System.Func{System.Threading.Tasks.Task}})">
            <summary>Ngoại lệ giờ theo ngày: có trong ảnh chụp và hợp lệ → ghi; không có → gỡ; sai luật → giữ hiện tại.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.RestoreRoutesAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ParsedSnapshot,System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,System.DateTimeOffset,System.Collections.Generic.Dictionary{System.String,System.Object},System.Collections.Generic.List{System.String},System.Collections.Generic.List{System.Func{System.Threading.Tasks.Task}})">
            <summary>Tuyến: dòng trỏ trang không còn là trang tuyến <c>dich-vu/</c> (đã xoá, đổi slug) bị bỏ kèm câu báo.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.RestoreStaffAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileService.ParsedSnapshot,System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor,System.DateTimeOffset,System.Collections.Generic.Dictionary{System.String,System.Object},System.Collections.Generic.List{System.String},System.Collections.Generic.List{System.Func{System.Threading.Tasks.Task}})">
            <summary>
            Nhân sự hiển thị: ảnh chụp không lưu Id nên ghép theo (họ tên, chức danh) không phân biệt hoa thường — đúng khoá
            chống trùng của <c>UpsertStaff</c>. Dòng thiếu tên/chức danh hoặc có số điện thoại bị bỏ; ảnh chân dung đã gỡ → bỏ ảnh.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyChangeRequestQueries">
            <summary>
            Truy vấn hàng đợi đề xuất — hàm tĩnh trả <c>IQueryable</c> để service và test <c>ToQueryString()</c> chạy CÙNG một
            truy vấn (review GĐ D: test dựng lại tay không bắt được biểu thức không dịch được sang SQL).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyChangeRequestQueries.InScope(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.AgencyChangeRequest},System.Nullable{System.Int32},System.Nullable{System.Int32})">
            <summary>Đề xuất trong phạm vi: <paramref name="ownAgencyId"/> (phạm vi Own) ép trước, rồi lọc bưu cục nếu có.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyChangeRequestQueries.WithStatus(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.AgencyChangeRequest},System.Nullable{System.Int32})">
            <summary>Lọc trạng thái (<c>status</c> ≤ 0 = mọi trạng thái).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyChangeRequestQueries.Page(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.AgencyChangeRequest},System.Int32,System.Int32)">
            <summary>Một trang: đề xuất chờ lên đầu, rồi mới nhất trước.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService">
            <summary>
            Hồ sơ công khai của bưu cục (docs/plan-buu-cuc.md §3.3–§3.5, GĐ A1). Mọi method nhận agencyId đều ép phạm vi
            qua <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope.EnsureCanAccess(System.Int32)"/> ngay đầu hàm — không trông vào controller.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Danh sách hồ sơ trong phạm vi; phạm vi Own chỉ trả bưu cục của mình.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.Get(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Chi tiết hồ sơ + Agency lõi (chỉ đọc) + giờ + tuyến + nhân sự + điều kiện đăng + cờ quyền.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.CreateProfile(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileCreateModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Tạo hồ sơ nháp cho Agency LadaBranch/Franchise chưa có hồ sơ; sinh slug từ tên hiển thị.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileUpdateModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Sửa theo nhóm trường với khoá lạc quan.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.SetStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileSetStatusModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Công bố / tạm ngưng / đóng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.Reopen(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileReopenModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Mở lại hồ sơ đã đóng về nháp.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.UpsertHours(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyHoursUpsertModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Ghi giờ làm việc đủ 7 ngày.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.GetMediaPreviewFile(System.Int32,System.String)">
            <summary>File ảnh cho vé xem trước (BC-14); null khi vé sai/hết hạn hoặc ảnh không còn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.UpsertException(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyHourExceptionUpsertModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Thêm/sửa/gỡ ngoại lệ giờ một ngày.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.SetRoutes(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyRoutesSetModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Thay toàn bộ tuyến.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.UpsertStaff(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyStaffUpsertModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Thêm/sửa nhân sự hiển thị.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.DeleteStaff(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyStaffDeleteModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Gỡ nhân sự hiển thị.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.UploadMedia(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaUploadModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Tải một ảnh lên (JPEG/PNG/WebP thật, ≤ 10 MB). Branch.Manager tải lên thì ảnh chờ duyệt.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.UpdateMedia(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaUpdateModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Sửa vai / alt / chú thích / cờ ảnh thật / thứ tự của một ảnh.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.DeleteMedia(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaDeleteModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Gỡ một ảnh (xoá mềm) và gỡ tham chiếu Open Graph / chân dung nhân sự tới nó.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.ReorderMedia(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaReorderModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Sắp lại thứ tự ảnh của một vai. Branch.Manager chỉ sắp được thư viện ảnh.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.ApproveMedia(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyMediaApproveModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Duyệt / bỏ duyệt một ảnh.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.ChangeSlug(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileChangeSlugModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Đổi slug; slug cũ vào lịch sử cho 301.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.Versions(System.Int32,System.Int32,System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Lịch sử phiên bản (không kèm ảnh chụp), mới nhất trước.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.GetVersion(System.Int32,System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Một phiên bản kèm ảnh chụp.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.RestoreVersion(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileRestoreModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Khôi phục nội dung một phiên bản cũ thành phiên bản mới.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.Lookups(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Danh mục chọn: tỉnh bộ 2 cấp, trang tuyến, loại hàng, chi nhánh chưa có hồ sơ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.NavPermissions(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Cờ mức trang — trả cho mọi người đã đăng nhập, không gác role.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.BulkUpsertExceptions(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyHourExceptionBulkModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Ngoại lệ giờ cho nhiều bưu cục một lần (GĐ D) — mỗi bưu cục một phiên bản, tất cả một transaction.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.CreateChangeRequest(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestCreateModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Branch.Manager gửi đề xuất sửa một nhóm trường (GĐ D).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.ChangeRequests(System.Nullable{System.Int32},System.Nullable{System.Int32},System.Int32,System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Hàng đợi đề xuất trong phạm vi người gọi, kèm bảng so sánh hiện tại ↔ đề xuất.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.ApproveChangeRequest(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestApproveModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Duyệt: áp đề xuất vào hồ sơ qua đúng đường ghi sẵn có, một phiên bản mới.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyProfileService.RejectChangeRequest(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyChangeRequestRejectModel,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>Từ chối: hồ sơ không đổi, lý do trả cho Branch.Manager.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileSnapshot">
            <summary>
            Khuôn JSON của <c>AgencyProfileVersion.SnapshotJson</c> (Newtonsoft mặc định: PascalCase, enum là số).
            </summary>
            <remarks>
            Script <c>SeedHoSoBuuCucChoChiNhanhDangHoatDong.sql</c> dựng phiên bản 1 của hồ sơ seed bằng <c>FOR JSON</c> theo
            đúng khuôn này — thêm/đổi tên thuộc tính ở đây thì đổi cả script (hoặc để khôi phục GĐ A2 chịu được thuộc tính thiếu).
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileStatusMachine">
            <summary>
            Máy trạng thái công bố (đặc tả §10.2, plan §3.3) — hàm thuần, 7 chuyển hợp lệ:
            Draft→Published, Published→Paused, Paused→Published, Draft/Published/Paused→Closed (qua <c>SetStatus</c>) và
            Closed→Draft (chỉ qua <c>Reopen</c>).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileStatusMachine.CanSetStatus(Lada.Framework.Data.Domains.Network.AgencyPublishStatus,Lada.Framework.Data.Domains.Network.AgencyPublishStatus)">
            <summary>Chuyển qua <c>SetStatus</c> có hợp lệ không (không gồm Reopen).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileStatusMachine.CanReopen(Lada.Framework.Data.Domains.Network.AgencyPublishStatus)">
            <summary>Mở lại chỉ từ Closed.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileStatusMachine.TargetsFrom(Lada.Framework.Data.Domains.Network.AgencyPublishStatus)">
            <summary>Các đích <c>SetStatus</c> hợp lệ từ một trạng thái.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileValidation">
            <summary>
            Kiểm số điện thoại, toạ độ, link — dùng chung cho <c>Update</c> (chặn sớm) và điều kiện công bố (plan §3.3 #2, #3).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileValidation.MinLatitude">
            <summary>Khung lãnh thổ Việt Nam thô cho điều kiện #2.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileValidation.MaxLatitude">
            <summary>Khung lãnh thổ Việt Nam thô cho điều kiện #2.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileValidation.MinLongitude">
            <summary>Khung lãnh thổ Việt Nam thô cho điều kiện #2.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileValidation.MaxLongitude">
            <summary>Khung lãnh thổ Việt Nam thô cho điều kiện #2.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileValidation.E164Vn">
            <remarks>
            Pattern:<br/>
            <code>^\\+84[1-9]\\d{7,9}$</code><br/>
            Explanation:<br/>
            <code>
            ○ Match if at the beginning of the string.<br/>
            ○ Match the string "+84".<br/>
            ○ Match a character in the set [1-9].<br/>
            ○ Match a Unicode digit atomically at least 7 and at most 9 times.<br/>
            ○ Match if at the end of the string or if before an ending newline.<br/>
            </code>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileValidation.PhoneNoise">
            <remarks>
            Pattern:<br/>
            <code>[\\s.\\-()]</code><br/>
            Explanation:<br/>
            <code>
            ○ Match a character in the set [()-.\s].<br/>
            </code>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileValidation.EmailPattern">
            <remarks>
            Pattern:<br/>
            <code>^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$</code><br/>
            Explanation:<br/>
            <code>
            ○ Match if at the beginning of the string.<br/>
            ○ Match a character in the set [^@\s] atomically at least once.<br/>
            ○ Match '@'.<br/>
            ○ Match a character in the set [^@\s] greedily at least once.<br/>
            ○ Match '.'.<br/>
            ○ Match a character in the set [^@\s] atomically at least once.<br/>
            ○ Match if at the end of the string or if before an ending newline.<br/>
            </code>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileValidation.NormalizePhone(System.String)">
            <summary>
            Chuẩn hoá số người dùng gõ về E.164: bỏ khoảng trắng/dấu chấm/gạch/ngoặc, "0…" → "+84…", "84…" → "+84…",
            tổng đài "1900…"/"1800…" → "+841900…"/"+841800…", và bỏ số 0 gõ thừa ngay sau mã nước ("+84 0912…" → "+84912…").
            Không đoán gì thêm — kết quả vẫn phải qua <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileValidation.IsE164Vn(System.String)"/>.
            </summary>
            <remarks>
            Số 1900/1800 lưu dạng "+841900…" cho đồng nhất cột và cho luật đầu số; khi hiển thị/dựng <c>tel:</c> (GĐ C) phải
            đổi về dạng quốc nội "1900…" vì nhiều nhà mạng không gọi được tổng đài qua +84.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileValidation.IsE164Vn(System.String)">
            <summary>E.164 Việt Nam: <c>^\+84[1-9]\d{7,9}$</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileValidation.ParsePrefixes(System.String)">
            <summary>Tách danh sách đầu số AppConfig <c>Network.AllowedPhonePrefixes</c> (phẩy, chấm phẩy, khoảng trắng).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileValidation.MatchesAllowedPrefix(System.String,System.Collections.Generic.IReadOnlyList{System.String})">
            <summary>
            Đầu số có nằm trong danh sách cho phép không. Danh sách rỗng = không hạn chế. Một đầu số khớp khi số dạng quốc
            nội (<c>0…</c>) hoặc phần sau <c>+84</c> bắt đầu bằng nó — để "0225" và "1900" đều viết được tự nhiên.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileValidation.IsHttpUrl(System.String)">
            <summary>Link tuyệt đối http/https.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileVersionNotes">
            <summary>
            Ghi chú mặc định của một phiên bản hồ sơ khi người sửa không ghi gì. Ghi chú hiện NGUYÊN VĂN ở lịch sử phiên bản
            trên portal — trước bấm thật B2 nó là tên thao tác nội bộ (<c>UpsertHours</c>, <c>ReorderStaff</c>…). Tên thao tác
            tiếng Anh vẫn đi vào nhật ký (<c>AgencyProfileAuditLog.Action</c>) cho máy đọc; ở đây chỉ là chữ cho người đọc.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileVersionNotes.KnownActions">
            <summary>Mọi tên thao tác đã có nhãn — test đối chiếu với các lời gọi <c>CommitAsync</c> trong service.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileVersionNotes.Default(System.String)">
            <summary>Nhãn tiếng Việt của thao tác; thao tác chưa có nhãn thì trả lại chính tên (không nuốt thông tin).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileVersionNotes.ForUpdate(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Network.AgencyFieldGroup})">
            <summary>"Sửa: Liên hệ; Toạ độ" — nhãn nhóm lấy từ <c>[Description]</c> của enum (cùng nguồn với <c>Lookups.FieldGroups</c>).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileVersionNotes.ForStatus(Lada.Framework.Data.Domains.Network.AgencyPublishStatus)">
            <summary>"Chuyển sang «Tạm ngưng»".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishContext">
            <summary>Dữ liệu đã nạp sẵn để chạy điều kiện công bố của một hồ sơ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishContext.Agency">
            <summary>Agency lõi (đã lọc xoá mềm) — null nếu đã xoá.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishContext.City">
            <summary><c>Location</c> mà <c>Agency.CityId</c> trỏ tới (null nếu không có hoặc đã xoá).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishContext.Ward">
            <summary><c>Location</c> mà <c>Agency.WardId</c> trỏ tới.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishContext.CoverageWardCount">
            <summary>Số xã bộ 2 cấp thuộc vùng phủ (<c>Location.AgencyId</c>, Level 3, LevelType 2).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishContext.AllowedPhonePrefixes">
            <summary>AppConfig <c>Network.AllowedPhonePrefixes</c> đã tách; rỗng = không hạn chế.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishContext.Media">
            <summary>Mọi ảnh chưa xoá của bưu cục — cả ảnh chờ duyệt; điều kiện tự lọc <see cref="M:Lada.Framework.Infrastructures.Services.Network.AgencyPublicMedia.IsPublic(Lada.Framework.Data.Domains.Network.AgencyMedia)"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishContext.IntroCorpus">
            <summary>Intro của mọi hồ sơ (kể cả chính nó) — nạp một lần cho cả lượt, dùng cho <c>DUPLICATE_INTRO</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishIssue">
            <summary>Một điều kiện chưa đạt.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishIssue.Code">
            <summary>Mã máy — tên trường/khối để tab SEO trỏ tới (vd <c>Latitude</c>, <c>Hours</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishIssue.Message">
            <summary>Câu tiếng Việt cho người dùng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishIssue.Blocking">
            <summary>true = điều kiện cứng, chặn công bố.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishIssue.Field">
            <summary>Trường chứa lỗi khi mã là lỗi nội dung (<c>Intro</c>, <c>Faq[1].A</c>, <c>Media[12].Caption</c>…); null nếu không áp dụng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishIssue.Position">
            <summary>Vị trí trong trường ("dòng 2, ký tự 15"); null nếu không áp dụng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishIssue.Rule">
            <summary>Mã luật cổng chặn (<c>GATE_01_HOTLINE_CU</c>…) khi mã là <c>CONTENT_GATE</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishIssue.RelatedAgencyId">
            <summary>Bưu cục có intro trùng khi mã là <c>DUPLICATE_INTRO</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishCheck">
            <summary>Kết quả "Kiểm tra điều kiện đăng".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishCheck.Add(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishIssue)">
            <summary>Thêm một issue dựng sẵn (lỗi nội dung có trường/vị trí/luật).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyPublishPrecondition">
            <summary>
            Một nhóm điều kiện công bố. Service nhận <c>IEnumerable</c> các điều kiện qua DI — GĐ A2 thêm #5 (ảnh), #6 (intro),
            #10 (cổng chặn nội dung) bằng cách đăng ký thêm lớp, không sửa hàm công bố.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyCorePublishPreconditions">
            <summary>
            Điều kiện công bố làm được ở GĐ A1: #1 (Agency + địa chỉ bộ 2 cấp + tên hiển thị), #2 (toạ độ), #3 (số chính),
            #4 (≥ 5 ngày có giờ), #7 (vùng phủ), #8 mềm (tuyến), #9 mềm (độ dài meta). Plan §3.3.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyCorePublishPreconditions.IsTwoLevelAddress(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyPublishContext)">
            <summary>
            Tỉnh là <c>Location</c> sống Level 1 LevelType 2; xã là <c>Location</c> sống Level 3 LevelType 2 thuộc đúng tỉnh đó.
            Bộ 2 cấp không có Level 2 và <c>ParentId</c> của xã trỏ thẳng tỉnh (Việc 0 Đ6).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyReportCsv">
            <summary>
            Dựng CSV cho báo cáo bưu cục (GĐ D) — repo chưa có tiền lệ CSV server-side (Việc 0 D3). Excel đọc đúng tiếng Việt nhờ
            BOM UTF-8; ô chữ theo RFC 4180, luôn bọc nháy kép (nháy bên trong nhân đôi); ô số ghi thẳng.
            </summary>
            <remarks>
            <b>Chống CSV/formula injection</b>: nguồn truy cập (<c>utm_source</c>, host referrer) và đường dẫn trang của
            <c>AgencyWebEvent</c> là chữ TỰ DO do trình duyệt khách gửi. Ô chữ bắt đầu bằng <c>=</c> <c>+</c> <c>-</c> <c>@</c>, tab
            hay CR bị Excel/LibreOffice hiểu là công thức (<c>=HYPERLINK(...)</c>, <c>=cmd|...</c>) ⇒ thêm dấu <c>'</c> ở đầu (khuyến
            nghị OWASP). Áp cho MỌI ô chữ, kể cả tên bưu cục — một hàm duy nhất, không phân biệt nguồn "tin được". Ô số ghi thẳng.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyReportCsv.Text(System.String)">
            <summary>
            Một ô chữ đã chống công thức + thoát theo RFC 4180. <b>Luôn bọc nháy kép</b> (review GĐ D): máy đặt dấu phân cách
            danh sách là <c>;</c> (vùng de/fr… hoặc tự chỉnh) mở CSV thì Excel tách ô tại <c>;</c> — ô không bọc nháy
            <c>x;=cmd|…</c> thành ô mới bắt đầu bằng <c>=</c>. Trong nháy kép, mọi dấu phân cách là chữ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyReportCsv.Number(System.Int32)">
            <summary>Một ô số (không bao giờ bị hiểu là công thức — chỉ chữ số).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyReportCsv.Build(System.Collections.Generic.IEnumerable{System.Collections.Generic.IEnumerable{System.String}})">
            <summary>Ghép các dòng (mỗi dòng là các ô ĐÃ thoát) thành file CSV UTF-8 có BOM, xuống dòng CRLF.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyWebEventSource">
            <summary>
            Nguồn đọc hai bảng sự kiện trang bưu cục. Hai bảng cố ý không kế thừa <c>BaseEntity</c> (bảng ghi thô / số dẫn xuất)
            nên không có <c>IRepository&lt;T&gt;</c> (<c>Repository&lt;T&gt; where T : BaseEntity</c>) — lớp mỏng này cho service đọc
            qua <see cref="T:Lada.Framework.Data.Mappings.DbContexts.LadaDbContext"/> mà test vẫn thay được bằng dữ liệu bộ nhớ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyWebEventSource.Events">
            <summary>Sự kiện thô (giữ 13 tháng).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyWebEventSource.Daily">
            <summary>Số gộp theo ngày (job <c>network-gop-su-kien-ngay</c>).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventSource">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyWebEventSource" />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventCountRow">
            <summary>Số sự kiện của một bưu cục × một loại trong một khoảng thời gian.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebSessionRow">
            <summary>Một phiên (<c>SessionHash</c>) có sự kiện loại <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebSessionRow.EventType"/> — thời điểm đầu tiên để biết ngày.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebSourceSessionRow">
            <summary>Số sự kiện theo nguồn × loại × phiên — gom nhãn nguồn ở C# mà vẫn đếm phiên khác nhau đúng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventKeyRow">
            <summary>Số sự kiện theo một khoá chữ (nguồn truy cập / đường dẫn trang) × loại.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries">
            <summary>
            Truy vấn và quy ước ngày của số đo trang bưu cục (GĐ D). Hàm tĩnh trả <c>IQueryable</c> để test hình SQL bằng
            <c>ToQueryString()</c> (bẫy "test bộ nhớ không bắt lỗi dịch EF").
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.AggregateWindowDays">
            <summary>Số ngày job gộp tính lại mỗi lần chạy: hôm qua + 2 ngày trước (phòng lần chạy bị lỡ vì máy chủ tắt).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.RawRetentionMonths">
            <summary>Giữ sự kiện thô bấy nhiêu tháng (plan §3.2).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.TodayVn(System.DateTimeOffset)">
            <summary>Ngày hiện tại theo giờ Việt Nam.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.DayRange(System.DateTime)">
            <summary>
            Khoảng <c>[00:00, 00:00 hôm sau)</c> giờ Việt Nam của một ngày. <c>AgencyWebEvent.CreatedAt</c> là
            <c>DateTimeOffset.Now</c> của máy chủ web (Việc 0 D2) — so <c>datetimeoffset</c> trên SQL Server là so thời điểm
            tuyệt đối nên đúng với mọi offset đã lưu; <c>CAST(CreatedAt AS date)</c> thì lấy ngày theo offset LƯU, sai khi
            máy chủ không chạy giờ Việt Nam.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.RawCutoff(System.DateTimeOffset)">
            <summary>
            Mốc cắt giữ sự kiện thô: 00:00 giờ Việt Nam của ngày cách hôm nay <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.RawRetentionMonths"/> tháng — job dọn
            xoá mọi sự kiện trước mốc; báo cáo tháng bắt đầu trước mốc thì không còn bảng nguồn truy cập / trang.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.Counts(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.AgencyWebEvent},System.DateTimeOffset,System.DateTimeOffset)">
            <summary>Đếm lượt + phiên theo bưu cục × loại trong <c>[from, to)</c> — nguồn của một ngày <c>AgencyWebEventDaily</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.CallClicks(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.AgencyWebEventDaily},System.Int32[],System.DateTime,System.DateTime)">
            <summary>
            Lượt bấm gọi theo bưu cục trong các ngày <c>[fromDate, toDate]</c> (cột "Gọi 30n" của danh sách portal).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.DailyRows(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.AgencyWebEventDaily},System.Int32[],System.DateTime,System.DateTime)">
            <summary>Dòng gộp ngày của các bưu cục trong <c>[fromDate, toDate]</c> — nguồn chính của báo cáo.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.BySourceSession(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.AgencyWebEvent},System.Int32[],System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Đếm theo <c>SourceJson</c> nguyên chuỗi × loại × phiên; gom thành nhãn nguồn ở C# (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.SourceLabel(System.String)"/>, SQL
            Server của repo không dùng hàm JSON). Giữ phiên trong khoá để phiên khác nhau của MỘT nhãn đếm đúng khi nhiều chuỗi
            JSON ra cùng nhãn (cùng <c>utm_source</c>, khác <c>utm_campaign</c>/referrer) — cộng COUNT DISTINCT từng chuỗi là
            đếm lặp (review GĐ D).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.Sessions(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.AgencyWebEvent},System.Int32[],System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Mỗi (loại, phiên) một dòng kèm thời điểm đầu — số phiên khác nhau trên CẢ phạm vi (không cộng theo bưu cục: một khách
            xem 2 bưu cục là 1 phiên). Hash phiên có ngày giờ VN trong công thức nên mọi sự kiện của một hash cùng một ngày.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.ByPage(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.AgencyWebEvent},System.Int32[],System.DateTimeOffset,System.DateTimeOffset)">
            <summary>Đếm theo đường dẫn trang × loại.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.SourceLabel(System.String)">
            <summary>
            Nhãn nguồn của một <c>SourceJson</c> (<c>{"referrer": host, "utm_source": …}</c> do website ghi):
            <c>utm_source</c> nếu có, không thì host referrer, không thì "(trực tiếp)". Chữ do trình duyệt khách gửi — người hiển
            thị phải mã hoá (portal nội suy văn bản, CSV qua <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyReportCsv"/>).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebEventQueries.DirectSource">
            <summary>Nhãn cho sự kiện không mang utm lẫn referrer.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebReportFile">
            <summary>File báo cáo đã dựng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyWebReportService">
            <summary>
            Báo cáo bưu cục theo tháng (docs/plan-buu-cuc.md §3.5 <c>Report</c>, <c>Report/Export</c>, GĐ D; đặc tả §6.4): lượt +
            phiên theo bưu cục × loại sự kiện từ <c>AgencyWebEventDaily</c>; nguồn truy cập / trang từ sự kiện thô. Phạm vi ép ở
            câu truy vấn — Branch.Manager chỉ có bưu cục của mình, kể cả khi xuất file.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyWebReportService.Export(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyWebReportQuery,System.String,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.AgencyProfileActor)">
            <summary>CSV của một bảng: <c>agencies</c> (mặc định), <c>daily</c>, <c>sources</c>, <c>pages</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebReportService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IAgencyWebReportService" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebReportService.TopBreakdown">
            <summary>Số dòng tối đa của bảng nguồn truy cập / trang.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebReportService.CanReport(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)">
            <summary>
            Xem báo cáo: role <c>Report</c>, hoặc Branch.Manager phạm vi Own (ép về bưu cục mình). <c>ManageOwn</c> không thay
            role ở phạm vi toàn mạng lưới (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope.IsOwnBranchManager"/>).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebReportService.CanExport(Ladaer.BackEnd.Infrastructures.Services.Network.AgencyProfileScope)">
            <summary>Xuất file: role <c>Export</c>, hoặc Branch.Manager phạm vi Own (ép về bưu cục mình).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebReportService.TryParseMonth(System.String,System.DateTimeOffset,System.DateTime@)">
            <summary>Tháng <c>yyyy-MM</c> → ngày đầu tháng; trống = tháng hiện tại giờ Việt Nam.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebReportService.Top(System.Collections.Generic.IEnumerable{System.ValueTuple{System.String,Lada.Framework.Data.Domains.Network.AgencyWebEventType,System.String,System.Int32}})">
            <summary>
            Top nguồn: gom các chuỗi <c>SourceJson</c> ra cùng nhãn; lượt cộng, phiên đếm hash KHÁC NHAU của nhãn (không cộng
            số phiên từng chuỗi — một phiên có thể mang hai chuỗi cùng nhãn).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.AgencyWebReportService.TopDistinct(System.Collections.Generic.IEnumerable{System.ValueTuple{System.String,Lada.Framework.Data.Domains.Network.AgencyWebEventType,System.Int32,System.Int32}})">
            <summary>Top trang: mỗi đường dẫn là một nhãn riêng nên COUNT DISTINCT của SQL đã đúng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseAdminNavPermissions">
            <summary>
            Trang "Quản trị nhượng quyền" (<c>/mang-luoi/quan-tri-nhuong-quyen</c>) gộp bốn màn cũ thành bốn tab: Bảng giá ·
            Quản trị bảng giá · Nội dung cổng · Trợ lý AI. Chủ dự án 2026-10-23: "Trang mới chỉ có quản lý mạng lưới hoặc
            founder mới được xem".
            </summary>
            <remarks>
            "Quản lý mạng lưới" là một NHÓM quyền (bó role, <c>SeedNhomQuyenQuanLyMangLuoi.sql</c>), không phải role — máy chủ chỉ
            đọc role phẳng. Role phân biệt nhóm đó với "Mạng lưới 2" là <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseAdminNavPermissions.Manager"/>: GĐ L rút nó khỏi "Mạng lưới 2"
            (<c>RutQuyenQuanLyKhoiNhomMangLuoi2.sql</c>), trong khi "Mạng lưới 2" vẫn giữ <c>FranchisePrice.Manage</c> và
            <c>FranchisePortal.Content</c> — gác bằng role của từng tab là để lọt đúng nhóm phải chặn.
            <para>
            Cờ của từng tab = cờ trang AND cờ sẵn có của màn cũ (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavPermissions"/>,
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalNavPermissions.ResolveContent(System.Collections.Generic.IReadOnlyCollection{System.String})"/>) — một luật sống ở một chỗ. Đây là hàng rào HIỂN THỊ (menu +
            trang); <c>[Authorize]</c> của các API bên dưới giữ nguyên.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseAdminNavPermissions.Founder">
            <summary>Vai bỏ qua mọi kiểm tra role của hệ thống — ẩn trang của Founder là dựng hàng rào không có thật.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseAdminNavPermissions.Manager">
            <summary>Role chỉ nhóm "Quản lý mạng lưới" có — vào được trang.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseAdminNavPermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c>; <c>null</c> = không có role nào</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseAdminNavFlags">
            <summary>Cờ hiển thị của trang "Quản trị nhượng quyền"; <c>CanView = false</c> thì mọi cờ con đều tắt.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseAdminNavFlags.#ctor(System.Boolean,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavFlags,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalContentNavFlags)">
            <summary>Cờ hiển thị của trang "Quản trị nhượng quyền"; <c>CanView = false</c> thì mọi cờ con đều tắt.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseBusinessPlanService">
            <summary>
            Màn tham số mục "Kế hoạch kinh doanh" của cổng nhượng quyền <c>/mang-luoi/bang-gia-nhuong-quyen/ke-hoach</c> (GĐ M,
            plan cổng §3.13, §6.24): xem + tính thử (<c>FranchisePrice.Export</c> / <c>Manage</c>), sửa cả bộ (<c>Manage</c>).
            Không thêm / xoá bậc — năm dòng bậc và một dòng tham số seed bằng migration.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseBusinessPlanService.GetAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceActor)">
            <summary>Cả bộ tham số; null = không có quyền xem.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseBusinessPlanService.PreviewAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseBusinessPlanPreviewModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceActor)">
            <summary>
            Tính thử với số phường mỗi bậc do người dùng gõ + tham số đang sửa (chưa lưu). Không ghi gì, không đọc phường của
            bất kỳ mã truy cập nào.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseBusinessPlanService.Stamp(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Network.FranchiseTierVolume},Lada.Framework.Data.Domains.Network.FranchiseBusinessPlanSetting)">
            <summary>Dấu phiên bản của cả bộ — đổi khi bất kỳ bậc nào hay dòng tham số được lưu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseBusinessPlanService.Apply(Lada.Framework.Data.Domains.Network.FranchiseTierVolume,Lada.Framework.Data.Domains.Network.FranchiseTierVolume)">
            <summary>Chép bản nháp vào dòng thật; true = có ô đổi.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklogBucket">
            <summary>Một cột thời gian chờ: số ngày kể từ lần cập nhật gần nhất nằm trong [<c>MinDays</c>, <c>MaxDays</c>].</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklogBucket.#ctor(System.String,System.String,System.Int32,System.Nullable{System.Int32})">
            <summary>Một cột thời gian chờ: số ngày kể từ lần cập nhật gần nhất nằm trong [<c>MinDays</c>, <c>MaxDays</c>].</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklogRow">
            <summary>Một đăng ký rút gọn cho báo cáo — <c>LastActivity</c> = <c>UpdatedTime ?? CreatedTime</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklogRow.#ctor(Lada.Framework.Data.Domains.Network.FranchiseLeadStatus,System.String,System.String,System.Nullable{System.DateTimeOffset})">
            <summary>Một đăng ký rút gọn cho báo cáo — <c>LastActivity</c> = <c>UpdatedTime ?? CreatedTime</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog">
            <summary>
            Báo cáo tồn đọng đăng ký nhượng quyền (<c>POST api/FranchiseLead/backlog</c>) — hàm thuần, theo khuôn backlog đơn
            hàng nhưng nhóm theo tỉnh đăng ký thay cho bưu cục.
            <list type="bullet">
            <item><b>Thời gian chờ</b> = số NGÀY LỊCH (giờ Việt Nam) từ lần cập nhật gần nhất (<c>UpdatedTime</c>: đổi trạng
            thái, ghi chú, sửa, giao người, cổng tự đổi trạng thái; chưa có thì <c>CreatedTime</c>) tới hôm nay.</item>
            <item><b>Đang xử lý</b> = mọi trạng thái trừ Đã ký hợp đồng và Không phù hợp — chỉ chúng có thời gian chờ; bảng theo
            tỉnh vẫn đếm cả hai trạng thái đã đóng.</item>
            </list>
            Bấm vào ô thì giao diện gọi <c>search</c> với đúng khoá của ô (<c>status</c>, <c>provinceCode</c>,
            <c>idleMinDays</c>/<c>idleMaxDays</c>, <c>openOnly</c>) — các khoá đó lọc bằng <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.WhereIdle(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},System.Nullable{System.Int32},System.Nullable{System.Int32},System.DateTimeOffset)"/>,
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.WhereProvince(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},System.String)"/>, <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.IsOpen(Lada.Framework.Data.Domains.Network.FranchiseLeadStatus)"/> ở đây, nên số trong ô và số dòng danh sách là một phép đếm.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.NoProvinceCode">
            <summary>Khoá lọc của đăng ký không có mã tỉnh (dữ liệu chuyển từ bảng <c>Lead</c> cũ).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.Buckets">
            <summary>Đăng ký nhượng quyền đi chậm hơn đơn hàng: ba ngày đầu tách riêng, sau đó gộp theo tuần / nửa tháng / tháng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.IsOpen(Lada.Framework.Data.Domains.Network.FranchiseLeadStatus)">
            <summary>Trạng thái còn phải xử lý — mọi trạng thái trừ hai trạng thái sale đã chốt xong.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.ProvinceKey(System.String)">
            <summary>Khoá tỉnh của một đăng ký: mã rỗng gộp vào <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.NoProvinceCode"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.DaysAgo(System.Nullable{System.DateTimeOffset},System.DateTimeOffset)">
            <summary>Số ngày lịch (giờ Việt Nam) từ <paramref name="lastActivity"/> tới hôm nay; mốc tương lai tính 0, không có mốc tính là cũ nhất.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.BucketIndex(System.Int32)">
            <summary>Vị trí cột của một số ngày chờ trong <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.Buckets"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.WhereIdle(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},System.Nullable{System.Int32},System.Nullable{System.Int32},System.DateTimeOffset)">
            <summary>
            Lọc đăng ký có số ngày chờ trong [<paramref name="minDays"/>, <paramref name="maxDays"/>] — cùng phép tính với
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.DaysAgo(System.Nullable{System.DateTimeOffset},System.DateTimeOffset)"/>, dịch ra mốc giờ để SQL so được:
            ngày chờ ≥ a ⇔ mốc &lt; đầu ngày (hôm nay − a + 1); ngày chờ ≤ b ⇔ mốc ≥ đầu ngày (hôm nay − b).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.WhereProvince(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},System.String)">
            <summary>Lọc theo khoá tỉnh của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.ProvinceKey(System.String)"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.WhereOpen(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead})">
            <summary>Lọc các trạng thái đang xử lý (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.IsOpen(Lada.Framework.Data.Domains.Network.FranchiseLeadStatus)"/>).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.Rows(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead})">
            <summary>Phép chiếu đọc từ DB — chỉ bốn cột cần cho hai bảng, không kéo dữ liệu cá nhân của đăng ký về.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.ProvinceRank(System.String)">
            <summary>Tỉnh trong vùng phủ trước, rồi "Tỉnh, thành khác", cuối cùng là đăng ký không có tỉnh.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.ProvinceName(System.String,System.Collections.Generic.IEnumerable{System.String})">
            <summary>Tên theo danh mục nếu có; không thì tên người gửi thấy lúc chọn (lấy tên gặp nhiều nhất), cuối cùng là mã.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadExcelBuilder">
            <summary>
            File Excel của nút Xuất ở màn "Đăng ký nhượng quyền". Hàm thuần: nhận dòng đã lọc theo phạm vi, trả byte —
            mọi ô ghi dạng giá trị (không công thức), nên chuỗi người gửi bắt đầu bằng <c>=</c> không thành công thức.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadExcelBuilder.Build(System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Network.FranchiseLead},System.Collections.Generic.IReadOnlyDictionary{System.Int32,System.DateTimeOffset})">
            <param name="rows">Dòng đã lọc theo phạm vi, đúng thứ tự xuất.</param>
            <param name="portalLastSeen">
            Lần khách vào xem cổng gần nhất theo <c>FranchiseLead.Id</c> (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadPortalVisits.LastSeenByLeadAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32})"/>);
            đăng ký không có trong đây = khách chưa vào cổng, ô để trống. <c>null</c> = để trống cả cột.
            </param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadNavPermissions">
            <summary>
            Màn "Đăng ký nhượng quyền": nút nào được hiện (rule <c>quyen-hien-thi</c>) và mỗi người thấy những đăng ký nào.
            Hàm thuần cùng khuôn <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavPermissions"/>: nhận role đã phân giải qua
            <c>IUserRoleResolver</c> — để luật "ai thấy gì" có ca test gọi thẳng vào nó.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadNavPermissions.Founder">
            <summary>Vai bỏ qua mọi kiểm tra role của hệ thống — ẩn nút của Founder là dựng hàng rào không có thật.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadNavPermissions.Search">
            <summary>
            Role xem/sửa/đổi trạng thái đăng ký MÌNH phụ trách và nhập tay đăng ký mới: <c>search</c>, <c>{id}</c>,
            <c>{id}/history</c>, <c>update-status</c>, <c>create</c>, <c>update</c>.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadNavPermissions.Manage">
            <summary>Role quản lý: thấy tất cả + <c>assign</c>, <c>assignees</c>, <c>export</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadNavPermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c>; <c>null</c> = không có role nào</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadNavPermissions.ApplyScope(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},System.Collections.Generic.IReadOnlyCollection{System.String},System.Int32)">
            <summary>
            Phạm vi dữ liệu — MỘT hàm cho Search, GetById, GetHistory, Update, UpdateStatus và Export: Manage/Founder thấy tất cả; chỉ có
            Search thì chỉ thấy đăng ký mình phụ trách (<c>PicId</c> = mình); không role thì không thấy gì.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadNavFlags">
            <summary>Cờ hiển thị của màn "Đăng ký nhượng quyền".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadNavFlags.#ctor(System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
            <summary>Cờ hiển thị của màn "Đăng ký nhượng quyền".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadSearchFilter">
            <summary>
            Bộ lọc màn "Đăng ký nhượng quyền", đọc từ <c>Search.PredicateObject</c>. Khoá (không phân biệt hoa thường):
            <list type="bullet">
            <item><c>globalSearch</c> — <c>NQ000123</c> tìm theo mã (cả mã cũ theo <c>LegacyLeadId</c> của dòng chuyển từ
            <c>Lead</c>); toàn chữ số tìm trong SĐT; còn lại tìm họ tên, SĐT, khu vực.</item>
            <item><c>status</c> — số của <see cref="T:Lada.Framework.Data.Domains.Network.FranchiseLeadStatus"/>.</item>
            <item><c>provinceCode</c> — <c>Location.Code</c>, <c>khac</c>, hoặc <c>chua-ro</c> (đăng ký không có mã tỉnh — ô của báo
            cáo tồn đọng, <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.NoProvinceCode"/>).</item>
            <item><c>picId</c> — người phụ trách; <c>0</c> = chưa giao.</item>
            <item><c>channel</c> — số của <see cref="T:Lada.Framework.Data.Domains.Network.FranchiseLeadChannel"/>.</item>
            <item><c>fromDate</c>, <c>toDate</c> — ngày gửi, tính theo giờ Việt Nam, gồm cả hai đầu. Nhận <c>yyyy-MM-dd</c>
            hoặc chuỗi ISO có giờ (<c>...Z</c>, <c>...+07:00</c> — kiểu <c>JSON.stringify(Date)</c>): quy về ngày theo giờ Việt Nam.</item>
            <item><c>updatedFromDate</c>, <c>updatedToDate</c> — ngày cập nhật gần nhất (<c>UpdatedTime</c>: đổi trạng thái, ghi
            chú, sửa thông tin, giao người, hoặc cổng tự đổi trạng thái), cùng cách đọc với <c>fromDate</c>/<c>toDate</c>.</item>
            <item><c>portalSeenFromDate</c>, <c>portalSeenToDate</c> — ngày khách vào xem Cổng nhượng quyền gần nhất
            (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadPortalVisits"/>), cùng cách đọc; đăng ký khách chưa vào cổng không bao giờ khớp. Cần
            <c>portal</c> ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadSearchFilter.Apply(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},System.Nullable{System.DateTimeOffset},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadPortalVisits)"/>.</item>
            <item><c>idleMinDays</c>, <c>idleMaxDays</c> — số ngày chờ kể từ lần cập nhật gần nhất, gồm cả hai đầu
            (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.WhereIdle(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},System.Nullable{System.Int32},System.Nullable{System.Int32},System.DateTimeOffset)"/>) — cột của báo cáo tồn đọng gửi lại nguyên văn.</item>
            <item><c>openOnly</c> — <c>true</c> = chỉ trạng thái đang xử lý (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog.IsOpen(Lada.Framework.Data.Domains.Network.FranchiseLeadStatus)"/>).</item>
            <item><c>appointmentFromDate</c>, <c>appointmentToDate</c> — ngày hẹn gặp / khảo sát (<c>AppointmentAt</c>, plan cổng
            §6.29), cùng cách đọc với <c>fromDate</c>/<c>toDate</c>; đăng ký chưa từng ghi lịch không bao giờ khớp. Không lọc trạng
            thái: lịch của đăng ký đã sang Đã ký / Không phù hợp vẫn hiện để biết cuộc hẹn dẫn tới đâu.</item>
            <item><c>appointmentOverdue</c> — <c>true</c> = đang "Đã hẹn gặp/khảo sát" mà giờ hẹn đã qua (chưa cập nhật kết quả).</item>
            <item><c>appointmentMissing</c> — <c>true</c> = đang "Đã hẹn gặp/khảo sát" mà chưa ghi lịch (đăng ký có trước §6.29).</item>
            </list>
            Giá trị sai kiểu bị bỏ qua, không ném lỗi (cùng lệ <c>AgencyProfileSearchFilter</c>).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadSearchFilter.Apply(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},System.Nullable{System.DateTimeOffset},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadPortalVisits)">
            <param name="query">Truy vấn đã qua phạm vi của người gọi.</param>
            <param name="now">Mốc "hôm nay" của <c>idleMinDays</c>/<c>idleMaxDays</c> — báo cáo tồn đọng truyền đúng mốc nó đếm;
            <c>null</c> = bây giờ.</param>
            <param name="portal">Nguồn phiên cổng cho <c>portalSeenFromDate</c>/<c>portalSeenToDate</c>. Có khoá đó mà thiếu nguồn là
            lỗi lập trình (ném) — không được lặng lẽ bỏ qua bộ lọc rồi trả thừa dòng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadSearchFilter.Sort(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadPortalVisits)">
            <summary>
            Sắp xếp theo danh sách cột cho phép (<c>Sort.Predicate</c>); mặc định mới gửi trước. Cột lạ rơi về mặc định —
            không sắp theo tên property tuỳ ý từ client. <c>portallastseenat</c> (lần khách vào xem cổng gần nhất) cần
            <paramref name="portal"/>; giảm dần = vào gần đây nhất trước, đăng ký khách chưa vào cổng (<c>null</c>) xuống cuối.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadSearchFilter.Bool(Newtonsoft.Json.Linq.JObject,System.String)">
            <summary><c>true</c> (JSON) hoặc chuỗi <c>"true"</c>; mọi giá trị khác là <c>false</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadSearchFilter.Date(Newtonsoft.Json.Linq.JObject,System.String)">
            <summary>
            Ngày (theo giờ Việt Nam) của một giá trị lọc. Newtonsoft đổi chuỗi ISO có giờ thành <see cref="F:Newtonsoft.Json.Linq.JTokenType.Date"/>
            với <c>Kind</c> Utc/Local tuỳ hậu tố — dựng thẳng <c>DateTimeOffset(+07)</c> từ <c>DateTime</c> Utc là ném lỗi, nên
            quy mọi dạng về một thời điểm rồi mới lấy ngày ở múi +07.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadSearchFilter.VietnamDate(System.DateTime)">
            <summary>Utc/Local là một thời điểm → đổi sang +07 rồi lấy ngày; Unspecified coi như giờ Việt Nam.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadPortalVisits">
            <summary>
            Lần khách vào xem Cổng nhượng quyền gần nhất của một đăng ký (plan cổng §6.28) = <c>LastSeenAt</c> lớn nhất của mọi
            phiên (<see cref="T:Lada.Framework.Data.Domains.Network.FranchisePortalVisit"/>) trên mọi mã gắn đăng ký đó (<c>FranchisePortalAccessCode.FranchiseLeadId</c>),
            kể cả mã đã thu hồi / hết hạn. KHÔNG dùng <c>FranchisePortalAccessCode.LastAccessAt</c>: cột đó chỉ ghi lúc khách
            NHẬP MÃ, mà cookie phiên của cổng sống tới 7 ngày (<c>FranchisePortal.SessionDays</c>) — khách quay lại trong khoảng đó
            không nhập mã lại, chỉ phiên được chạm (<c>FranchisePortalStore.TouchLastSeenAsync</c>, tối đa một lần mỗi phút).
            Không gác theo role cổng: việc khách đã vào cổng vốn lộ qua trạng thái "Đã xem thông tin nhượng quyền" và người cập
            nhật "website" trên dòng đăng ký; mã rõ vẫn chỉ ở <c>FranchiseLeadService.AttachAccessCodesAsync</c>.
            Hai nguồn là truy vấn ĐÃ lọc xoá mềm (<c>IRepository.Query()</c>) cùng DbContext với truy vấn đăng ký — EF chèn chúng
            thành truy vấn con tương quan; repository giả in-memory chạy được cùng biểu thức.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadPortalVisits.WhereLastSeenFrom(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},System.DateTimeOffset)">
            <summary>Đăng ký có lần vào xem gần nhất từ <paramref name="from"/> trở đi (chưa vào cổng: MAX là null → không khớp).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadPortalVisits.WhereLastSeenBefore(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},System.DateTimeOffset)">
            <summary>Đăng ký có lần vào xem gần nhất TRƯỚC <paramref name="toExclusive"/> (chưa vào cổng: không khớp).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadPortalVisits.OrderByLastSeen(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},System.Boolean)">
            <summary>Giảm dần: vào gần đây nhất trước, chưa vào cổng (null) cuối; tăng dần thì ngược lại. Cùng mốc thì theo <c>Id</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadPortalVisits.LastSeenByLeadAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>Lần vào xem gần nhất theo <c>FranchiseLead.Id</c> cho một trang dòng; đăng ký khách chưa vào cổng không có trong kết quả.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadFilterOptions">
            <summary>
            Danh mục cho giao diện (<c>GET api/FranchiseLead/filter-options</c>), lấy từ enum và <see cref="T:Lada.Framework.Infrastructures.Services.Network.FranchiseLeadOptions"/>,
            không chép tay: <c>Statuses</c>/<c>Provinces</c>/<c>Channels</c> là đúng các giá trị <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadSearchFilter"/>
            nhận (ô lọc, hộp thoại đổi trạng thái); <c>BusinessStatuses</c> chỉ là nhãn — bộ lọc chưa có khoá cho nó.
            Form nhập tay đọc <c>Provinces</c>, <c>BusinessStatuses</c> và <c>ManualChannels</c> — đúng các giá trị
            <c>FranchiseLeadService</c> nhận khi tạo/sửa.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadFilterOptions.ManualChannels">
            <summary>Kênh nhân viên chọn được khi nhập tay: mọi kênh trừ Website (chỉ form website ghi kênh đó).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor">
            <summary>Người đang thao tác — controller đóng gói từ <c>User.GetCurrentUser()</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor.#ctor(System.Int32,System.String)">
            <summary>Người đang thao tác — controller đóng gói từ <c>User.GetCurrentUser()</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLeadService">
            <summary>
            Màn quản trị "Đăng ký nhượng quyền" (docs/plan-nhuong-quyen-website.md §3.1, §3.4, §3.6).
            <see cref="T:Lada.Framework.Data.Domains.Network.FranchiseLead"/> chứa dữ liệu cá nhân: mọi đường đọc/sửa đi qua <see cref="!:ScopedAsync"/> —
            người chỉ có <c>FranchiseLead.Search</c> chỉ chạm được đăng ký mình phụ trách; ngoài phạm vi trả "không tìm thấy".
            Mọi đường GHI kèm một dòng <see cref="T:Lada.Framework.Data.Domains.Network.FranchiseLeadHistory"/> trong cùng transaction.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLeadService.GetByIdAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor)">
            <summary><c>null</c> khi không có hoặc ngoài phạm vi của <paramref name="actor"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLeadService.GetHistoryAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor)">
            <summary>
            Lịch sử cập nhật của một đăng ký, mới nhất trước, kết thúc bằng dòng "Tạo đăng ký"; <c>null</c> khi không có
            hoặc ngoài phạm vi của <paramref name="actor"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLeadService.CreateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadCreateModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor)">
            <summary>
            Nhập tay một đăng ký cho người nhắn tin hoặc gọi tổng đài. Số điện thoại đã có đăng ký thì từ chối kèm mã của
            đăng ký đó. Người chỉ có <c>FranchiseLead.Search</c> tự phụ trách đăng ký mình nhập.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLeadService.UpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor)">
            <summary>Sửa thông tin người đăng ký; không có trường nào đổi thì không ghi gì.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLeadService.UpdateStatusAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadStatusModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor)">
            <summary>
            Đổi trạng thái và/hoặc ghi chú; giữ nguyên trạng thái mà đổi ghi chú là thêm một dòng tiến độ. Trạng thái đích
            "Đã hẹn gặp/khảo sát" bắt buộc kèm lịch hẹn; giữ trạng thái đó mà đổi lịch là một dòng "Đổi lịch hẹn" (§6.29).
            Trạng thái đích "Không phù hợp" thu hồi mọi mã truy cập cổng chưa thu hồi của đăng ký trong cùng transaction.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLeadService.AssignAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadAssignModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor)">
            <summary>Giao người phụ trách — người được giao phải còn làm việc và giữ Search hoặc Manage.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLeadService.AssignManyAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadAssignManyModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor)">
            <summary>
            Giao cùng một người phụ trách cho nhiều đăng ký trong MỘT transaction — cùng luật với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLeadService.AssignAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadAssignModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor)"/>,
            mỗi đăng ký đổi người một dòng lịch sử riêng. Id ngoài phạm vi bị bỏ qua và đếm vào <c>NotFoundCount</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLeadService.GetAssigneesAsync">
            <summary>Người giao được: giữ <c>FranchiseLead.Search</c> hoặc <c>FranchiseLead.Manage</c>, còn làm việc.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLeadService.ExportAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor)">
            <summary>Xuất Excel theo cùng bộ lọc với danh sách; tối đa <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.MaxExportRows"/> dòng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLeadService.GetBacklogAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor)">
            <summary>
            Báo cáo tồn đọng (trạng thái × thời gian chờ theo tỉnh, tỉnh × trạng thái) trong phạm vi người gọi, theo cùng bộ
            lọc với danh sách (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadBacklog"/>).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLeadService.GetStatusTimelineAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadTimelineModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor)">
            <summary>
            Các đoạn trạng thái theo thời gian (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadStatusTimeline"/>) của các đăng ký được hỏi — thanh
            của biểu đồ Gantt trang lịch hẹn. Id ngoài phạm vi của <paramref name="actor"/> bị bỏ qua (không có trong kết quả).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.MaxTimelineLeads">
            <summary>Trang lịch hẹn gộp ba khối, mỗi khối tối đa 200 dòng (<see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.MaxPageSize"/>).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.MaxAssignLeads">
            <summary>Giao hàng loạt chạy trên các dòng đang chọn của MỘT trang — tối đa một trang lớn nhất (<see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.MaxPageSize"/>).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.MaxPageSize">
            <summary>Khớp lựa chọn lớn nhất của bộ phân trang FE (<c>pageSizeOptions</c> tới 200).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.MaxNameLength">
            <summary>Ba trần dưới đây khớp form website (<c>FranchiseRegisterModel</c>).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.MaxAppointmentDistance">
            <summary>
            Lịch hẹn cách hôm nay quá khoảng này là gõ nhầm năm — vẫn nhận lịch đã qua để ghi lại cuộc hẹn vừa diễn ra.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.PhoneRegex">
            <summary>
            Rộng hơn form website (chỉ nhận di động): người gọi tổng đài có thể gọi từ số bàn 11 chữ số.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.PortalVisits">
            <summary>Nguồn "lần khách vào xem cổng gần nhất" (§6.28) cho bộ lọc, phép sắp và cột — mã + phiên đã lọc xoá mềm.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.ScopedAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor)">
            <summary>Phạm vi dữ liệu của người thao tác — MỘT chỗ cho Search, GetById, GetHistory, Update, UpdateStatus, Export.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.AttachPortalLastSeenAsync(System.Collections.Generic.IReadOnlyCollection{Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadPortalVisits)">
            <summary>
            Gắn lần khách vào xem cổng gần nhất (§6.28, <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadPortalVisits"/>) vào các dòng — một truy vấn
            gom theo đăng ký cho cả trang; không gác role cổng (xem lý do ở lớp nguồn).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.AttachAccessCodesAsync(System.Collections.Generic.IReadOnlyCollection{Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadItem},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor)">
            <summary>
            Gắn mã truy cập gần nhất + cờ "tạo được mã" vào các dòng đăng ký (plan cổng §6.23). Người gọi không có role cổng
            thì để trống cả hai — role cổng là hàng rào của mã, kể cả bản tóm tắt. Mã đọc qua ĐÚNG phạm vi mã
            (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalNavPermissions.ApplyScope(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchisePortalAccessCode},System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},System.Collections.Generic.IReadOnlyCollection{System.String},System.Int32)"/>): người giữ role chéo (vd. <c>FranchiseLead.Manage</c> +
            <c>FranchisePortal.Sale</c>) thấy mọi đăng ký nhưng chỉ thấy tóm tắt mã của đăng ký mình phụ trách — không hiện
            một mã mà mở ra lại 404.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.RevokeAccessCodesAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadActor,System.DateTimeOffset)">
            <summary>
            Thu hồi các mã truy cập cổng của đăng ký vừa lưu "Không phù hợp" — đúng cách ghi của nút Thu hồi
            (<c>FranchisePortalAccessCodeService.RevokeAsync</c>): đổi trạng thái mã, đóng phiên đang mở để request kế tiếp
            của khách bị đẩy về trang nhập mã, một dòng lịch sử của mã. Gọi TRONG transaction đổi trạng thái; mã người khác
            vừa thu hồi trước (store trả <c>false</c>) thì bỏ qua, không đè người/lý do của họ. Trả số mã thu hồi được.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.LeadInput">
            <summary>Thông tin người đăng ký đã chuẩn hoá và qua kiểm tra.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.LeadInput.#ctor(System.String,System.String,System.String,System.String,System.String,System.Boolean,System.String,System.String,Lada.Framework.Data.Domains.Network.FranchiseLeadChannel)">
            <summary>Thông tin người đăng ký đã chuẩn hoá và qua kiểm tra.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.Validate(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadModel,Lada.Framework.Data.Domains.Network.FranchiseLead)">
            <summary>
            Kiểm form nhập tay. Giá trị KHÔNG ĐỔI so với <paramref name="current"/> (số điện thoại, tỉnh, tình trạng doanh
            nghiệp) được giữ nguyên dù không còn qua luật — dòng chuyển từ bảng <c>Lead</c> cũ và tỉnh ngoài danh sách hiện
            tại vẫn sửa được các trường khác.
            </summary>
            <param name="current">Đăng ký đang sửa; <c>null</c> khi nhập mới.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.ValidateAppointment(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseLeadStatusModel,System.DateTimeOffset)">
            <summary>
            Lịch hẹn của form đổi trạng thái khi trạng thái đích là <see cref="F:Lada.Framework.Data.Domains.Network.FranchiseLeadStatus.Meeting"/> (plan cổng
            §6.29): bắt buộc, quy về giờ Việt Nam và bỏ giây (độ mịn của ô chọn giờ), trong vòng
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.MaxAppointmentDistance"/> quanh <paramref name="now"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.FormatAppointment(System.Nullable{System.DateTimeOffset})">
            <summary>Lịch hẹn như dòng lịch sử hiển thị: <c>dd/MM/yyyy HH:mm</c> giờ Việt Nam; chưa có lịch = <c>null</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.FindLeadByPhoneAsync(System.String,System.Int32)">
            <summary>
            Id của đăng ký khác đang giữ số này (mới nhất), <c>null</c> khi chưa có. CỐ Ý tìm ngoài phạm vi của người thao
            tác: trùng số với đăng ký người khác phụ trách vẫn là trùng — câu từ chối chỉ lộ mã NQ, không lộ thông tin nào khác.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.ResolveAssigneeAsync(System.Int32)">
            <summary>
            Tên hiển thị của người nhận phụ trách, hoặc câu từ chối: phải còn làm việc và xem được đăng ký nhượng quyền.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.SaveWithHistoryAsync(System.Func{System.Threading.Tasks.Task},System.Func{Lada.Framework.Data.Domains.Network.FranchiseLeadHistory})">
            <summary>
            Ghi thay đổi của đăng ký và dòng lịch sử của nó trong MỘT transaction — không có thay đổi nào thiếu dấu vết,
            không có dấu vết nào của thay đổi không xảy ra. <paramref name="buildHistory"/> chạy SAU khi lưu đăng ký để đọc
            được Id vừa sinh của bản ghi mới.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.Track(System.Collections.Generic.List{System.String},System.String,System.String,System.String)">
            <summary>Thêm dòng <c>Nhãn: cũ → mới</c> khi hai giá trị khác nhau (rỗng và <c>null</c> là một).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadService.BusinessLabel(System.String)">
            <summary>Nhãn tình trạng doanh nghiệp; mã lạ (dòng cũ) hiện nguyên mã thay vì biến mất khỏi dòng lịch sử.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadStatusTimeline">
            <summary>
            Các đoạn trạng thái theo thời gian của một đăng ký — thanh của biểu đồ Gantt trang lịch hẹn (plan cổng §6.30). Hàm
            thuần, dựng từ các dòng <see cref="F:Lada.Framework.Data.Domains.Network.FranchiseLeadHistoryAction.StatusChanged"/> (sale đổi tay, cổng tự đặt "Đã xem", tạo
            mã tự đặt "Đã cấp mã" — mọi đường đổi trạng thái đều ghi dòng đó).
            </summary>
            <remarks>
            Dữ liệu cũ không khớp lịch sử vẫn ra một dải liền, không lỗ hổng: đăng ký có trước bảng lịch sử không có dòng nào →
            một đoạn trạng thái hiện tại từ lúc gửi; trạng thái bị đổi ngoài đường ghi lịch sử (DataFix, sửa tay DB) → thêm đoạn
            trạng thái hiện tại từ <c>UpdatedTime</c>. Mốc lùi (giờ máy lệch) kẹp về mốc trước đó, đoạn dài 0 bỏ.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadStatusTimeline.Change">
            <summary>Một lần đổi trạng thái đọc từ lịch sử.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadStatusTimeline.Change.#ctor(System.Int32,System.DateTimeOffset,System.Nullable{Lada.Framework.Data.Domains.Network.FranchiseLeadStatus},Lada.Framework.Data.Domains.Network.FranchiseLeadStatus)">
            <summary>Một lần đổi trạng thái đọc từ lịch sử.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadStatusTimeline.Build(System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset},Lada.Framework.Data.Domains.Network.FranchiseLeadStatus,System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadStatusTimeline.Change})">
            <param name="createdTime">Lúc gửi / nhập đăng ký — đầu dải.</param>
            <param name="updatedTime">Lần cập nhật gần nhất — mốc của đoạn bù khi trạng thái hiện tại không khớp lịch sử.</param>
            <param name="current">Trạng thái hiện tại của đăng ký — đoạn cuối luôn mang trạng thái này.</param>
            <param name="changes">Mọi lần đổi trạng thái của đăng ký, thứ tự bất kỳ.</param>
            <returns>Các đoạn liền nhau theo thời gian; đoạn cuối <c>To = null</c> (còn đang ở trạng thái đó).</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadStatusTimeline.Close(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchiseLeadStatusSpanItem},Lada.Framework.Data.Domains.Network.FranchiseLeadStatus,System.DateTimeOffset,System.DateTimeOffset)">
            <summary>Đóng đoạn <paramref name="status"/> tại <paramref name="to"/>; đoạn dài 0 (đổi hai lần cùng lúc) bỏ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletHolder">
            <summary>Kết quả một lần đối chiếu Ví.</summary>
            <summary>
            Người cầm tiền thuộc bưu cục nhượng quyền đã bật ví (V-05): tiền người đó thu trên đơn Ví ghi đã nằm trong ví bưu cục, không nộp Quỹ LADA.
            </summary>
            <param name="AgencyId">Bưu cục nhượng quyền của người cầm tiền.</param>
            <param name="StartDate">Ngày bắt đầu ghi Ví (AppConfig <c>FranchiseWallet.StartDate</c>); null = mọi đơn.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletHolder.#ctor(System.Int32,System.Nullable{System.DateTime})">
            <summary>Kết quả một lần đối chiếu Ví.</summary>
            <summary>
            Người cầm tiền thuộc bưu cục nhượng quyền đã bật ví (V-05): tiền người đó thu trên đơn Ví ghi đã nằm trong ví bưu cục, không nộp Quỹ LADA.
            </summary>
            <param name="AgencyId">Bưu cục nhượng quyền của người cầm tiền.</param>
            <param name="StartDate">Ngày bắt đầu ghi Ví (AppConfig <c>FranchiseWallet.StartDate</c>); null = mọi đơn.</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletHolder.AgencyId">
            <summary>Bưu cục nhượng quyền của người cầm tiền.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletHolder.StartDate">
            <summary>Ngày bắt đầu ghi Ví (AppConfig <c>FranchiseWallet.StartDate</c>); null = mọi đơn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletHolder.Covers(System.Nullable{System.DateTimeOffset})">
            <summary>Đơn tạo lúc <paramref name="createdTime"/> có do Ví ghi không (cùng luật <c>RunAsync</c> và SP màn Quỹ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletHolder.Cutoff">
            <summary>
            Mốc 00:00 giờ VN của <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletHolder.StartDate"/> để lọc trong truy vấn: đơn tạo TRƯỚC mốc không do Ví ghi (lái xe vẫn nộp LADA);
            null = mọi đơn do Ví ghi. Dùng chung cho phiếu chuyển khoản lái xe và màn "tiền cần nộp" của app (V-40).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePickupCollect">
            <summary>
            Kết quả kiểm số thực thu khi lấy (E1) TRƯỚC SP lấy hàng: <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePickupCollect.Error"/> ≠ null → từ chối lấy; <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePickupCollect.Amount"/> = số sẽ ghi
            vào <c>OrderFin.SourceFeeCollectedAmount</c> SAU khi SP thành công (V-29); null = không áp.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePickupCollect.#ctor(System.String,System.Nullable{System.Decimal})">
            <summary>
            Kết quả kiểm số thực thu khi lấy (E1) TRƯỚC SP lấy hàng: <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePickupCollect.Error"/> ≠ null → từ chối lấy; <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePickupCollect.Amount"/> = số sẽ ghi
            vào <c>OrderFin.SourceFeeCollectedAmount</c> SAU khi SP thành công (V-29); null = không áp.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePickupCollect.NotApplicable">
            <summary>Không áp (bên lấy không bật ví, đơn không thu người gửi, đơn trước ngày ghi Ví).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerRunResult.SenderPayout">
            <summary>E8 — chỉ có khi lượt chạy là đối soát với khách của đơn COD giao thành công có bên bán bật ví.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOutboundRequest">
            <summary>Yêu cầu xuất kho một đơn cho bưu cục phát (plan v2 §3.3 "Xuất kho").</summary>
            <param name="DeliveryAgencyId">Chi nhánh của người được gán — bên phát P.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOutboundRequest.#ctor(System.Int32,System.Int32,System.Int32,System.String,System.Int32)">
            <summary>Yêu cầu xuất kho một đơn cho bưu cục phát (plan v2 §3.3 "Xuất kho").</summary>
            <param name="DeliveryAgencyId">Chi nhánh của người được gán — bên phát P.</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOutboundRequest.DeliveryAgencyId">
            <summary>Chi nhánh của người được gán — bên phát P.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOutboundCheck">
            <summary>Kết quả kiểm xuất kho MỘT đơn — hợp đồng API gán đổi từ "Failed cả lô" sang từng đơn (FE GĐ D đọc).</summary>
            <param name="Ok">Đơn được xuất (đã ghi khoản giữ E2 / E3 nếu có).</param>
            <param name="WouldBlock">Ví không đủ nhưng công tắc chặn tắt — đã đi, đã ghi "sẽ chặn" vào sổ vấn đề.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOutboundCheck.#ctor(System.Int32,System.Boolean,System.Boolean,System.Decimal,System.Decimal,System.Decimal,System.String)">
            <summary>Kết quả kiểm xuất kho MỘT đơn — hợp đồng API gán đổi từ "Failed cả lô" sang từng đơn (FE GĐ D đọc).</summary>
            <param name="Ok">Đơn được xuất (đã ghi khoản giữ E2 / E3 nếu có).</param>
            <param name="WouldBlock">Ví không đủ nhưng công tắc chặn tắt — đã đi, đã ghi "sẽ chặn" vào sổ vấn đề.</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOutboundCheck.Ok">
            <summary>Đơn được xuất (đã ghi khoản giữ E2 / E3 nếu có).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOutboundCheck.WouldBlock">
            <summary>Ví không đủ nhưng công tắc chặn tắt — đã đi, đã ghi "sẽ chặn" vào sổ vấn đề.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOutboundCheck.Pass(System.Int32)">
            <summary>Không có gì phải kiểm (bên phát không bật ví).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOfficialFeeLock">
            <summary>Kết quả chốt cước chính thức khi nhập kho LADA.</summary>
            <param name="Applicable">Đơn thuộc phạm vi v2 (có chi nhánh bật ví tham gia, người quét không bật ví, đang trên đường đi).</param>
            <param name="Locked">Vừa chốt ở lần này (false khi đã chốt trước đó).</param>
            <param name="CodBelowFeeHold">Đơn COD có tiền thu hộ nhỏ hơn cước chính thức — đã đặt cờ giữ, không chặn nhập.</param>
            <param name="Error">Lý do từ chối nhập kho đơn này (thiếu ô cân thật khi cờ bắt buộc bật); null = nhập được.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOfficialFeeLock.#ctor(System.Boolean,System.Boolean,System.Nullable{System.Decimal},System.Nullable{System.Int32},System.Boolean,System.String)">
            <summary>Kết quả chốt cước chính thức khi nhập kho LADA.</summary>
            <param name="Applicable">Đơn thuộc phạm vi v2 (có chi nhánh bật ví tham gia, người quét không bật ví, đang trên đường đi).</param>
            <param name="Locked">Vừa chốt ở lần này (false khi đã chốt trước đó).</param>
            <param name="CodBelowFeeHold">Đơn COD có tiền thu hộ nhỏ hơn cước chính thức — đã đặt cờ giữ, không chặn nhập.</param>
            <param name="Error">Lý do từ chối nhập kho đơn này (thiếu ô cân thật khi cờ bắt buộc bật); null = nhập được.</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOfficialFeeLock.Applicable">
            <summary>Đơn thuộc phạm vi v2 (có chi nhánh bật ví tham gia, người quét không bật ví, đang trên đường đi).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOfficialFeeLock.Locked">
            <summary>Vừa chốt ở lần này (false khi đã chốt trước đó).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOfficialFeeLock.CodBelowFeeHold">
            <summary>Đơn COD có tiền thu hộ nhỏ hơn cước chính thức — đã đặt cờ giữ, không chặn nhập.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOfficialFeeLock.Error">
            <summary>Lý do từ chối nhập kho đơn này (thiếu ô cân thật khi cờ bắt buộc bật); null = nhập được.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOrderForecast">
            <summary>Dự kiến phí của một đơn (màn Đơn hàng bưu cục, plan §3.8.1).</summary>
            <param name="OrderCode">Mã đơn.</param>
            <param name="ParticipantAgencyIds">Chi nhánh tham gia đơn: bán, lấy (thật / dự kiến), phát (gán / đã giao / dự kiến), phát hoàn (dự kiến / thật).</param>
            <param name="Forecast">Dòng dự kiến; null = chưa bật ví nào hoặc đơn tạo trước ngày bắt đầu ghi Ví.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOrderForecast.#ctor(System.String,System.Collections.Generic.IReadOnlyList{System.Int32},Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerForecast)">
            <summary>Dự kiến phí của một đơn (màn Đơn hàng bưu cục, plan §3.8.1).</summary>
            <param name="OrderCode">Mã đơn.</param>
            <param name="ParticipantAgencyIds">Chi nhánh tham gia đơn: bán, lấy (thật / dự kiến), phát (gán / đã giao / dự kiến), phát hoàn (dự kiến / thật).</param>
            <param name="Forecast">Dòng dự kiến; null = chưa bật ví nào hoặc đơn tạo trước ngày bắt đầu ghi Ví.</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOrderForecast.OrderCode">
            <summary>Mã đơn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOrderForecast.ParticipantAgencyIds">
            <summary>Chi nhánh tham gia đơn: bán, lấy (thật / dự kiến), phát (gán / đã giao / dự kiến), phát hoàn (dự kiến / thật).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOrderForecast.Forecast">
            <summary>Dòng dự kiến; null = chưa bật ví nào hoặc đơn tạo trước ngày bắt đầu ghi Ví.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService">
            <summary>
            Ghi Ví bưu cục theo sự kiện đơn (Ví v2 — Docs "Yêu cầu kỹ thuật Ví bưu cục v2", plan <c>docs/plan-vi-buu-cuc-v2.md</c>). Móc vào các
            chỗ đơn đổi trạng thái NGAY SAU khi nghiệp vụ đã thành công (SP trả Success) hoặc CÙNG GIAO DỊCH (xuất kho, nhập kho, mở hoàn —
            §3.3) qua <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope"/>.
            </summary>
            <remarks>
            <b>Móc sự kiện không bao giờ ném lỗi ra nơi gọi</b> (SPEC M19): mọi lỗi được log, ghi sổ vấn đề <c>FranchiseLedgerIssue</c>, và job
            đêm <c>franchise-ledger-recheck</c> đối chiếu lại. Ngoại lệ duy nhất là <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.OutboundToAgencyAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOutboundRequest,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope,System.Func{System.Threading.Tasks.Task})"/> — điểm chặn: lỗi kỹ
            thuật = từ chối đơn đó (hàng không rời kho khi chưa giữ được tiền). Luật nằm ở <see cref="T:Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerPlanner"/> (thuần,
            idempotent): móc và job cùng một luật.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.StampOrderAsync(System.Int32,System.Int32)">
            <summary>Đóng dấu bưu cục bán / bưu cục tạo / bản giá mua đơn / dải cự ly ngay sau khi tạo đơn (không ghi dòng).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.OnOrderEventAsync(System.Int32,Lada.Framework.Data.Domains.Network.WalletEventType,System.Int32,System.String,System.Int32)">
            <summary>Một sự kiện đơn vừa xảy ra (sau SP đã commit) — đối chiếu và ghi Ví của đơn. Không ném lỗi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.OnOrderEventAsync(System.Int32,Lada.Framework.Data.Domains.Network.WalletEventType,System.Int32,System.String,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            Như trên nhưng CÙNG GIAO DỊCH của nơi gọi: đọc / ghi qua connection + transaction của <paramref name="scope"/>. Gọi SAU khi nơi
            gọi đã ghi trạng thái mới của đơn (chưa commit) — Ví đọc được trạng thái đó. Không ném lỗi (lỗi → sổ vấn đề, job đêm bù).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.ReconcileOrderAsync(System.Int32)">
            <summary>Đối chiếu một đơn theo trạng thái (không sự kiện) — dùng cho job và nút "đối chiếu lại".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.RecheckAsync">
            <summary>Job đêm: đối chiếu đơn có cập nhật gần đây dính tới chi nhánh bật ví + đơn còn vấn đề mở.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.IsPriceVersionUsedAsync(System.Int32)">
            <summary>Bản giá đã được dùng (dòng Ví / đơn neo) chưa.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.LoadWalletEnabledAgencyIdsAsync">
            <summary>Chi nhánh đã bật ví (đệm 2 phút) — nơi gọi dùng để biết đơn / người có thuộc phạm vi v2 không.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.IsWalletInvolvedAsync(System.Int32,System.Int32)">
            <summary>Đơn có dính chi nhánh bật ví không (người thao tác, S / L / P / chủ khách, hoặc đã có dòng Ví).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.IsFranchiseAgencyAsync(System.Int32)">
            <summary>
            Chi nhánh là bưu cục NHƯỢNG QUYỀN (<c>AgencyType = Franchise</c>). Chi nhánh LADA bật ví để đo (§6 mục 15) vẫn là "kho LADA" ở
            mốc chốt cước và nhận lại hàng hoàn — không dùng cờ bật ví để nhận diện kho LADA. 0 / không có = LADA.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.ResolveWalletHolderAsync(System.Int32)">
            <summary>
            V-05: người dùng thuộc bưu cục NHƯỢNG QUYỀN đang bật ví → bưu cục + ngày bắt đầu ghi Ví (để màn Quỹ không thu tiền của đơn Ví ghi);
            không thì null. Chi nhánh LADA bật ví để đo trả null — lái xe LADA vẫn nộp Quỹ (§6 mục 15).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.LoadStartDateAsync">
            <summary>Ngày bắt đầu ghi Ví (AppConfig <c>FranchiseWallet.StartDate</c>); null = mọi đơn. Đơn tạo trước ngày này đi luồng LADA cũ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.OutboundToAgencyAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOutboundRequest,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope,System.Func{System.Threading.Tasks.Task})">
            <summary>
            Điểm chặn xuất kho (plan §3.4, Docs §5): trong giao dịch của nơi gọi — khoá ví bên phát, đọc số dư SAU khoá, quyết định bằng
            <see cref="M:Lada.Framework.Infrastructures.Services.Network.FranchiseWalletRules.CanOutbound(System.Decimal,System.Decimal,System.Decimal,System.Boolean,System.Boolean)"/>; được thì gọi <paramref name="applyOrder"/> (nơi gọi đổi trạng thái + ghi
            <c>AgencyDeliveryAssignedId</c> + track, chưa commit) rồi ghi E2 / E3 cùng giao dịch. Không được → trả <c>Ok = false</c> kèm số
            thiếu, chưa đụng đơn. Lỗi kỹ thuật NÉM ra để nơi gọi rollback đơn đó.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.CheckInboundByDeliveryAgencyAsync(System.Int32,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            Cổng ví cho đường "bưu cục bật ví QUÉT NHẬN hàng chưa qua gán" (§4.0 #9 B2) — cùng luật điểm chặn xuất kho: bưu cục quét là bên phát
            (<see cref="M:Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerPlanner.IsInboundByDeliveryAgency(Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerOrder,System.Int32,System.Func{System.Int32,System.Boolean})"/>) và chưa được gán → khoá ví, đọc số dư sau khoá,
            <see cref="M:Lada.Framework.Infrastructures.Services.Network.FranchiseWalletRules.CanOutbound(System.Decimal,System.Decimal,System.Decimal,System.Boolean,System.Boolean)"/>. Không ghi gì: nơi gọi từ chối quét khi <c>Ok = false</c>, còn lại đi tiếp rồi gọi
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.OnOrderEventAsync(System.Int32,Lada.Framework.Data.Domains.Network.WalletEventType,System.Int32,System.String,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)"/> để planner ghi E2 / E3.
            Review bảo mật GĐ B (26/10/2026): thiếu cổng này, bưu cục có role nhập kho tự quét đơn đang ở kho LADA → E2 / E3 ghi không kiểm
            số dư, rồi gán lái xe mình không qua điểm chặn (bên giữ = bên phát). Lỗi kỹ thuật NÉM ra để nơi gọi từ chối đơn đó.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.CheckCollectedAtPickupAsync(System.Int32,System.Int32,System.Nullable{System.Decimal},System.Boolean)">
            <summary>
            E1 bước 1 — kiểm số lái xe thực thu của người gửi khi lấy, gọi TRƯỚC SP lấy hàng, KHÔNG ghi gì: chỉ áp khi bên lấy bật ví, đơn do
            Ví ghi và hình thức GỬI-TRẢ / Thu 2 đầu; thiếu số = <see cref="M:Lada.Framework.Infrastructures.Services.OrderPaymentRules.DefaultCollectedAtPickup(Lada.Framework.Infrastructures.Services.Network.FranchisePayMode,System.Decimal,System.Decimal)"/>; biên 0–150 % cước
            tạm tính. <paramref name="requireWhenPrompted"/> (app lái xe): ô "Số tiền đã thu" đang bật (<see cref="M:Lada.Framework.Infrastructures.Services.OrderPaymentRules.DecidePickupCollect(System.Boolean,System.Boolean,Lada.Framework.Infrastructures.Services.Network.FranchisePayMode,System.Decimal,System.Decimal,System.Nullable{System.Decimal})"/>)
            mà thiếu số → từ chối. Lỗi kỹ thuật → không áp + ghi vấn đề (không chặn lấy hàng).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.RecordCollectedAtPickupAsync(System.Int32,System.Decimal)">
            <summary>
            E1 bước 2 — ghi số đã kiểm vào <c>OrderFin.SourceFeeCollectedAmount</c> SAU khi SP lấy hàng thành công, trước móc
            <c>PickupConfirmed</c> (V-29: SP thất bại thì đơn không mang số của lần lấy hỏng). Không ném lỗi: lỗi → vấn đề, planner dùng
            cước thu người gửi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.GetPickupCollectPromptsAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Int32)">
            <summary>
            Ô "Số tiền đã thu" cho các đơn lái xe sắp lấy (plan §3.8.2) — cùng luật với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.CheckCollectedAtPickupAsync(System.Int32,System.Int32,System.Nullable{System.Decimal},System.Boolean)"/>. Lái xe không
            thuộc bưu cục nhượng quyền bật ví → rỗng (một lần đọc tập ví đã cache). Đơn lỗi kỹ thuật bị bỏ qua (app hiện màn cũ, máy chủ vẫn
            kiểm lúc lấy).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.ValidateOrderPaymentAsync(System.Int32,System.Int32,Lada.Framework.Data.Enums.OrderFinEnum.PayFeeType,System.Decimal,System.Decimal)">
            <summary>
            Cổng tạo đơn (T06 / T23): chỉ kiểm khi đơn có chi nhánh bật ví tham gia (bên bán theo Q16, chi nhánh tạo). Trả thông điệp lỗi
            hoặc null (hợp lệ / không áp). Lỗi kỹ thuật → null + log (V-17 bắt lại ở sự kiện đầu).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.LockOfficialFeeAtInboundAsync(System.Int32,System.Int32,System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            Chốt cước chính thức CC khi kho LADA (chi nhánh không bật ví) nhập đơn có chi nhánh bật ví tham gia, lần đầu, trong giao dịch
            nhập kho (plan §3.3). Cân thật ≠ Σ cân kiện → tính lại bằng <c>FeeQuoteEngine</c>; không thì CC = cước tạm tính. Đơn COD có tiền
            thu hộ nhỏ hơn CC → cờ giữ + báo bên bán, KHÔNG chặn nhập. Không ném lỗi (trừ khi thiếu ô cân bắt buộc → <c>Error</c>).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.LockOfficialFeeAtReturnAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Mở hoàn trước khi nhập kho LADA (§6 mục 2): CC = cước tạm tính lúc huỷ nếu chưa chốt — trong giao dịch mở hoàn. Không ném lỗi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.ApplyCustomerReconciledAsync(System.Int32,System.Collections.Generic.IReadOnlyList{Lada.Framework.Infrastructures.Services.Network.FranchiseReturnFeeDebt},System.Decimal,System.Int32,System.String,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            E8 / E13 tại mốc hoàn thành phiếu đối soát khách (plan §3.6), CÙNG GIAO DỊCH chuyển tiền của phiếu: planner tính tiền trả khách gửi
            của đơn COD (E8, ngoài ví) và ghi E13 + ví bưu cục sale cho từng đơn hoàn trong <paramref name="debts"/> (khoản đã giữ chỗ lúc lập
            phiếu). NÉM lỗi khi không ghi được hoặc khi số planner tính lệch <paramref name="expectedPayout"/> (số đã đưa vào phiếu) — nơi gọi
            rollback cả phiếu: không trả khách số tiền mà ví bưu cục sale chưa được cộng tương ứng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.PreviewSenderPayoutAsync(System.Int32,System.Collections.Generic.IReadOnlyList{Lada.Framework.Infrastructures.Services.Network.FranchiseReturnFeeDebt})">
            <summary>
            Xem trước E8 của một đơn khi lập phiếu đối soát khách — CÙNG planner với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.ApplyCustomerReconciledAsync(System.Int32,System.Collections.Generic.IReadOnlyList{Lada.Framework.Infrastructures.Services.Network.FranchiseReturnFeeDebt},System.Decimal,System.Int32,System.String,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)"/> nhưng không ghi gì.
            null = đơn không theo luật ví (không phải COD giao thành công có bưu cục NHƯỢNG QUYỀN bật ví bán, hoặc tạo trước ngày bắt đầu ghi Ví)
            → phiếu giữ công thức cũ (plan §1.3).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.ForecastAsync(System.Int32)">
            <summary>
            Dự kiến dòng ví nếu đơn giao thành công từ trạng thái hiện tại (planner <c>Forecast</c>, không ghi gì) — màn Đơn hàng bưu cục
            (plan §3.8.1). null = đơn không có / hệ thống chưa bật ví nào / đơn tạo trước ngày bắt đầu ghi Ví. Kèm các chi nhánh tham gia đơn
            (bán / lấy / phát / phát hoàn, kể cả dự kiến) để nơi gọi kiểm phạm vi bưu cục.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService.WarnLowBalanceAsync(System.Collections.Generic.IEnumerable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            Cảnh báo số dư thấp (plan §3.4 "Cảnh báo"): với mỗi bưu cục NHƯỢNG QUYỀN có ví bật mà số dư &lt; ngưỡng, báo một lần mỗi ngày (bưu
            cục + quản lý khu vực). Chi nhánh LADA bật ví để đo không áp ngưỡng (§6 mục 15). Không ném lỗi.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.StartDateKey">
            <summary>Khoá AppConfig ngày bắt đầu ghi Ví.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.RecheckDaysKey">
            <summary>Khoá AppConfig số ngày job đêm nhìn lại.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.SystemActor">
            <summary>Tên người ghi trên cột audit của dòng Ví do hệ thống sinh.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.Stamps">
            <summary>Bộ dấu trên đơn dùng cho một lần lập kế hoạch.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.Stamps.#ctor(System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{System.Int32})">
            <summary>Bộ dấu trên đơn dùng cho một lần lập kế hoạch.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.StampOrderAsync(System.Int32,System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.OnOrderEventAsync(System.Int32,Lada.Framework.Data.Domains.Network.WalletEventType,System.Int32,System.String,System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.OnOrderEventAsync(System.Int32,Lada.Framework.Data.Domains.Network.WalletEventType,System.Int32,System.String,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.ReconcileOrderAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.RecheckAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.LockLateOfficialFeeAsync(System.Int32,System.Collections.Generic.HashSet{System.Int32})">
            <summary>
            V-22 (job đêm): đơn có bưu cục nhượng quyền bật ví tham gia, ĐÃ NHẬP kho LADA (<c>Inbound</c> — không tính <c>Outbound</c>: đó là hàng
            đang trên đường từ bưu cục về kho, chốt lúc đó là mất lần cân thật khi nhập — review GĐ C) mà chưa có cước chính
            thức — lỗi kỹ thuật lúc nhập kho, hoặc nhập kho trước khi bưu cục bật ví — chốt CC = TT (nguồn "nhập kho") + ghi chú cho kế toán kiểm
            cân thật. Cùng điều kiện "tham gia" với chốt cước lúc nhập kho; đơn tạo trước ngày bắt đầu ghi Ví không đụng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.CheckInvariantAsync(Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerOrder,System.Func{System.Int32,System.Boolean},Lada.Framework.Infrastructures.Services.Network.IFranchiseLedgerPriceSource,Lada.Framework.Infrastructures.Services.Network.FranchiseWalletParams,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            T17 (lượt đối chiếu không trigger — job đêm / nút đối chiếu lại) cho đơn đã kết thúc: dòng ví thực có so với dựng lại từ đầu theo luật
            (<see cref="M:Lada.Framework.Infrastructures.Services.Network.FranchiseInvariant.CheckReplay(Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerOrder,System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Network.FranchiseWalletEntry},System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Network.FranchiseWalletEntry})"/>, plan §6 mục 22). Lệch → vấn đề loại bất biến + báo kế toán MỘT lần (vấn đề mới); hết lệch
            → lần kiểm sau tự đóng. Trả true khi lệch.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.IsPriceVersionUsedAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.LoadWalletEnabledAgencyIdsAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.IsWalletInvolvedAsync(System.Int32,System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.LoadStartDateAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.ResolveWalletHolderAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.IsFranchiseAgencyAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.OutboundToAgencyAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseOutboundRequest,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope,System.Func{System.Threading.Tasks.Task})">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.CheckInboundByDeliveryAgencyAsync(System.Int32,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.DecideHoldAsync(System.Int32,System.Int32,System.Collections.Generic.HashSet{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope,System.Func{Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerOrder,System.Boolean})">
            <summary>
            Phần chung của hai cổng (xuất kho, quét nhận thẳng): ảnh chụp đơn trong giao dịch (không ghi dấu lên Order — nơi gọi sắp
            <c>UpdateAsync</c> cả dòng), khoản E2 / E3 phải giữ cho bên phát (đã giữ đúng khoản → 0), khoá ví rồi mới đọc số dư
            (mẫu SqlCashHolderLock — hai lô song song xếp hàng ở đây), quyết định bằng <see cref="M:Lada.Framework.Infrastructures.Services.Network.FranchiseWalletRules.CanOutbound(System.Decimal,System.Decimal,System.Decimal,System.Boolean,System.Boolean)"/>.
            </summary>
            <param name="applies">Điều kiện áp cổng tính trên trạng thái hiện tại (trước khi coi <paramref name="deliveryAgencyId"/> là bên phát); null = luôn áp.</param>
            <returns>Quyết định (null khi <paramref name="applies"/> không thoả — chưa khoá ví) và ảnh chụp đơn.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.FranchiseOnlyAsync(System.Collections.Generic.HashSet{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Tập chi nhánh bật ví thu hẹp về bưu cục nhượng quyền (bỏ chi nhánh LADA bật ví để đo).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.IsFranchiseTypeAsync(System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Chi nhánh là bưu cục nhượng quyền (<c>Agency.AgencyType = Franchise</c>); chi nhánh LADA bật ví để đo (plan §6 mục 15) không phải.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.IsFranchiseWalletAsync(System.Nullable{System.Int32},System.Collections.Generic.HashSet{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            "Bên bán có ví" theo nghĩa Docs = bưu cục nhượng quyền ĐANG bật ví. Review GĐ B F3: chi nhánh LADA bật ví để đo không chịu cổng
            T06 / T23 và chuyển khoản của nó vẫn là CK kế toán — nếu không, sau 18/12 nhân viên LCHN tạo đơn CK + thu hộ sẽ bị từ chối.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.CheckCollectedAtPickupAsync(System.Int32,System.Int32,System.Nullable{System.Decimal},System.Boolean)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.RecordCollectedAtPickupAsync(System.Int32,System.Decimal)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.GetPickupCollectPromptsAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.ResolvePickupCollectAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerOrderSnapshot,System.Boolean,System.Collections.Generic.HashSet{System.Int32},System.Nullable{System.DateTime})">
            <summary>
            Hình thức Ví v2 + đơn có do Ví ghi không + ô "Số tiền đã thu" của một đơn. <paramref name="pickerIsFranchise"/> = bên lấy là bưu
            cục nhượng quyền bật ví — người gọi tính một lần cho cả lô (không truy vấn lại loại chi nhánh từng đơn).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.ValidateOrderPaymentAsync(System.Int32,System.Int32,Lada.Framework.Data.Enums.OrderFinEnum.PayFeeType,System.Decimal,System.Decimal)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.LockOfficialFeeAtInboundAsync(System.Int32,System.Int32,System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.LockOfficialFeeAtReturnAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.ApplyCustomerReconciledAsync(System.Int32,System.Collections.Generic.IReadOnlyList{Lada.Framework.Infrastructures.Services.Network.FranchiseReturnFeeDebt},System.Decimal,System.Int32,System.String,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.PreviewSenderPayoutAsync(System.Int32,System.Collections.Generic.IReadOnlyList{Lada.Framework.Infrastructures.Services.Network.FranchiseReturnFeeDebt})">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.ForecastAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.WarnLowBalanceAsync(System.Collections.Generic.IEnumerable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.MarkFranchiseHeldAsync(Lada.Framework.Data.Domains.Orders.OrderFin,System.Collections.Generic.HashSet{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            V-60 (anh Thắng 27/10/2026): khoản còn ở "Lái xe đang cầm" mà người cầm thuộc bưu cục nhượng quyền bật ví → "Bưu cục giữ" — đơn đã qua
            cổng ngày bắt đầu ghi Ví ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.RunAsync(System.Int32,Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerTrigger,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope,System.Collections.Generic.IReadOnlyList{Lada.Framework.Infrastructures.Services.Network.FranchiseReturnFeeDebt})"/>, tức đúng luật <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletHolder.Covers(System.Nullable{System.DateTimeOffset})"/> mà màn Quỹ / phiếu chuyển
            khoản / job phạt đang loại. Chi nhánh LADA bật ví để đo không chuyển: lái xe chi nhánh vẫn nộp Quỹ.
            Mỗi khoản chỉ chuyển khi chi nhánh của người cầm có dòng ví chưa đảo cho ĐÚNG khoản đó (cước lấy ↔ E1, cước giao ↔ E2, COD / phí trừ
            COD ↔ E3) — review H2: lái xe LADA đang cầm tiền đơn có bưu cục tham gia rồi chuyển sang bưu cục bật ví không được kéo tiền LADA
            chưa thu sang "Bưu cục giữ" (Quỹ không thu được nữa, doanh thu / lương tính như đã thanh toán).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.BuildOrder(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerOrderSnapshot,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.Stamps,Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerTrigger,System.Collections.Generic.IReadOnlyList{Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerCollection},System.Boolean)">
            <summary>Ảnh chụp DB → đầu vào planner.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.ResolveSeller(System.Nullable{System.Int32},System.Int32,System.Collections.Generic.HashSet{System.Int32})">
            <summary>Bên bán theo SPEC Q16: chủ khách nếu bật ví; chủ khách = 0 → LADA; khách chưa gán → bưu cục tạo nếu bật ví; không thì LADA (0).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.ResolveSellerAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerOrderSnapshot,System.Collections.Generic.HashSet{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Bên bán + bưu cục tạo của một đơn, KHÔNG ghi dấu (dùng trước khi nơi gọi ghi đơn trong giao dịch).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.ResolveStampsAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerOrderSnapshot,System.Collections.Generic.HashSet{System.Int32},Lada.Framework.Infrastructures.Services.Network.IFranchiseLedgerPriceSource,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Tính bộ dấu (bưu cục bán / tạo / bản giá mua / dải) và cho biết có cột NULL cần ghi không — KHÔNG ghi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.EnsureStampsAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerOrderSnapshot,System.Collections.Generic.HashSet{System.Int32},Lada.Framework.Infrastructures.Services.Network.IFranchiseLedgerPriceSource,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Đóng dấu còn thiếu (chỉ cột NULL) và trả bộ giá trị dùng cho lần lập kế hoạch này.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.PaymentGuardAsync(System.Int32,System.String,Lada.Framework.Data.Domains.Orders.OrderFin,System.Nullable{System.Int32},System.Nullable{System.Int32},System.Collections.Generic.HashSet{System.Int32},System.Collections.Generic.List{System.String},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            Luật T06 / T23 trên đơn ĐÃ tồn tại (V-17 ở sự kiện đầu; COD &lt; CC sau cân khi nhập kho): vi phạm → cờ giữ hàng
            <c>CodBelowFeeHold</c> (chặn ở xuất kho) + vấn đề + báo bên bán; hết vi phạm (bên bán đã sửa) → bỏ cờ. Trả cờ sau khi kiểm.
            Chỉ áp với đơn có bên bán / bưu cục tạo bật ví.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.CanRequote(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerOrderSnapshot)">
            <summary>Có tính lại được cước bằng một con số cân không: đơn giá theo cân (không phụ phí thuộc tính, không kiện khai loại hàng, không đối tác).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.CollectionsAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerOrderSnapshot,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Các khoản đã thu của đơn kèm bưu cục người thu thực tế; đóng dấu cột bưu cục người thu còn NULL.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.LoadParamsAsync">
            <summary>Tham số luật Ví v2 từ AppConfig <c>FranchiseWallet.*</c> (thiếu khoá → mặc định, không ném lỗi).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.BoolConfigAsync(System.String)">
            <summary>Cờ bool trong AppConfig ("true" / "1"); thiếu hoặc không đọc được = false.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerService.SafeIssueAsync(System.Int32,System.String,System.String,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            Ghi vấn đề lỗi kỹ thuật, không ném lỗi. Có <paramref name="scope"/> (giao dịch của nơi gọi còn mở): chèn thẳng trên connection riêng,
            không đọc sổ vấn đề của đơn — đọc sẽ chờ khoá dòng mà giao dịch kia vừa ghi tới hết hạn lệnh (V-26). Ghi ngoài giao dịch để nơi gọi
            rollback thì vấn đề vẫn còn để soát.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerOrderSnapshot">
            <summary>Ảnh chụp thô một đơn (đọc mới từ DB, không qua bản EF đang theo dõi của request).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerOrderSnapshot.ChargeWeightGram">
            <summary>Σ cân kiện (gram) — cân tạm tính lúc tạo đơn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerOrderSnapshot.HadDeliveryFail">
            <summary>Đơn đã từng giao thất bại (<c>OrderTrack</c> 153 hoặc trạng thái hiện tại) — E11 (V-19, GĐ B việc 5).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerOrderSnapshot.HasPackageGoodsCategory">
            <summary>Có kiện khai loại hàng riêng (giá theo loại hàng) — không tính lại cước theo cân thật được bằng một con số cân.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerOrderSnapshot.Packages">
            <summary>Kiện như lúc tạo (cân khai, kích thước mm, số lượng, cân tính cước đã lưu) — cân thể tích khi chốt cước theo cân thật (review GĐ B F1).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseHeldParts">
            <summary>
            V-60: các khoản của một đơn sẽ chuyển sang "Bưu cục giữ", mỗi khoản kèm người đang cầm (null = không đổi khoản đó). Phí trừ COD đi theo
            người cầm của nó.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerPackage">
            <summary>Một kiện của đơn: cân khai (gram), kích thước (mm), số lượng, cân tính cước đã lưu (<c>OrderPackage.SubTotalWeight</c>).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerPackage.#ctor(System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32)">
            <summary>Một kiện của đơn: cân khai (gram), kích thước (mm), số lượng, cân tính cước đã lưu (<c>OrderPackage.SubTotalWeight</c>).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope">
            <summary>
            Phạm vi "cùng giao dịch" của nơi gọi (xuất kho, nhập kho, mở hoàn — plan v2 §3.3): bọc <see cref="T:Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction"/> của
            <c>IRepository.BeginTransaction()</c>; tầng lưu Ví đọc / ghi qua một <see cref="T:Lada.Framework.Data.Mappings.DbContexts.LadaDbContext"/> RIÊNG dựng trên ĐÚNG connection
            + transaction đó — đọc được trạng thái đơn vừa ghi chưa commit, không chạm change tracker của service đang gọi, và commit /
            rollback của nơi gọi quyết định cả dòng Ví.
            </summary>
            <remarks>Dispose scope chỉ đóng context bọc, KHÔNG đụng transaction (nơi gọi sở hữu).</remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope.Transaction">
            <summary>Giao dịch của nơi gọi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope.Db">
            <summary>Context bọc cùng connection + transaction (tạo lần đầu dùng).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletBalance">
            <summary>Số dư một ví (không khoá) kèm ngưỡng cảnh báo — đầu vào cảnh báo số dư thấp (plan §3.4 "Cảnh báo").</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletBalance.#ctor(System.Int32,System.Int32,System.Decimal,System.Decimal)">
            <summary>Số dư một ví (không khoá) kèm ngưỡng cảnh báo — đầu vào cảnh báo số dư thấp (plan §3.4 "Cảnh báo").</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletLocked">
            <summary>Ví đã khoá trong giao dịch kèm số dư đọc SAU khoá (plan §3.4 "Xuất kho").</summary>
            <param name="Balance">Số dư = Σ dòng vào số dư (cùng luật <see cref="M:Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerPlanner.CountsInBalance(Lada.Framework.Data.Domains.Network.FranchiseWalletEntry)"/>).</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletLocked.#ctor(System.Int32,System.Int32,System.Decimal,System.Decimal,System.Boolean)">
            <summary>Ví đã khoá trong giao dịch kèm số dư đọc SAU khoá (plan §3.4 "Xuất kho").</summary>
            <param name="Balance">Số dư = Σ dòng vào số dư (cùng luật <see cref="M:Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerPlanner.CountsInBalance(Lada.Framework.Data.Domains.Network.FranchiseWalletEntry)"/>).</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletLocked.Balance">
            <summary>Số dư = Σ dòng vào số dư (cùng luật <see cref="M:Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerPlanner.CountsInBalance(Lada.Framework.Data.Domains.Network.FranchiseWalletEntry)"/>).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore">
            <summary>Tầng đọc / ghi của Ví — tách để luật lập kế hoạch và service test được không cần DB.</summary>
            <remarks>
            Mọi method nhận <paramref name="scope"/> tuỳ chọn: null = context riêng, tự commit (móc ngay sau SP, job đêm); có scope = đọc / ghi
            trong giao dịch của nơi gọi (xem <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope"/>).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.LoadOrderAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Đọc một đơn (null = không có / đã xoá).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.LoadEntriesAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Mọi dòng Ví của một đơn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.LoadWalletEnabledAgencyIdsAsync">
            <summary>
            Chi nhánh ĐÃ BẬT VÍ (<c>FranchiseWallet</c> Active, có <c>EnabledAt</c>) — chỉ chúng sinh dòng Ví v2 (plan v2 §1.1). Không theo
            <c>Agency.AgencyType</c>: bưu cục nhượng quyền chưa bật ví và chi nhánh LADA chưa bật ví đều là "vai trò LADA". Nhớ đệm 2 phút;
            bật ví gọi <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.InvalidateWalletCache"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.IsFranchiseInvolvedAsync(System.Int32,System.Int32,System.Collections.Generic.IReadOnlySet{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            Đơn có dính chi nhánh bật ví nào không (người thao tác, đơn vị giữ hàng, lấy, giao, dự kiến giao, bưu cục bán /
            tạo, chủ khách) hoặc đã có dòng Ví — đường tắt để móc sự kiện gần như không tốn gì với đơn của LADA.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.HasLadaHubInboundAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            V-65 (review H2): đơn đã từng được kho LADA quét nhập kho — track "Nhập vào kho" của người thuộc chi nhánh không phải bưu cục nhượng
            quyền. Đơn như vậy không phải đơn nội vùng dù lần nhập kho đó không chốt được cước (lỗi, hoặc bưu cục bật ví sau khi hàng vào kho).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.LoadUserAgencyIdsAsync(System.Collections.Generic.IEnumerable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Bưu cục hiện tại của người dùng (0 = không có).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.LoadCustomerOwnerAgencyIdAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Bưu cục sở hữu khách (null = chưa gán; 0 = LADA).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.LoadAgencyTypesAsync(System.Collections.Generic.IEnumerable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Loại chi nhánh (nhượng quyền / LADA) của các chi nhánh — thiếu = không có trong bảng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.StampDeliveryAssignedAsync(System.Int32,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Đóng dấu bên phát P lúc bưu cục bật ví quét nhận hàng chưa qua gán (§4.0 #9 đường B2) — chỉ khi cột còn NULL.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.ClearDeliveryAssignedAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Xoá dấu bên phát khi kho LADA nhận lại hàng (ReturnedToHub) — lần đối chiếu sau không giữ lại E2 / E3 cho bưu cục phát cũ (review GĐ B F2 / F4).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.ResolveRouteIdAsync(System.Int32,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Dải cự ly theo khoảng cách hai phường đã đo (null = chưa đo / không có dải).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.LoadPriceSourceAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Bản giá nội bộ đã duyệt kèm phạm vi và ô — nguồn giá cho bộ lập kế hoạch.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.StampOrderAsync(System.Int32,System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Đóng dấu các cột Ví trên đơn — chỉ ghi vào cột đang NULL, không bao giờ đè.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.StampCashierAgenciesAsync(System.Int32,System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Đóng dấu bưu cục người thu thực tế trên OrderFin — chỉ cột đang NULL.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.StampSourceFeeCollectedAsync(System.Int32,System.Decimal,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Ghi số lái xe thực thu của người gửi khi lấy (E1) — ghi đè lần lấy sau cùng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.MarkFranchiseHeldAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseHeldParts,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            V-60: khoản tiền người của bưu cục nhượng quyền bật ví đang cầm trên đơn Ví ghi → "Bưu cục giữ" (<c>FranchiseHeld</c>). Chỉ đổi từng
            khoản có tên trong <paramref name="parts"/>, khi khoản đó còn ở "Lái xe đang cầm" của đúng người ghi ở đó (không đè người khác đã thu).
            Trả số khoản đã đổi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.StampCodBelowFeeHoldAsync(System.Int32,System.Boolean,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Đặt / bỏ cờ giữ hàng đơn COD có tiền thu hộ nhỏ hơn cước (chặn ở xuất kho).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.LockOfficialFeeAsync(System.Int32,System.Decimal,System.Nullable{System.Int32},Lada.Framework.Data.Domains.Network.OfficialFeeSource,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            Chốt cước chính thức — CHỈ khi <c>OfficialFee</c> còn NULL (chốt một lần, mota §1 (a)). Trả true nếu vừa chốt, false nếu đã
            có người chốt trước (hai máy quét cùng lúc).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.LockWalletAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            Khoá ví của chi nhánh (<c>sp_getapplock</c> theo <c>WalletId</c>, chủ khoá = giao dịch của <paramref name="scope"/>) rồi đọc số dư
            SAU khoá — mẫu <c>SqlCashHolderLock</c>. null = chi nhánh chưa bật ví. Quá hạn chờ khoá → ném <see cref="T:System.TimeoutException"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.SavePlanAsync(Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerPlan,System.String,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            Ghi kế hoạch (chèn dòng, đổi trạng thái, cập nhật người thu) trong MỘT giao dịch (giao dịch riêng, hoặc của nơi gọi khi có scope).
            Chi nhánh thiếu ví → ném lỗi, không tự mở ví.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.SyncIssuesAsync(System.Int32,System.String,System.Collections.Generic.IReadOnlyCollection{System.String},System.DateTimeOffset,System.Boolean,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope,Lada.Framework.Data.Domains.Network.FranchiseLedgerIssueKind,System.Nullable{System.Int32})">
            <summary>
            Ghi sổ vấn đề của đơn: thêm / tăng đếm vấn đề còn gặp; <paramref name="resolveOthers"/> = tự đóng vấn đề không còn
            (lần đối chiếu đầy đủ), false = chỉ thêm (lỗi kỹ thuật giữa chừng không chứng minh vấn đề cũ đã hết). Vấn đề mới mang
            <paramref name="kind"/> / <paramref name="agencyId"/> (V-24); tự đóng chỉ chạm nhóm <see cref="M:Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerIssueKinds.ResolvedBy(Lada.Framework.Data.Domains.Network.FranchiseLedgerIssueKind)"/> của
            <paramref name="kind"/>. Trả số vấn đề MỚI ghi (để nơi gọi chỉ báo một lần).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.AppendIssueAsync(System.Int32,System.String,System.String,Lada.Framework.Data.Domains.Network.FranchiseLedgerIssueKind,System.DateTimeOffset)">
            <summary>
            Chèn THẲNG một vấn đề trên connection riêng tự commit, không đọc vấn đề đang mở (V-26): dùng ở nhánh lỗi khi giao dịch của nơi gọi
            còn mở — đọc sổ vấn đề của đơn đó sẽ chờ khoá dòng giao dịch kia vừa ghi tới hết hạn lệnh. Có thể trùng nội dung; lượt đối chiếu
            đầy đủ sau đó đóng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.FindRecheckOrderIdsAsync(System.DateTimeOffset,System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Int32)">
            <summary>Đơn cần đối chiếu lại: có cập nhật từ <paramref name="since"/> và dính tới chi nhánh bật ví, cộng đơn còn vấn đề mở.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.IsPriceVersionUsedAsync(System.Int32)">
            <summary>Có dòng Ví hoặc đơn nào tham chiếu bản giá này không (để chặn huỷ bản đã dùng — SPEC §3.3 mục 7).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.LoadWalletBalanceAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>
            Số dư hiện tại + ngưỡng cảnh báo của ví đang bật của chi nhánh (null = chưa bật ví). Có scope: đọc trong giao dịch của nơi gọi (thấy
            dòng vừa ghi chưa commit), KHÔNG khoá ví — chỉ để cảnh báo, không để quyết định tiền.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.TryMarkLowBalanceNotifiedAsync(System.Int32,System.DateTimeOffset)">
            <summary>
            Đánh dấu ví đã được báo "số dư dưới ngưỡng" hôm nay (giờ Việt Nam) — UPDATE có điều kiện chưa báo hôm nay, trả true nếu lần này
            là lần đánh dấu (nơi gọi gửi thông báo). LUÔN chạy trên connection riêng tự commit, không qua giao dịch của nơi gọi: giữ khoá dòng
            <c>FranchiseWallet</c> tới cuối giao dịch xuất kho sẽ chặn chính truy vấn danh sách ví bật (context riêng) của cùng request.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore"/>
            <remarks>
            Không có scope: mỗi lời gọi dùng một <see cref="T:Lada.Framework.Data.Mappings.DbContexts.LadaDbContext"/> RIÊNG dựng từ options: (1) đọc được trạng thái mới nhất mà SP vừa
            ghi — DbContext dùng chung của request đang giữ bản <c>OrderOps</c> cũ nạp trước SP; (2) <c>SaveChanges</c> của Ví không vô tình
            lưu thay đổi dở dang của service đang gọi. Có scope: dùng context bọc của scope (cùng connection + transaction của nơi gọi).
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.DeliveryFailTrackPrefix">
            <summary>
            Tên track giao thất bại do <c>SP_UpdateOrderDeliveryFail</c> ghi. App lái xe trước GĐ B2 (26/10/2026) không truyền
            <c>@TrackActionType</c> nên SP ghi mặc định 7 (= <see cref="F:Lada.Framework.Data.Enums.TrackActionType.Inbound"/> trong enum) — dev có 59.995 dòng mã 7, 0 dòng
            153 — vì vậy dấu vết "đã từng giao thất bại" (V-19) phải đọc cả dòng cũ theo tên.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.Lease">
            <summary>Context mượn: của scope (không dispose) hoặc mới (dispose khi xong).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.LoadOrderAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.LoadEntriesAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.InvalidateWalletCache">
            <summary>Xoá đệm danh sách chi nhánh bật ví — gọi ngay sau khi bật / tắt ví để móc sự kiện thấy ngay.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.LoadWalletEnabledAgencyIdsAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.IsFranchiseInvolvedAsync(System.Int32,System.Int32,System.Collections.Generic.IReadOnlySet{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.HasLadaHubInboundAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.LoadUserAgencyIdsAsync(System.Collections.Generic.IEnumerable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.LoadCustomerOwnerAgencyIdAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.LoadAgencyTypesAsync(System.Collections.Generic.IEnumerable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.StampDeliveryAssignedAsync(System.Int32,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.ClearDeliveryAssignedAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.ResolveRouteIdAsync(System.Int32,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.LoadPriceSourceAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.StampOrderAsync(System.Int32,System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.StampCashierAgenciesAsync(System.Int32,System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.StampSourceFeeCollectedAsync(System.Int32,System.Decimal,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.MarkFranchiseHeldAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseHeldParts,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.StampCodBelowFeeHoldAsync(System.Int32,System.Boolean,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.LockOfficialFeeAsync(System.Int32,System.Decimal,System.Nullable{System.Int32},Lada.Framework.Data.Domains.Network.OfficialFeeSource,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.WalletLockResource(System.Int32)">
            <summary>Tên tài nguyên khoá ví trong <c>sp_getapplock</c> (cùng họ "lada:" với khoá người cầm tiền).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.LockWalletAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.SavePlanAsync(Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerPlan,System.String,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.SyncIssuesAsync(System.Int32,System.String,System.Collections.Generic.IReadOnlyCollection{System.String},System.DateTimeOffset,System.Boolean,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope,Lada.Framework.Data.Domains.Network.FranchiseLedgerIssueKind,System.Nullable{System.Int32})">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.AppendIssueAsync(System.Int32,System.String,System.String,Lada.Framework.Data.Domains.Network.FranchiseLedgerIssueKind,System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.FindRecheckOrderIdsAsync(System.DateTimeOffset,System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.IsPriceVersionUsedAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.LoadWalletBalanceAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.TryMarkLowBalanceNotifiedAsync(System.Int32,System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerStore.SumBalanceAsync(Lada.Framework.Data.Mappings.DbContexts.LadaDbContext,System.Int32)">
            <summary>Số dư = Σ dòng vào số dư của ví (cùng luật <see cref="M:Lada.Framework.Infrastructures.Services.Network.FranchiseLedgerPlanner.CountsInBalance(Lada.Framework.Data.Domains.Network.FranchiseWalletEntry)"/>).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceLedgerPriceSource">
            <summary>Nguồn bản giá nội bộ nạp sẵn vào bộ nhớ — một lần cho cả lượt đối chiếu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceLedgerPriceSource.Effective(Lada.Framework.Data.Domains.Network.InternalPriceTableKind,System.Int32,System.DateTime)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceLedgerPriceSource.Version(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseNotifier">
            <summary>
            Thông báo cho bưu cục nhượng quyền (SPEC §3.11, GĐ5): bản giá nội bộ vừa duyệt / sắp áp dụng, phiếu đối soát vừa phát
            hành / tới hạn tự xác nhận. Người nhận = user THUỘC bưu cục có role tương ứng + <c>Agency.ManagerId</c> nếu có.
            </summary>
            <remarks>
            Không bao giờ ném lỗi ra nơi gọi: thông báo hỏng không được làm hỏng thao tác duyệt / phát hành. Bưu cục nhận bản giá do
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService"/> tính (bản riêng của bưu cục thắng bản toàn mạng — bưu cục đó không nhận tin bản toàn
            mạng không áp cho mình).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseNotifier.NotifyInternalPriceApprovedAsync(Lada.Framework.Data.Domains.Network.InternalPriceVersion,System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>Bản giá vừa duyệt — gửi cho bưu cục mà bản này áp vào ngày bắt đầu; trả số người nhận.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseNotifier.NotifyInternalPriceEffectiveSoonAsync(Lada.Framework.Data.Domains.Network.InternalPriceVersion,System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Int32)">
            <summary>Nhắc bản sắp áp dụng sau <paramref name="daysLeft"/> ngày; trả số người nhận.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseNotifier.NotifySettlementPublishedAsync(Lada.Framework.Data.Domains.Network.FranchiseSettlement)">
            <summary>Phiếu tháng vừa phát hành; trả số người nhận.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseNotifier.NotifySettlementAutoConfirmSoonAsync(System.DateTime)">
            <summary>Nhắc phiếu có hạn xác nhận là hôm nay (job hằng ngày); trả số người nhận.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseNotifier.NotifyOrderHoldAsync(System.Int32,System.Int32,System.String,System.String)">
            <summary>
            Ví v2: đơn bị giữ hàng (tiền thu hộ nhỏ hơn cước / hình thức trả cước không hợp lệ) — báo bưu cục BÁN sửa trước khi xuất kho;
            tối đa một lần mỗi đơn mỗi ngày. Trả số người nhận.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseNotifier.NotifyWithdrawalRequestedAsync(Lada.Framework.Data.Domains.Network.FranchiseWalletWithdrawal,System.String)">
            <summary>Ví v2 GĐ C: bưu cục vừa tạo lệnh rút (ví đã trừ) — báo mọi người có role kế toán quỹ (<c>FranchiseWallet.Treasury</c>). Trả số người nhận.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseNotifier.NotifyWithdrawalResultAsync(Lada.Framework.Data.Domains.Network.FranchiseWalletWithdrawal,System.String)">
            <summary>Ví v2 GĐ C: lệnh rút đã chuyển tiền / bị từ chối / tự huỷ — báo bưu cục chủ ví (role View hoặc Withdraw + quản lý bưu cục). Trả số người nhận.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseNotifier.NotifyDepositRecordedAsync(Lada.Framework.Data.Domains.Network.FranchiseWalletDeposit,System.Decimal)">
            <summary>Ví v2 GĐ C: kế toán vừa ghi nhận tiền nạp — báo bưu cục chủ ví kèm số dư sau nạp. Trả số người nhận.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseNotifier.NotifyLowBalanceAsync(System.Int32,System.Decimal,System.Decimal)">
            <summary>
            Ví v2 GĐ C: số dư dưới ngưỡng cảnh báo — báo bưu cục (role View + quản lý bưu cục) và quản lý khu vực (chi nhánh cha loại
            <c>Region</c>). Nơi gọi chống nhắc trùng theo ngày (<c>FranchiseWallet.LastLowBalanceNotifiedAt</c>). Trả số người nhận.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseNotifier.NotifyInvariantBrokenAsync(System.Int32,System.String,System.String)">
            <summary>
            Ví v2 GĐ C2 (T17): job đêm thấy đơn đã kết thúc lệch bất biến — báo kế toán (role <c>FranchiseWallet.Manage</c> và, từ V-68 — anh Thắng
            27/10/2026, cả <c>FranchiseWallet.Config</c> của kế toán trưởng; người của LADA nên không lọc chi nhánh). Nơi gọi chỉ báo khi vấn đề mới
            ghi lần đầu. Trả số người nhận.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseNotifier"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.NotifyInternalPriceApprovedAsync(Lada.Framework.Data.Domains.Network.InternalPriceVersion,System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.NotifyInternalPriceEffectiveSoonAsync(Lada.Framework.Data.Domains.Network.InternalPriceVersion,System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.NotifySettlementPublishedAsync(Lada.Framework.Data.Domains.Network.FranchiseSettlement)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.NotifySettlementAutoConfirmSoonAsync(System.DateTime)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.NotifyOrderHoldAsync(System.Int32,System.Int32,System.String,System.String)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.NotifyWithdrawalRequestedAsync(Lada.Framework.Data.Domains.Network.FranchiseWalletWithdrawal,System.String)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.NotifyWithdrawalResultAsync(Lada.Framework.Data.Domains.Network.FranchiseWalletWithdrawal,System.String)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.NotifyDepositRecordedAsync(Lada.Framework.Data.Domains.Network.FranchiseWalletDeposit,System.Decimal)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.NotifyLowBalanceAsync(System.Int32,System.Decimal,System.Decimal)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.NotifyInvariantBrokenAsync(System.Int32,System.String,System.String)">
            <inheritdoc/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.InvariantRecipientRoles">
            <summary>
            Người nhận cảnh báo lệch T17: kế toán quản lý ví + kế toán trưởng (cấu hình ví). V-68 bấm G1: chỉ <c>Manage</c> thì production không ai
            giữ role là không ai biết lệch, kế toán trưởng không nhận.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.MoneyLabel(System.Decimal)">
            <summary>"1.250.000 đ" — số âm giữ dấu (ví âm).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.BankLabel(System.String,System.String,System.String)">
            <summary>"Vietcombank · 0123456789 · NGUYEN VAN A" — thiếu phần nào bỏ phần đó; trống hết = "tài khoản chưa khai".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.RemindedTodayAsync(System.String,System.String,System.Int32)">
            <summary>
            Lời nhắc này (loại + bản / phiếu) đã gửi trong hôm nay (giờ Việt Nam) chưa. Job nhắc chạy lại trong ngày — bấm "Chạy
            ngay", Hangfire thử lại sau lỗi — không được nhắc trùng (bấm thử 19/10/2026: hai lần kích job → hai tin giống hệt).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.ReminderMarks(System.String,System.String,System.Int32)">
            <summary>
            Hai chuỗi nhận ra một lời nhắc trong <c>Notification.ActionData</c> — JSON của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.PriceData(System.String,Lada.Framework.Data.Domains.Network.InternalPriceVersion,System.Nullable{System.Int32})"/> /
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.SettlementData(System.String,Lada.Framework.Data.Domains.Network.FranchiseSettlement)"/> do <c>NotificationService</c> ghi bằng System.Text.Json.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.RecipientsAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},System.String[])">
            <summary>User thuộc các bưu cục và có một trong các role (UserRole ∪ nhóm quyền), cộng Agency.ManagerId — đã loại trùng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.PriceData(System.String,Lada.Framework.Data.Domains.Network.InternalPriceVersion,System.Nullable{System.Int32})">
            <summary>Dữ liệu điền mẫu thông báo bản giá. Không nêu bưu cục khác cùng phạm vi (QUYET-DINH-TAM T14).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.SettlementData(System.String,Lada.Framework.Data.Domains.Network.FranchiseSettlement)">
            <summary>Dữ liệu điền mẫu thông báo phiếu; số ròng ghi rõ chiều trả tiền.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseNotifier.NetLabel(System.Decimal)">
            <summary>"1.250.000 đ (LADA trả bưu cục)" / "(bưu cục trả LADA)" / "0 đ".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePackageTierService">
            <summary>
            Màn tham số bốn bậc gói vùng phủ <c>/mang-luoi/bang-gia-nhuong-quyen/goi</c> (GĐ K, plan cổng §6.16, §6.17): xem
            (<c>FranchisePrice.Export</c> / <c>Manage</c>) và sửa cả bộ (<c>Manage</c>). Không thêm / xoá bậc — bốn dòng seed
            bằng migration. Gói không gắn tay cho mã nữa: mã chỉ mang phường/xã, bậc tự xếp bằng
            <see cref="M:Lada.Framework.Infrastructures.Services.Network.FranchisePackageTierRules.TierFor(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Network.FranchisePackageTier},System.Int32)"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePackageTierService.GetAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceActor)">
            <summary>Mọi bậc theo thứ tự ngưỡng; null = không có quyền xem.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePackageTierService.ToItems(System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Network.FranchisePackageTier})">
            <summary>Bậc → dòng hiển thị; dùng chung cho màn tham số và ô chọn phường của sale.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePackageTierService.Stamp(System.Collections.Generic.IEnumerable{Lada.Framework.Data.Domains.Network.FranchisePackageTier})">
            <summary>Dấu phiên bản của cả bộ — đổi khi bất kỳ bậc nào được lưu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePackageTierService.Apply(Lada.Framework.Data.Domains.Network.FranchisePackageTier,Lada.Framework.Data.Domains.Network.FranchisePackageTier)">
            <summary>Chép bản nháp vào dòng thật; true = có ô đổi.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeStates">
            <summary>
            Trạng thái hiển thị của một mã truy cập, tính tại lúc đọc (hết hạn không phải cột — plan §3.1). Bốn mã dưới đây
            cũng là giá trị bộ lọc <c>status</c> của danh sách.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeSearchFilter">
            <summary>
            Bộ lọc của `POST search` (ô chọn mã "Hỏi thử" ở màn Cấu hình trợ lý — màn Mã truy cập đã bỏ ở GĐ L, plan §6.23),
            đọc từ <c>Search.PredicateObject</c>. Khoá (không phân biệt hoa thường):
            <list type="bullet">
            <item><c>globalSearch</c> — cả mã <c>NQ-XXXX-XXXX</c> tìm đúng mã đó (so băm có khoá); gõ dở <c>NQ-AB…</c> tới
            <c>NQ-ABCD-234</c> tìm theo tối đa 4 ký tự đầu; dãy số (kể cả có dấu cách/chấm/gạch) tìm trong SĐT khách; còn lại
            tìm tên khách, SĐT.</item>
            <item><c>status</c> — <c>active</c> (còn hạn, gồm cả sắp hết hạn) · <c>expiring</c> (còn ≤ 2 ngày) ·
            <c>expired</c> · <c>revoked</c>.</item>
            <item><c>provinceCode</c> — mã có giới hạn tỉnh chứa đúng tỉnh này (mã không giới hạn tỉnh không khớp).</item>
            <item><c>priceScope</c> — <c>none</c> (chưa gắn phường nào) · <c>below</c> (có phường nhưng chưa đủ gói vùng phủ — ít
            hơn ngưỡng của bậc đầu, khách thấy câu "cần từ 3 phường…").</item>
            <item><c>fromDate</c>, <c>toDate</c> — ngày tạo, theo giờ Việt Nam, gồm cả hai đầu.</item>
            </list>
            Giá trị sai kiểu bị bỏ qua, không ném lỗi (cùng lệ <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadSearchFilter"/>).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeSearchFilter.PriceScopeNone">
            <summary>Giá trị bộ lọc <c>priceScope</c>: mã chưa gắn phạm vi giá nào.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeSearchFilter.PriceScopeBelow">
            <summary>Giá trị bộ lọc <c>priceScope</c>: mã có phường nhưng chưa đủ gói vùng phủ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeSearchFilter.Apply(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchisePortalAccessCode},System.DateTimeOffset,Lada.Framework.Infrastructures.Services.Network.IFranchisePortalCodeHasher,System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchisePortalAccessPriceItem},System.Nullable{System.Int32})">
            <param name="codeHasher">Băm có khoá để tìm theo CẢ mã; máy chủ chưa có khoá thì tìm cả mã không ra dòng nào.</param>
            <param name="priceItems">Dòng phạm vi giá của các mã — cho bộ lọc <c>priceScope</c>. Chỉ dòng PHƯỜNG được tính:
            dòng gói "Toàn tỉnh / Cấp 1" cũ để ngủ (GĐ K) không còn là phạm vi giá.</param>
            <param name="entryTierMinWards">Ngưỡng phường của bậc gói đầu (POINT) — cho <c>priceScope = below</c>; null = bảng
            bậc trống, không mã nào "chưa đủ gói".</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeSearchFilter.Sort(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchisePortalAccessCode},Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Sắp xếp theo danh sách cột cho phép (<c>Sort.Predicate</c>); mặc định mới tạo trước. Cột lạ rơi về mặc định —
            không sắp theo tên property tuỳ ý từ client.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeSearchFilter.CodePrefixOf(System.String)">
            <summary>
            Phần so được với <c>CodePrefix</c> khi người dùng gõ dở mã (<c>NQ-AB</c>, <c>NQ-ABCD-2</c>); <c>null</c> khi
            không phải dạng đó. Database chỉ giữ rõ 4 ký tự đầu của thân mã nên gõ tới ký tự thứ 5–7 vẫn chỉ khớp theo 4 ký
            tự đầu — ra mọi mã cùng đầu, đủ 8 ký tự mới tìm đúng một mã (so băm).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalSectionTotalRow">
            <summary>Một dòng tổng theo mục của dấu vết — kết quả <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalEventQueries.SectionTotals(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchisePortalEvent},System.Int32)"/>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalEventQueries">
            <summary>
            Truy vấn dấu vết của MỘT mã truy cập — hàm thuần trên <c>IQueryable</c> để có ca test dịch SQL thật (test
            in-memory không bắt được lỗi dịch <c>GroupBy</c>). Phạm vi (mã có thuộc người gọi không) kiểm ở service TRƯỚC khi
            gọi vào đây.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalEventQueries.Timeline(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchisePortalEvent},System.Int32)">
            <summary>Dòng thời gian, mới nhất trước.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalEventQueries.SectionTotals(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchisePortalEvent},System.Int32)">
            <summary>
            Tổng theo mục: thời gian xem = tổng <c>DurationSec</c> của các lần rời mục (<c>SectionLeave</c>), số lần mở =
            số sự kiện <c>SectionOpen</c>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeService">
            <summary>
            Màn quản trị "Mã truy cập" của Cổng nhượng quyền (docs/plan-cong-nhuong-quyen.md §3.2, §3.10).
            <see cref="T:Lada.Framework.Data.Domains.Network.FranchisePortalAccessCode"/> là chìa vào nội dung riêng tư và chứa dữ liệu cá nhân của khách: MỌI đường
            đọc/ghi đi qua <see cref="!:ScopedAsync"/> — người chỉ có <c>FranchisePortal.Sale</c> chỉ chạm được mã của đăng ký
            nhượng quyền mình phụ trách (plan §6.23); ngoài phạm vi trả "không tìm thấy". Mọi đường GHI kèm một dòng <see cref="T:Lada.Framework.Data.Domains.Network.FranchisePortalAccessHistory"/>
            trong cùng transaction.
            </summary>
            <remarks>
            Dòng mã đã có KHÔNG BAO GIỜ ghi bằng <c>UpdateAsync</c> của repository (UPDATE mọi cột từ ảnh chụp lúc đọc — hồi
            sinh mã vừa thu hồi, đè bộ đếm website ghi): mọi thay đổi đi qua <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeStore"/>.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeService.GetByIdAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Chi tiết kèm mã rõ, trạng thái mở/khoá từng mục, lịch sử gần nhất; <c>null</c> khi không có hoặc ngoài phạm vi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeService.CreateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAccessCodeCreateModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>
            Tạo mã cho khách của một đăng ký nhượng quyền (plan §6.23): chỉ người phụ trách đăng ký, và đăng ký chưa có mã
            chưa thu hồi. Mã sinh ở máy chủ, trả rõ trong kết quả; database giữ băm + bản mã hoá. Mặc định chưa mở mục nào.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeService.UnlockAsync(System.Int32,System.Collections.Generic.IReadOnlyCollection{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Mở các mục cho mã — chỉ mục đang bật; mục đang tắt/không có bị bỏ qua.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeService.UnlockAllAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Mở mọi mục đang bật.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeService.LockAsync(System.Int32,System.Collections.Generic.IReadOnlyCollection{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Khoá lại các mục.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeService.ExtendAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Gia hạn +7 ngày theo <see cref="M:Lada.Framework.Infrastructures.Services.Network.FranchisePortalAccessRules.ExtendedExpiry(Lada.Framework.Data.Domains.Network.FranchisePortalAccessCode,System.DateTimeOffset)"/>; mã đã thu hồi không gia hạn được.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeService.RevokeAsync(System.Int32,System.String,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Thu hồi mã ngay lập tức và đóng mọi phiên đang mở của nó.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeService.GetHistoryAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Lịch sử thao tác, mới nhất trước; <c>null</c> khi không có hoặc ngoài phạm vi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeService.SetPriceScopeAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalPriceScopeModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>
            Gắn phạm vi giá cho mã: các phường/xã 2 cấp ở một hay nhiều tỉnh CÓ GIÁ ở phiên bản giá hiện hành (§6.17, §6.26 —
            không đòi vùng phủ); không phường = gỡ. Khách mở mục "Bảng giá vùng phủ" của cổng chỉ thấy đúng thứ đã gắn
            (plan cổng §6.10).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeService.GetEventsAsync(System.Int32,System.Int32,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Dấu vết của khách: một trang sự kiện + tổng thời gian theo mục; <c>null</c> khi không có hoặc ngoài phạm vi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeService.GetChatAsync(System.Int32,System.Int32,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>
            Transcript hỏi-đáp với trợ lý AI của một mã (tab Hỏi đáp, GĐ G): một trang tin nhắn mới trước + bộ đếm câu hỏi;
            null khi mã không có hoặc ngoài phạm vi.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.MaxPageSize">
            <summary>Khớp lựa chọn lớn nhất của bộ phân trang FE (<c>pageSizeOptions</c> tới 200).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.ScopedAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Phạm vi mã truy cập của người thao tác — MỘT chỗ cho mọi đường đọc/ghi của service này.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.FindScopedAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>
            Mã theo Id TRONG phạm vi của người thao tác; ngoài phạm vi trả <c>null</c> như không tồn tại. Ảnh chụp chỉ để
            ĐỌC (không theo dõi) — ghi thì qua <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService._store"/>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.PriceSummary">
            <summary>Tóm tắt phạm vi giá của một mã cho cột "Phạm vi giá" của danh sách.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.PriceSummary.#ctor(System.String,System.String,System.String)">
            <summary>Tóm tắt phạm vi giá của một mã cho cột "Phạm vi giá" của danh sách.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.ReadTiersAsync">
            <summary>Bốn bậc gói vùng phủ theo thứ tự ngưỡng (GĐ K).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.Summarize(Lada.Framework.Infrastructures.Services.Network.FranchisePackageTierMatch,System.String)">
            <summary>"7 phường, xã · HUB" / "2 phường, xã · chưa đủ gói"; bảng bậc trống thì chỉ số phường.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.ReadPriceSummariesAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>
            Tóm tắt phạm vi giá của MỘT TRANG mã — ba truy vấn cho cả trang (dòng phường, tỉnh, bậc gói), không theo từng
            dòng. Mã không có trong kết quả = chưa gắn gì. Chỉ gọi với Id đã qua <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.ScopedAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.JoinProvinces(System.Collections.Generic.IEnumerable{System.Int32},System.Collections.Generic.IReadOnlyDictionary{System.Int32,System.String})">
            <summary>Tên các tỉnh theo thứ tự xuất hiện đầu tiên, cách nhau dấu phẩy.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.ReadPriceScopeAsync(System.Int32,System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Network.FranchisePackageTier})">
            <summary>Phạm vi giá đang gắn cho mã — null khi chưa gắn phường nào.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.CreateOwnerError(System.Nullable{System.Int32},System.String,System.Int32,System.String)">
            <summary>
            Câu từ chối khi người tạo không phải người phụ trách đăng ký (plan §6.23 mục 3 — kể cả quản lý); <c>null</c> = được
            tạo. Một hàm cho lần kiểm sớm và lần kiểm sau khi khoá dòng đăng ký.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.LiveCodeOfLeadAsync(System.Int32)">
            <summary>Mã chưa thu hồi (kể cả đã hết hạn) của một đăng ký, mới nhất trước; <c>null</c> khi không có.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.UnlockCoreAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor,System.Func{System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchisePortalSection},System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchisePortalSection}})">
            <param name="pick">Chọn trong các mục ĐANG BẬT — mục đang tắt không bao giờ được mở thêm.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.NewCodeAsync">
            <summary>Mã mới chưa trùng băm với mã nào (kể cả mã đã xoá). 2^40 khả năng nên trùng gần như không xảy ra.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.NormalizeProvinceCodes(System.Collections.Generic.IEnumerable{System.String})">
            <summary>Danh sách mã tỉnh đã chuẩn hoá thành chuỗi <c>01,31</c> (null = mọi tỉnh), hoặc câu từ chối.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeService.SaveWithHistoryAsync(System.Func{System.Threading.Tasks.Task{System.Boolean}},System.Func{Lada.Framework.Data.Domains.Network.FranchisePortalAccessHistory})">
            <summary>
            Ghi thay đổi của mã và dòng lịch sử của nó trong MỘT transaction. <paramref name="buildHistory"/> chạy SAU khi
            lưu để đọc được Id vừa sinh của mã mới. <paramref name="save"/> trả <c>false</c> (không dòng nào khớp điều kiện
            ghi) thì hoàn tác, KHÔNG ghi lịch sử và trả <c>false</c>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeWriteConditions">
            <summary>
            Điều kiện <c>WHERE</c> của từng đường ghi lên một mã truy cập — MỘT nguồn cho store thật và store giả của test,
            để bỏ một điều kiện ở đây là đỏ ở cả hai nơi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeWriteConditions.Extend(System.Int32,System.DateTimeOffset)">
            <summary>Gia hạn: mã chưa thu hồi VÀ hạn vẫn đúng như lúc đọc — hai lần bấm song song chỉ cộng một lần.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeWriteConditions.Revoke(System.Int32)">
            <summary>Thu hồi: chỉ mã chưa thu hồi — lần thu hồi thứ hai không đè người/lúc/lý do của lần đầu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeWriteConditions.TouchActive(System.Int32)">
            <summary>Đóng dấu sửa lên mã CHƯA thu hồi — đổi phạm vi giá của mã đã thu hồi thì không dòng nào khớp.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeWriteConditions.MarkLeadAccessCodeIssued(System.Int32,Lada.Framework.Data.Domains.Network.FranchiseLeadStatus)">
            <summary>Đổi trạng thái đăng ký khi cấp mã: trạng thái vẫn là trạng thái vừa đọc — không đè thứ sale vừa chọn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessCodeWriteConditions.OpenVisits(System.Int32)">
            <summary>Phiên đang mở của một mã.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeStore">
            <summary>
            Ghi lên dòng <see cref="T:Lada.Framework.Data.Domains.Network.FranchisePortalAccessCode"/> bằng MỘT lệnh <c>UPDATE</c> chỉ chạm đúng cột của thao tác,
            điều kiện nằm ở <c>WHERE</c> (review GĐ A, mục 1). <c>Repository.UpdateAsync</c> ghi MỌI cột từ ảnh chụp lúc đọc:
            "Gia hạn" chạy song song với "Thu hồi" ghi lại <c>Status = Active</c> — mã vừa thu hồi sống lại; và từ GĐ B
            website tăng <c>AccessCount</c>/<c>LastAccessAt</c>/<c>QuestionCount</c> trên cùng dòng, thao tác của sale đè số
            cũ lên. Tách thành store riêng để service test được bằng repo giả (<c>ExecuteUpdateAsync</c> chỉ chạy trên EF
            thật) — cùng khuôn <c>ITopicPublishStore</c>.
            </summary>
            <remarks>Mọi hàm trả <c>false</c>/0 khi không dòng nào khớp điều kiện — người gọi coi là "đã bị người khác đổi".</remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeStore.ExtendAsync(System.Int32,System.DateTimeOffset,System.DateTimeOffset,System.DateTimeOffset,System.Int32,System.String)">
            <summary>Ghi hạn mới. Chỉ chạm <c>ExpiresAt</c> + cột audit.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeStore.RevokeAsync(System.Int32,System.String,System.DateTimeOffset,System.Int32,System.String)">
            <summary>Thu hồi. Chỉ chạm <c>Status</c>, nhóm cột <c>Revoked*</c> + cột audit.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeStore.LockLeadAsync(System.Int32)">
            <summary>
            Khoá dòng đăng ký nhượng quyền tới hết transaction đang mở bằng một lệnh <c>UPDATE</c> không đổi giá trị nào
            (<c>Status = Status</c>) — gọi ở ĐẦU transaction tạo mã: hai lần tạo mã song song cho cùng một đăng ký chạy lần
            lượt, lần sau đọc được mã lần trước vừa tạo (luật một mã chưa thu hồi mỗi đăng ký, plan §6.23). Không đụng cột
            audit của đăng ký — cột "Cập nhật" của màn Đăng ký không đổi. <c>false</c> khi đăng ký không còn (đã xoá).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeStore.MarkLeadAccessCodeIssuedAsync(System.Int32,Lada.Framework.Data.Domains.Network.FranchiseLeadStatus,System.String,System.DateTimeOffset,System.Int32,System.String)">
            <summary>
            Đăng ký vừa được cấp mã → trạng thái <see cref="F:Lada.Framework.Data.Domains.Network.FranchiseLeadStatus.AccessCodeIssued"/> kèm MỘT dòng lịch sử
            "Đổi trạng thái" (plan §6.23 mục 8). Chỉ chạm <c>Status</c> + cột audit của đăng ký — <c>StatusNote</c> của sale
            giữ nguyên; điều kiện ở <c>WHERE</c> là "vẫn là <paramref name="expectedStatus"/>". Gọi TRONG transaction tạo mã
            (sau <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeStore.LockLeadAsync(System.Int32)"/>); <c>false</c> khi không dòng nào khớp — không ghi lịch sử.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeStore.EndOpenVisitsAsync(System.Int32,System.DateTimeOffset,System.Int32,System.String)">
            <summary>Đóng mọi phiên đang mở của mã (chỉ chạm <c>EndedAt</c> + cột audit); trả số phiên vừa đóng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAccessCodeStore.TouchActiveAsync(System.Int32,System.DateTimeOffset,System.Int32,System.String)">
            <summary>
            Đóng dấu "vừa sửa" lên mã chưa thu hồi — chỉ chạm cột audit. Gọi ở ĐẦU transaction của thao tác thay cả bộ
            dòng con (phạm vi giá): lệnh <c>UPDATE</c> giữ khoá dòng mã tới khi commit, nên hai người cùng đổi phạm vi giá
            của một mã chạy lần lượt thay vì để lại bộ dòng trộn của cả hai; mã vừa bị thu hồi thì trả <c>false</c>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAssistantService">
            <summary>
            Màn "Cấu hình trợ lý" của Cổng nhượng quyền (plan §3.6, GĐ G — đóng CNQ-50 phía API): đọc / ghi các khoá
            <c>FranchisePortal.Ai.*</c> và "Hỏi thử" trợ lý với ngữ cảnh của một mã. Chỉ người có cờ <c>CanConfigure</c>
            (<c>FranchisePortal.Manage</c>; Founder) — kiểm lần hai ở đây ngoài <c>[Authorize]</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAssistantService.GetConfigAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <returns>null khi người gọi không có cờ <c>CanConfigure</c>.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalAssistantService.AskTestAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalAssistantTestModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor,System.Threading.CancellationToken)">
            <summary>
            Hỏi trợ lý một câu với ngữ cảnh của một mã TRONG PHẠM VI người gọi — đúng ngữ cảnh khách cầm mã đó sẽ có. Không
            lưu vào transcript, không trừ lượt hỏi của khách.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAssistantService.ProviderChangedWhileEditingMessage">
            <summary>Lưu với dấu của bản form đã cũ — câu khác <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAssistantService.ProviderChangedMessage"/>: trợ lý chưa chắc đang tắt (review FE G2b).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAssistantService.ModelIds(System.String)">
            <summary>Id model từ danh sách đã đồng bộ của nhà cung cấp (<c>SyncedModelsJson</c>: mảng <c>AiModelInfo</c>).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalFileUpload">
            <summary>Một tệp đang tải lên — controller đóng gói từ <c>IFormFile</c>. <paramref name="Content"/> phải seek được.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalFileUpload.#ctor(System.IO.Stream,System.Int64,System.String,Lada.Framework.Data.Enums.FranchisePortalFileKind,System.Nullable{System.Int32},System.String)">
            <summary>Một tệp đang tải lên — controller đóng gói từ <c>IFormFile</c>. <paramref name="Content"/> phải seek được.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalFileType">
            <summary>Định dạng tệp đã nhận ra từ NỘI DUNG (magic bytes), không phải từ tên hay <c>Content-Type</c> trình duyệt gửi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalFileType.#ctor(System.String,System.String)">
            <summary>Định dạng tệp đã nhận ra từ NỘI DUNG (magic bytes), không phải từ tên hay <c>Content-Type</c> trình duyệt gửi.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalFileRules">
            <summary>
            Luật nhận tệp riêng tư của Cổng nhượng quyền (plan §3.4, §3.10) — hàm thuần: whitelist phần mở rộng và trần kích
            thước theo loại, nhận dạng bằng magic bytes.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalFileRules.AllowedExtensions(Lada.Framework.Data.Enums.FranchisePortalFileKind)">
            <summary>Phần mở rộng nhận theo loại; loại không tải lên được (audio thuyết minh do hệ thống sinh) → rỗng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalFileRules.Detect(Lada.Framework.Data.Enums.FranchisePortalFileKind,System.String,System.IO.Stream)">
            <summary>
            Nhận dạng tệp: phần mở rộng phải thuộc whitelist của <paramref name="kind"/> VÀ nội dung phải đúng định dạng
            đó. Trả định dạng, hoặc câu từ chối. Vị trí đọc của <paramref name="content"/> được trả về đầu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalFileRules.IsOfficeDocument(System.Byte[],System.Int32,System.IO.Stream,System.String)">
            <summary>
            Tệp Office Open XML: là ZIP, có phần tài liệu chính của đúng loại, và KHÔNG mang macro (<c>vbaProject.bin</c> —
            tệp .docm/.xlsm đổi đuôi).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalFileService">
            <summary>
            Tệp riêng tư của Cổng nhượng quyền (docs/plan-cong-nhuong-quyen.md §3.4, §6.5): tải lên, liệt kê, xoá. Nội dung
            nằm trên ổ đĩa qua <see cref="T:Lada.Framework.Infrastructures.Services.Network.IFranchisePortalFileStorage"/>; khách chỉ đọc được qua đường <c>/tep</c> của website
            sau khi kiểm mục của tệp đã mở cho mã.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalFileService.UploadAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalFileUpload,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor,System.Threading.CancellationToken)">
            <summary>
            Kiểm loại + magic bytes + kích thước, ghi đĩa RỒI MỚI ghi database; ghi database lỗi thì xoá tệp vừa ghi.
            PDF được trích văn bản cho trợ lý AI — trích lỗi vẫn lưu tệp.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalFileService.ListAsync(System.Nullable{System.Int32})">
            <summary>Tệp của một mục (hoặc mọi tệp khi <paramref name="sectionId"/> null), theo thứ tự.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalFileService.DeleteAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>
            Xoá mềm bản ghi rồi xoá tệp vật lý. Từ chối khi tệp đang là audio thuyết minh của một mục, hoặc đang được khối
            nội dung của mục dùng — trong bản đã xuất bản (khách đang thấy) hay bản đang sửa (CNQ-32).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalFileService.MaxExtractPages">
            <summary>Trần số trang PDF đem trích trong request tải lên — PDF scan phải OCR từng trang.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalFileService.FindBlockUseAsync(Lada.Framework.Data.Domains.Network.FranchisePortalFile)">
            <summary>
            Câu từ chối khi tệp đang nằm trong khối nội dung của mục nó thuộc về; <c>null</c> = không khối nào dùng. Bản đã
            xuất bản xét TRƯỚC: xoá tệp khách đang thấy là trang của khách mất tài liệu / video mà không ai được báo
            (website tự gỡ lúc đọc). Bản đang sửa: xoá xong thì lần lưu / xuất bản kế tiếp bị từ chối vì tham chiếu treo.
            Khối chỉ tham chiếu được tệp của ĐÚNG mục (<c>TopicService.CheckFileRef</c>) nên chỉ cần soát topic của mục đó.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalFileService.ExtractTextAsync(System.IO.Stream,System.String,System.Threading.CancellationToken)">
            <summary>Văn bản của PDF cho trợ lý AI; trích lỗi hoặc không có chữ → <c>null</c>, không chặn việc lưu tệp.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalFileService.SafeFileName(System.String,System.String)">
            <summary>Tên gốc để hiển thị: bỏ đường dẫn và ký tự điều khiển, cắt cho vừa cột, giữ phần mở rộng đã nhận dạng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalNavPermissions">
            <summary>
            Cổng nhượng quyền: nút nào được hiện (rule <c>quyen-hien-thi</c>) và mỗi người thấy những mã truy cập nào.
            Hàm thuần cùng khuôn <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLeadNavPermissions"/>: nhận role đã phân giải qua
            <c>IUserRoleResolver</c> — để luật "ai thấy gì" có ca test gọi thẳng vào nó.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalNavPermissions.Founder">
            <summary>Vai bỏ qua mọi kiểm tra role của hệ thống — ẩn nút của Founder là dựng hàng rào không có thật.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalNavPermissions.Content">
            <summary>Role biên tập: mục cổng, khối, tệp riêng tư, xuất bản (plan §6.8).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalNavPermissions.Sale">
            <summary>Role sale: mã truy cập của các đăng ký nhượng quyền MÌNH phụ trách (plan §6.23).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalNavPermissions.Manage">
            <summary>Role quản lý: mọi mã, cấu hình, và mọi việc của <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalNavPermissions.Content"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalNavPermissions.ResolveContent(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <summary>Cờ của màn "Nội dung cổng" và "Cấu hình trợ lý".</summary>
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c>; <c>null</c> = không có role nào</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalNavPermissions.ResolveAccess(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <summary>Cờ của khối "Mã truy cập" trong màn Đăng ký nhượng quyền (màn Mã truy cập riêng bỏ ở GĐ L, plan §6.23).</summary>
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c>; <c>null</c> = không có role nào</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalNavPermissions.ApplyScope(System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchisePortalAccessCode},System.Linq.IQueryable{Lada.Framework.Data.Domains.Network.FranchiseLead},System.Collections.Generic.IReadOnlyCollection{System.String},System.Int32)">
            <summary>
            Phạm vi mã truy cập — MỘT hàm cho mọi đường đọc/ghi: Manage/Founder thấy tất cả; chỉ có Sale thì chỉ thấy mã
            của đăng ký mình đang phụ trách (<c>FranchiseLead.PicId</c> = mình — plan §6.23: mã đi theo đăng ký, giao đăng ký
            là mã đi theo; mã chưa gắn đăng ký chỉ quản lý thấy); không role thì không thấy gì. Cột <c>SaleUserId</c> để ngủ,
            KHÔNG đọc ở đây (CNQ-80).
            </summary>
            <param name="leads">Đăng ký nhượng quyền (<c>IRepository&lt;FranchiseLead&gt;.Query()</c> — đã lọc xoá mềm, nên mã
            của đăng ký đã xoá chỉ quản lý thấy).</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalContentNavFlags">
            <summary>Cờ hiển thị của màn "Nội dung cổng" / "Cấu hình trợ lý".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalContentNavFlags.#ctor(System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
            <summary>Cờ hiển thị của màn "Nội dung cổng" / "Cấu hình trợ lý".</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessNavFlags">
            <summary>Cờ hiển thị của khối "Mã truy cập" (màn Đăng ký nhượng quyền).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalAccessNavFlags.#ctor(System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
            <summary>Cờ hiển thị của khối "Mã truy cập" (màn Đăng ký nhượng quyền).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalPriceOptionService">
            <summary>
            Nguồn tra cứu của khối "Phạm vi giá" ở màn Mã truy cập (docs/plan-cong-nhuong-quyen.md §3.9, CNQ-39): tỉnh CÓ GIÁ
            và phường/xã CÓ GIÁ ở phiên bản giá hiện hành — không đòi tỉnh thuộc vùng phủ (§6.26) — và bốn bậc gói vùng phủ
            (GĐ K) để drawer báo gói theo số phường đang chọn.
            </summary>
            <remarks>
            Gác bằng role của CỔNG (cờ <c>CanSetPriceScope</c>), không bằng <c>FranchisePrice.*</c>: sale là người báo giá cho
            khách của mình (plan §6.10, CNQ-45) và chỉ đọc được đúng thứ <c>POST {id}/price-scope</c> cho gắn — phường chưa có
            giá không ra ở đây. Đừng nới role của <c>api/FranchisePrice</c> / <c>api/FranchisePackageTier</c> để lấy dữ liệu
            cho màn này.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalPriceOptionService.GetProvincesAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Tỉnh/thành phố có giá ở phiên bản giá hiện hành.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalPriceOptionService.GetTiersAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Bốn bậc gói vùng phủ theo thứ tự ngưỡng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalPriceOptionService.GetWardsAsync(System.Int32,System.String,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Phường/xã 2 cấp của một tỉnh có giá ở phiên bản giá hiện hành.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalPriceOptionService.CanReadAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Cửa của cả ba nguồn — kiểm lần hai sau <c>[Authorize]</c>: người không gắn được giá thì không đọc được gì.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor">
            <summary>Người đang thao tác trên Cổng nhượng quyền — controller đóng gói từ <c>User.GetCurrentUser()</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor.#ctor(System.Int32,System.String)">
            <summary>Người đang thao tác trên Cổng nhượng quyền — controller đóng gói từ <c>User.GetCurrentUser()</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalSectionService">
            <summary>
            Màn quản trị "Nội dung cổng" (docs/plan-cong-nhuong-quyen.md §3.1, §3.4): danh sách mục, siêu dữ liệu, thứ tự,
            bật/tắt. Khối nội dung của mục nằm ở topic vật chủ <c>FranchisePortal.&lt;Code&gt;</c> — service này không chạm khối.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalSectionService.ListAsync">
            <summary>Mọi mục chưa xoá, theo thứ tự hiển thị (cả mục đang tắt).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalSectionService.GetByIdAsync(System.Int32)">
            <summary><c>null</c> khi không có.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalSectionService.CreateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>
            Tạo một mục nội dung kèm topic vật chủ của nó, trong MỘT transaction. Mã mục sinh từ slug và không đổi về sau.
            Mục mới xếp cuối, đang bật, và khoá với mọi mã truy cập như mọi mục.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalSectionService.UpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Sửa tiêu đề, slug, tóm tắt, icon — không đổi mã, loại, thứ tự, trạng thái bật.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalSectionService.ReorderAsync(System.Collections.Generic.IReadOnlyList{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Sắp lại thứ tự; <paramref name="ids"/> phải là đúng toàn bộ mục đang có, mỗi mục một lần.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePortalSectionService.SetActiveAsync(System.Int32,System.Boolean,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalActor)">
            <summary>Bật/tắt mục. Tắt = ẩn với MỌI mã truy cập, kể cả mã đã được mở mục này; dòng mở khoá giữ nguyên.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalSectionService.Validate(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePortalSectionModel,System.Boolean)">
            <summary>Chuẩn hoá và kiểm đầu vào; lỗi trả câu tiếng Việt hiển thị được.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalSectionService.NewCodeAsync(System.String)">
            <summary>
            Mã mục chưa từng dùng, sinh từ slug. Kiểm cả mục và topic ĐÃ XOÁ: mã không tái dùng, vì topic
            <c>FranchisePortal.&lt;Code&gt;</c> cũ vẫn còn và dấu vết/hội thoại cũ tham chiếu mã đó.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePortalSectionFormOptions">
            <summary>Danh mục cho form mục cổng — lấy từ <see cref="T:Lada.Framework.Data.Domains.Cms.BlockIconCatalog"/> và <see cref="T:Lada.Framework.Infrastructures.Services.Network.FranchisePortalSectionRules"/>, không chép tay.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceTerms">
            <summary>Tham số của một phiên bản bảng giá cần cho phần tổng — tách khỏi entity để hàm tính là hàm thuần.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceTerms.#ctor(System.Int64,System.Int64,System.Int64,System.Int32,System.Decimal)">
            <summary>Tham số của một phiên bản bảng giá cần cho phần tổng — tách khỏi entity để hàm tính là hàm thuần.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceSelection">
            <summary>Giá và cọc của một phường/xã đã chọn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceSelection.#ctor(System.Int64,System.Int64)">
            <summary>Giá và cọc của một phường/xã đã chọn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceCalculator">
            <summary>
            Phần tổng của bảng giá nhượng quyền — hàm thuần, số nguyên đồng, không float.
            Mọi mức tiền lấy từ <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceTerms"/> (dữ liệu đã upload), không ghi cứng trong mã.
            </summary>
            <remarks>
            Công thức theo đặc tả:
            <list type="bullet">
            <item>Tổng phí nhượng quyền (gồm VAT) = Σ giá.</item>
            <item>Giá chưa VAT = làm tròn nửa lên (tổng ÷ (1 + thuế suất)); tiền VAT = tổng − giá chưa VAT.</item>
            <item>Tiền bảo đảm theo vùng = min(tối đa, max(tối thiểu, Σ cọc theo sản lượng)).</item>
            <item>Bảo đảm xe thuê = số xe × bảo đảm mỗi xe; tổng tiền bảo đảm = theo vùng + xe thuê.</item>
            <item>Tổng nộp khi ký = tổng phí nhượng quyền + tổng tiền bảo đảm.</item>
            </list>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceCalculator.DivideRoundHalfUp(System.Int64,System.Decimal)">
            <summary>Chia rồi làm tròn nửa lên về số nguyên đồng — 41.666.666,67 → 41.666.667.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseTemplateWardRow">
            <summary>Một phường/xã của file mẫu — phần hệ thống điền sẵn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseTemplateWardRow.#ctor(System.Int32,System.String,System.Int32,System.String,System.String,System.String)">
            <summary>Một phường/xã của file mẫu — phần hệ thống điền sẵn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceExportContext">
            <summary>Dữ liệu đầu trang + bảng chi tiết + phần tổng của bảng giá xuất cho khách.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceExportContext.Summary">
            <summary>Null khi xuất cả tỉnh (không tích chọn) — không có phần tổng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceExcelBuilder">
            <summary>
            Dựng hai file Excel của chức năng: file mẫu cho quản trị điền giá, và bảng giá xuất cho khách.
            Hàm thuần — nhận dữ liệu đã nạp, trả byte[].
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceExcelBuilder.FooterNotes">
            <summary>
            Ba câu ghi chú cuối file, đúng nguyên văn đặc tả. Hai câu đầu dùng chung với mục bảng giá của cổng
            (<see cref="T:Lada.Framework.Infrastructures.Services.Network.FranchisePriceListLayout"/>).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceExcelBuilder.ExportColumns">
            <summary>Tên cột hiển thị của bảng chi tiết trong file xuất — cùng sáu cột với cổng nhượng quyền.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceExcelBuilder.PriceColumn">
            <summary>Cột "Giá nhượng quyền" — số của phần tổng cũng nằm ở cột này để thẳng hàng với giá.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavPermissions">
            <summary>
            Hai nút của chức năng Bảng giá nhượng quyền mà máy chủ gác bằng quyền có được hiện cho một người hay không
            (rule <c>quyen-hien-thi</c>). Hàm thuần cùng khuôn <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Ads.AdsNavPermissions"/>: nhận role đã phân giải
            qua <c>IUserRoleResolver</c>, trả cờ — để luật "ai thấy gì" có ca test gọi thẳng vào nó.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavPermissions.Founder">
            <summary>Vai bỏ qua mọi kiểm tra role của hệ thống — ẩn nút của Founder là dựng hàng rào không có thật.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavPermissions.Manage">
            <summary>
            Role của trang quản trị: <c>template</c>, <c>preview</c>, <c>import</c>, <c>versions</c>; và thêm/sửa tay từng dòng
            (<c>lines/*</c>) ngay trên trang xuất.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavPermissions.Export">
            <summary>Role của trang xuất: <c>current</c>, <c>export/provinces</c>, <c>export/wards</c>, <c>export</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavPermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c>; <c>null</c> = không có role nào</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavPermissions.ResolveTier(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <summary>
            Cờ của màn tham số bốn bậc gói vùng phủ (<c>api/FranchisePackageTier</c>, GĐ K). Cùng hai role với bảng giá
            phường: <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavPermissions.Export"/> xem, <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavPermissions.Manage"/> xem và sửa.
            </summary>
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c>; <c>null</c> = không có role nào</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavPermissions.ResolvePlan(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <summary>
            Cờ của màn tham số kế hoạch kinh doanh (<c>api/FranchiseBusinessPlan</c>, GĐ M — §6.24 mục 5). Cùng hai role với
            bảng giá phường: <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavPermissions.Export"/> xem + tính thử, <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavPermissions.Manage"/> xem, tính thử và sửa.
            </summary>
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c>; <c>null</c> = không có role nào</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavFlags">
            <summary>Cờ hiển thị của chức năng bảng giá nhượng quyền.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceNavFlags.#ctor(System.Boolean,System.Boolean)">
            <summary>Cờ hiển thị của chức năng bảng giá nhượng quyền.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePackageTierNavFlags">
            <summary>Cờ hiển thị của màn tham số gói vùng phủ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePackageTierNavFlags.#ctor(System.Boolean,System.Boolean)">
            <summary>Cờ hiển thị của màn tham số gói vùng phủ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceActor">
            <summary>Người đang thao tác — controller đọc từ <c>User.GetCurrentUser()</c> rồi truyền xuống.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceActor.#ctor(System.Int32,System.String)">
            <summary>Người đang thao tác — controller đọc từ <c>User.GetCurrentUser()</c> rồi truyền xuống.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePriceService">
            <summary>
            Bảng giá nhượng quyền bưu cục: quản trị tải mẫu và upload phiên bản giá; sale chọn tỉnh, phường/xã rồi xuất.
            Dữ liệu nội bộ — chỉ phục vụ SPA quản trị, không đưa lên website, app khách, app lái xe hay API công khai.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePriceService.GetTemplateProvincesAsync">
            <summary>Mọi tỉnh/thành phố 2 cấp, cờ <c>IsDefault</c> cho tỉnh thuộc vùng phủ hiện tại.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePriceService.BuildTemplateAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>File mẫu gồm toàn bộ phường/xã của các tỉnh được chọn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePriceService.PreviewAsync(System.IO.Stream)">
            <summary>Kiểm toàn bộ file. Có lỗi → báo theo dòng; không lỗi → bản xem trước. Không ghi gì.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePriceService.ImportAsync(System.IO.Stream,System.String,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceActor)">
            <summary>Kiểm lại toàn bộ file rồi lưu thành phiên bản mới, đặt làm hiện hành. Có lỗi thì không ghi gì.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePriceService.GetVersionsAsync">
            <summary>Lịch sử phiên bản, mới nhất trước.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePriceService.GetCurrentAsync">
            <summary>Phiên bản đang dùng để xuất; null khi chưa upload lần nào.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePriceService.GetExportProvincesAsync">
            <summary>Các tỉnh có ít nhất một phường/xã có giá trong phiên bản hiện hành.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePriceService.SearchWardsAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Phường/xã có giá của một tỉnh, tìm theo tên có dấu hay không dấu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePriceService.ExportAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceExportModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceActor)">
            <summary>Xuất bảng giá Excel. Không tích phường/xã nào → cả tỉnh, không phần tổng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePriceService.GetLineAsync(System.Int32)">
            <summary>Chi tiết một dòng giá của phiên bản hiện hành; null khi phường/xã không có giá.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePriceService.GetUnpricedWardsAsync(System.Int32)">
            <summary>Phường/xã 2 cấp của một tỉnh CHƯA có giá trong phiên bản hiện hành — để thêm dòng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePriceService.CreateLineAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceLineModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceActor)">
            <summary>Thêm tay một dòng giá vào phiên bản hiện hành, tính lại số dòng và tổng giá của phiên bản.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchisePriceService.UpdateLineAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceLineModel,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceActor)">
            <summary>Sửa tay một dòng giá của phiên bản hiện hành, tính lại tổng giá của phiên bản.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceService.ToItemsWithEditsAsync(System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Network.FranchisePriceVersion})">
            <summary>
            Gắn thông tin sửa tay vào phiên bản. Dòng của file upload mang <c>UpdatedTime</c> đúng bằng <c>UploadedAt</c>
            (cùng một <c>now</c> trong <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceService.ImportAsync(System.IO.Stream,System.String,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceActor)"/>, cùng kiểu <c>datetimeoffset(7)</c>) — dòng nào muộn hơn
            là đã được thêm hoặc sửa tay sau đó. Thường chỉ vài dòng nên gom trong bộ nhớ.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceService.MaxAreaKm2">
            <summary>Trần của <c>decimal(12,3)</c> — cột <c>AreaKm2</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceService.SaveLineAsync(Lada.Framework.Data.Domains.Network.FranchisePriceVersion,Lada.Framework.Data.Domains.Network.FranchisePriceLine,System.Boolean,Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceActor,System.DateTimeOffset)">
            <summary>
            Ghi dòng và tính lại số dòng + tổng giá của phiên bản trong cùng một giao dịch. Tổng đếm lại từ DB chứ không
            cộng dồn chênh lệch, để hai quản trị sửa song song vẫn hội tụ về đúng số ở lần ghi sau.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceService.ValidateLine(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchisePriceLineModel)">
            <summary>Cùng luật với sheet <c>BangGia</c> của file upload (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceWorkbook"/>).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceService.RoundScore(System.Nullable{System.Decimal})">
            <summary>Điểm lẻ là bình thường (mô hình giá chấm theo trọng số) — lưu 2 chữ số thập phân như lúc upload.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceService.LineStamp(Lada.Framework.Data.Domains.Network.FranchisePriceLine)">
            <summary>Dấu của dòng = <c>UpdatedTime</c> tính tới tick — <c>datetimeoffset(7)</c> giữ đủ độ chính xác đó.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceService.ResolveWardType(System.String,System.String)">
            <summary>
            Loại phường/xã: <c>Prefix</c> (Phường/Xã); 14 đặc khu trong danh mục để trống Prefix và ghi "Đặc khu X" vào Name.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceService.ResolveWardName(System.String,System.String)">
            <summary>Tên phường/xã không kèm loại — "Đặc khu Cát Hải" với Prefix trống → "Cát Hải".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceService.Unsign(System.String)">
            <summary>Bỏ dấu, chữ thường — dùng chung cho lúc lưu và lúc tìm để hai bên luôn khớp.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWardCatalogEntry">
            <summary>Một phường/xã trong danh mục 2 cấp — phần parser cần để kiểm id.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWardCatalogEntry.#ctor(System.Int32,System.Int32)">
            <summary>Một phường/xã trong danh mục 2 cấp — phần parser cần để kiểm id.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceParsedLine">
            <summary>Một dòng sheet <c>BangGia</c> đã qua kiểm, chưa ghép tên từ danh mục.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceParsedLine.#ctor(System.Int32,System.Int32,System.Int32,System.Byte,System.Int64,System.Int64,System.Int32,System.Nullable{System.Decimal},System.Nullable{System.Decimal},System.Nullable{System.Int64},System.String,System.String)">
            <summary>Một dòng sheet <c>BangGia</c> đã qua kiểm, chưa ghép tên từ danh mục.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceParsedTerms">
            <summary>Sheet <c>ThamSo</c> đã qua kiểm.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceParsedTerms.#ctor(System.String,System.DateTime,System.Int64,System.Int64,System.Int64,System.Int32,System.Decimal)">
            <summary>Sheet <c>ThamSo</c> đã qua kiểm.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceParseResult">
            <summary>Kết quả đọc file: có lỗi thì <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceParseResult.Lines"/> rỗng và <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceParseResult.Terms"/> null.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceWorkbook">
            <summary>
            Bố cục file mẫu bảng giá nhượng quyền (tên sheet, tên cột, mã tham số) và bộ đọc kiểm toàn bộ file
            trước khi ghi. Hàm thuần trên <see cref="T:OfficeOpenXml.ExcelPackage"/> — không chạm database; danh mục phường/xã
            truyền vào dưới dạng từ điển.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceWorkbook.HeaderAliases">
            <summary>Tên cũ / tên bị EPPlus cắt vẫn được nhận, để file điền tay theo tên cũ không bị bác oan.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceWorkbook.PriceColumns">
            <summary>Thứ tự cột của sheet BangGia trong file mẫu.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceWorkbook.RequiredPriceColumns">
            <summary>Cột bắt buộc phải có trong sheet BangGia để đọc được file.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceWorkbook.TermKeys">
            <summary>7 dòng của sheet ThamSo, đúng thứ tự in trong file mẫu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceWorkbook.Parse(OfficeOpenXml.ExcelPackage,System.Collections.Generic.IReadOnlyDictionary{System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWardCatalogEntry},System.Collections.Generic.ISet{System.String})">
            <summary>
            Kiểm toàn bộ file. Mọi lỗi gom lại theo dòng, không dừng ở lỗi đầu — quản trị sửa một lần cho xong.
            </summary>
            <param name="package">File đã mở.</param>
            <param name="catalog">Phường/xã 2 cấp còn hiệu lực trong danh mục, khoá theo <c>Location.Id</c>.</param>
            <param name="existingVersionCodes">Mã phiên bản đã có — trùng thì báo lỗi ở sheet ThamSo.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceWorkbook.ReadHeader(OfficeOpenXml.ExcelWorksheet)">
            <summary>Hàng 1 → tên cột chuẩn hoá → chỉ số cột. Chấp nhận viết hoa/thường, dấu cách thay gạch dưới, có dấu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchisePriceWorkbook.TermVat(System.Collections.Generic.Dictionary{System.String,System.ValueTuple{System.Int32,System.Object}},System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Network.FranchisePriceRowError})">
            <summary>Thuế suất chấp nhận 0.08, 8, "8%" — lưu dạng tỉ lệ 0 ≤ t &lt; 1.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSlipOrderPlan">
            <summary>Kế hoạch E8 của một đơn COD theo luật ví trong phiếu đối soát khách.</summary>
            <param name="AppliedFee">Cước chính thức (gồm phí thu hộ) — "phí" của dòng phiếu.</param>
            <param name="Offset">Cước nợ đơn hoàn cấn vào đơn này.</param>
            <param name="NetAmount">Tiền trả khách của đơn (E8).</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSlipOrderPlan.#ctor(System.Int32,System.Decimal,System.Decimal,System.Decimal,System.Collections.Generic.IReadOnlyList{Lada.Framework.Infrastructures.Services.Network.FranchiseReturnFeeDebt})">
            <summary>Kế hoạch E8 của một đơn COD theo luật ví trong phiếu đối soát khách.</summary>
            <param name="AppliedFee">Cước chính thức (gồm phí thu hộ) — "phí" của dòng phiếu.</param>
            <param name="Offset">Cước nợ đơn hoàn cấn vào đơn này.</param>
            <param name="NetAmount">Tiền trả khách của đơn (E8).</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSlipOrderPlan.AppliedFee">
            <summary>Cước chính thức (gồm phí thu hộ) — "phí" của dòng phiếu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSlipOrderPlan.Offset">
            <summary>Cước nợ đơn hoàn cấn vào đơn này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSlipOrderPlan.NetAmount">
            <summary>Tiền trả khách của đơn (E8).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSlipPlan">
            <summary>Kế hoạch ví của một phiếu đối soát khách: chỉ các đơn theo luật ví (đơn khác giữ công thức cũ).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSlipPlan.TotalOffset">
            <summary>Tổng cước nợ đơn hoàn cấn trong phiếu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSlipPlan.IsEmpty">
            <summary>Phiếu không dính đơn theo luật ví.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseReturnFeeDebtService">
            <summary>
            Khoản khách nợ cước đơn hoàn (dòng NO-CUOC) và E8 / E13 ở đối soát khách (Ví v2 — plan §3.6, mota L2-4): danh sách đơn nợ cước theo
            bưu cục sale, "đã thu ngoài", và móc vào phiếu đối soát khách (<c>CustomerReconciliationSlip</c> — luồng đối soát đang dùng, §6 mục 21):
            lập phiếu = tính E8 + giữ chỗ khoản nợ; từ chối = trả chỗ; hoàn thành = E13 + đóng nợ CÙNG giao dịch chuyển tiền.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseReturnFeeDebtService.SearchAsync(System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{Lada.Framework.Data.Domains.Network.FranchiseReturnFeeDebtStatus},Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Danh sách đơn nợ cước — bưu cục bị ép về ví mình; LADA lọc theo bưu cục / khách. Mặc định: còn nợ + đang giữ chỗ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseReturnFeeDebtService.SettleOutsideAsync(System.Int64,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseReturnFeeDebtSettleModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Kế toán (role Manage) ghi nhận bưu cục sale đã tự thu khoản nợ của khách ngoài ví — đóng nợ, KHÔNG có E13.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseReturnFeeDebtService.PlanSlipAsync(System.Int32,System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>
            Lập phiếu đối soát khách: với từng đơn COD có bưu cục nhượng quyền bật ví bán (giao thành công) tính E8 bằng planner và phân bổ khoản
            nợ còn mở của khách (<see cref="M:Lada.Framework.Infrastructures.Services.Network.FranchiseWalletRules.AllocateReturnFeeDebts(System.Collections.Generic.IEnumerable{System.ValueTuple{System.Int32,System.Decimal}},System.Collections.Generic.IEnumerable{Lada.Framework.Infrastructures.Services.Network.FranchiseReturnFeeDebt})"/>). Đơn không theo luật ví vắng mặt.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseReturnFeeDebtService.ReserveForSlipAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSlipPlan)">
            <summary>Giữ chỗ các khoản nợ đã phân bổ cho phiếu (UPDATE có điều kiện còn nợ). Có khoản vừa bị phiếu khác giữ → trả chỗ đã giữ + NÉM lỗi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseReturnFeeDebtService.ReleaseSlipAsync(System.Int32)">
            <summary>Phiếu bị từ chối / huỷ lập: trả mọi khoản nợ phiếu đang giữ về "còn nợ".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseReturnFeeDebtService.ApplySlipCompletedAsync(System.Int32,System.Collections.Generic.IReadOnlyList{System.ValueTuple{System.Int32,System.Decimal}},Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction,System.Int32,System.String)">
            <summary>
            Hoàn thành phiếu (CÙNG giao dịch chuyển tiền của phiếu): mỗi đơn theo luật ví → planner ghi E13 cho khoản nợ đã giữ, kiểm tiền trả
            khách đúng số trên phiếu, rồi đóng nợ (Offset). NÉM lỗi khi lệch — nơi gọi rollback.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseReturnFeeDebtService.FindFranchiseSellerOrderIdsAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>Đơn nào trong danh sách có bên bán là bưu cục nhượng quyền đang bật ví (để màn đối soát cũ từ chối — §6 mục 21).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseReturnFeeDebtService.ListBySlipAsync(System.Int32)">
            <summary>
            Khoản nợ cước đơn hoàn một phiếu đối soát khách đang giữ chỗ / đã cấn (V-37 — chi tiết phiếu + Excel). KHÔNG kiểm quyền: nơi gọi đã
            kiểm quyền xem phiếu.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseReturnFeeDebtService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseReturnFeeDebtService"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseReturnFeeDebtService.DebtRows">
            <summary>Dòng NO-CUOC còn hiệu lực (không xoá / huỷ / từ chối).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseReturnFeeDebtService.SearchAsync(System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{Lada.Framework.Data.Domains.Network.FranchiseReturnFeeDebtStatus},Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseReturnFeeDebtService.ListBySlipAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseReturnFeeDebtService.SettleOutsideAsync(System.Int64,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseReturnFeeDebtSettleModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseReturnFeeDebtService.PlanSlipAsync(System.Int32,System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseReturnFeeDebtService.ReserveForSlipAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSlipPlan)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseReturnFeeDebtService.ReleaseSlipAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseReturnFeeDebtService.ApplySlipCompletedAsync(System.Int32,System.Collections.Generic.IReadOnlyList{System.ValueTuple{System.Int32,System.Decimal}},Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction,System.Int32,System.String)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseReturnFeeDebtService.FindFranchiseSellerOrderIdsAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseReturnFeeDebtService.FranchiseWalletAgencyIdsAsync">
            <summary>Bưu cục NHƯỢNG QUYỀN đang bật ví ("bên bán có ví", §6 mục 20) — chi nhánh LADA bật ví để đo không tính.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseReturnFeeDebtService.OpenDebtsAsync(System.Int32)">
            <summary>
            Khoản nợ còn mở (chưa giữ chỗ) của khách — của mọi bưu cục sale NHƯỢNG QUYỀN đang bật ví. Ví bưu cục đã tắt / chi nhánh LADA bật
            ví để đo: không cấn (không có ví nào nhận E13 thì cấn là trừ tiền khách mà không trả ai — review GĐ C); bưu cục tự thu.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementExportContext">
            <summary>Đầu vào dựng bảng kê một phiếu tháng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementExportContext.#ctor(Lada.Framework.Data.Domains.Network.FranchiseSettlement,System.String,System.String,System.String,System.String,System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Network.FranchiseWalletEntry},Lada.Framework.Infrastructures.Services.Network.FranchiseStatements,System.Collections.Generic.IReadOnlyList{Lada.Framework.Infrastructures.Services.Network.FranchiseSaleToCustomerLine},Lada.Framework.Infrastructures.Services.Network.FranchiseSettlementMinutes,System.DateTimeOffset,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseIntraRegionLine})">
            <summary>Đầu vào dựng bảng kê một phiếu tháng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseIntraRegionLine">
            <summary>
            Một đơn nội vùng của kỳ (V-65, anh Thắng 27/10/2026): bưu cục tự lấy, tự giao, cước chính thức = cước tạm tính — liệt kê riêng kèm cân
            khai để kế toán kiểm xác suất cân.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseIntraRegionLine.#ctor(System.Int32,System.String,System.Nullable{System.DateTimeOffset},System.Nullable{System.Int32},System.Decimal,System.String)">
            <summary>
            Một đơn nội vùng của kỳ (V-65, anh Thắng 27/10/2026): bưu cục tự lấy, tự giao, cước chính thức = cước tạm tính — liệt kê riêng kèm cân
            khai để kế toán kiểm xác suất cân.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementExcelBuilder">
            <summary>
            Bảng kê Excel của phiếu tháng = biên bản đối chiếu (Ví v2 plan §3.6): (1) chiều 1 LADA → bưu cục (E4 / E4h), (2) chiều 2 bưu cục →
            LADA (E6 / E7 / E10 / E11 / E12) — mỗi mã một dòng, tổng gồm VAT, tách chưa VAT / VAT làm tròn đồng sau cùng; (3) chiều 3 bưu cục
            sale → khách (E5, CK-THẲNG, đơn hoàn); (4) chi tiết mọi dòng của kỳ + biên bản Đầu kỳ / Phát sinh / Nạp / Rút / Cuối kỳ. Hàm THUẦN
            trả byte[] — không lưu file ra đĩa (khuôn FranchisePrice: tiền nội bộ không nằm ở URL công khai).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementExcelBuilder.Vn(System.DateTimeOffset)">
            <summary>In theo giờ Việt Nam dù thời điểm lưu kèm offset nào (máy chủ / SQL chạy UTC).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementExcelBuilder.Build(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementExportContext,System.Int32)">
            <summary>Dựng workbook. <paramref name="type"/>: 0 = đủ 5 sheet, 1–5 = một sheet (5 = đơn nội vùng, V-65).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementNavPermissions">
            <summary>Bó role của phiếu đối soát tháng (SPEC §3.10) và luật THUẦN đổi role thành cờ.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementNavPermissions.Founder">
            <summary>Founder.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementNavPermissions.Manage">
            <summary>Kế toán LADA: lập nháp, phát hành, khoá, đánh dấu hoá đơn, xuất bảng kê.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementNavPermissions.Confirm">
            <summary>Chủ bưu cục xác nhận phiếu của mình.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementNavPermissions.ViewRoles">
            <summary>Mọi đường xem phiếu (bưu cục có Confirm hoặc xem ví được xem phiếu của mình).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementNavPermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <summary>Đổi role thành cờ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementNavFlags">
            <summary>Cờ role thô của phiếu tháng.</summary>
            <param name="CanAdjustWallet">Tạo được điều chỉnh tay Ví (bó quyền của <c>POST api/FranchiseWallet/adjustments</c>).</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementNavFlags.#ctor(System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
            <summary>Cờ role thô của phiếu tháng.</summary>
            <param name="CanAdjustWallet">Tạo được điều chỉnh tay Ví (bó quyền của <c>POST api/FranchiseWallet/adjustments</c>).</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementNavFlags.CanAdjustWallet">
            <summary>Tạo được điều chỉnh tay Ví (bó quyền của <c>POST api/FranchiseWallet/adjustments</c>).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementAccess">
            <summary>Phạm vi truy cập phiếu tháng của một người dùng (fail-closed).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementAccess.#ctor(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementNavFlags,System.Int32,System.String,System.Boolean)">
            <summary>Phạm vi truy cập phiếu tháng của một người dùng (fail-closed).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementAccess.CanViewOwn">
            <summary>Bưu cục xem phiếu của mình.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementAccess.CanConfirmOwn">
            <summary>Bưu cục xác nhận phiếu của mình.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementAccess.CanAccessAgency(System.Int32)">
            <summary>Được xem phiếu của bưu cục này không.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseSettlementService">
            <summary>
            Phiếu đối soát tháng + bảng kê hai chiều + phụ lục K1 (SPEC §3.6, GĐ4): Nháp → Chờ bưu cục xác nhận → Đã xác nhận (bấm,
            hoặc tự xác nhận sau 3 ngày làm việc) → Đã khoá (dòng Ví → đã đối soát) → Đã lập hoá đơn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseSettlementService.ListAgenciesAsync(Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Bưu cục nhượng quyền để lọc / lập phiếu (kế toán LADA) — không mượn danh sách ví của màn Ví.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseSettlementService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.ConfirmWorkingDaysKey">
            <summary>Khoá AppConfig số ngày làm việc để xác nhận.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService._finRepo">
            <summary>Cước chính thức của đơn CK-THẲNG cho chiều 3 (Ví v2); null = chiều 3 ghi 0 cho đơn CK-THẲNG (test cũ dựng không có).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.GetAccessAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.GetAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.GenerateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementGenerateModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.GenerateForPeriodAsync(System.Int32,System.Nullable{System.Int32},System.String)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.PublishAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementNoteModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.ConfirmAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.AutoConfirmDueAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.LockAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementNoteModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.MarkInvoicedAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseSettlementInvoiceModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.ExportAsync(System.Int32,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.ListAgenciesAsync(Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.PeriodEntriesAsync(Lada.Framework.Data.Domains.Network.FranchiseSettlement)">
            <summary>Dòng thuộc phiếu: đã khoá thì theo SettlementId; còn mở thì theo luật BelongsTo.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.SaleToCustomerAsync(Lada.Framework.Data.Domains.Network.FranchiseSettlement,System.Collections.Generic.List{Lada.Framework.Data.Domains.Network.FranchiseWalletEntry})">
            <summary>
            Chiều 3 của phiếu (Ví v2 plan §3.6): dòng E4 / E4h / E5 của phiếu + dòng thông tin NO-CUOC chốt trong kỳ (dòng thông tin không
            thuộc phiếu nên lọc theo thời điểm chốt), cước chính thức của đơn CK-THẲNG đọc từ đơn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseSettlementService.IntraRegionAsync(Lada.Framework.Data.Domains.Network.FranchiseSettlement,System.Collections.Generic.List{Lada.Framework.Data.Domains.Network.FranchiseWalletEntry})">
            <summary>
            V-65 (anh Thắng 27/10/2026): đơn có dòng trong phiếu mà cước chính thức chốt theo nguồn "nội vùng" (= cước tạm tính) — liệt kê riêng kèm
            cân khai để kế toán kiểm xác suất cân. Chỉ đơn CHỐT trong kỳ của phiếu (review H2): đơn có dòng ở hai kỳ chỉ lên một phiếu, và phiếu
            đã phát hành / khoá không tự thêm đơn chốt sau kỳ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletDepositService">
            <summary>
            Nạp tiền ví bưu cục (Ví v2 — plan §3.5 đường 1): kế toán quỹ ghi nhận khoản bưu cục đã chuyển vào tài khoản LADA → khoản nạp
            <c>Confirmed</c> + dòng NAP (+, đã chốt, <c>EventAt</c> = ngày tiền vào) cùng giao dịch khoá ví. KHÔNG có đường cho bưu cục tự nạp.
            </summary>
            <remarks>
            Đường 2 (import sao kê khớp tài khoản ảo → khoản nạp <c>Pending</c> chờ kế toán xác nhận một nút) chỉ để chỗ — chờ ngân hàng cấp tài
            khoản ảo (V-12, Q118 kế toán): bảng và trạng thái đã có, chưa code import. Nạp xong đơn bị chặn không tự xuất — điều phối bấm gán lại
            (mota L3).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletDepositService.RecordAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseDepositCreateModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Kế toán quỹ ghi nhận một khoản nạp (role Treasury).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletDepositService.ListAsync(System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Danh sách khoản nạp — bưu cục bị ép về ví mình; LADA lọc theo bưu cục hoặc xem mọi ví.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletDepositService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletDepositService"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletDepositService.RecordAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseDepositCreateModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletDepositService.ListAsync(System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletDepositService.Validate(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseDepositCreateModel,System.DateTimeOffset)">
            <summary>Kiểm một yêu cầu ghi nhận nạp (thuần — ngày tính theo giờ Việt Nam).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletDepositService.StatusName(Lada.Framework.Data.Domains.Network.FranchiseDepositStatus)">
            <summary>Tên trạng thái khoản nạp.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions">
            <summary>Bó role của Ví bưu cục (SPEC §3.10) và luật THUẦN đổi tập role thành cờ.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Founder">
            <summary>Founder.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.View">
            <summary>Bưu cục xem ví mình.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Manage">
            <summary>Kế toán LADA: mọi ví, tạo điều chỉnh, duyệt lần 1, đối chiếu lại.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Approve">
            <summary>Duyệt lần 2 điều chỉnh từ ngưỡng.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Withdraw">
            <summary>Chủ bưu cục tạo / huỷ lệnh rút của bưu cục mình (Ví v2, migration M202610251501; service GĐ C).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Treasury">
            <summary>Kế toán quỹ: ghi nhận nạp, chuyển / từ chối lệnh rút, nhập sao kê (Ví v2).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Config">
            <summary>Bật ví cho chi nhánh, tham số theo bưu cục, tài khoản nhận tiền rút (Ví v2).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.CustomerUpdate">
            <summary>Gán bưu cục sở hữu khách (role sẵn có của màn khách hàng).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.CustomerRead">
            <summary>Đọc bưu cục sở hữu khách.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.ViewRoles">
            <summary>Mọi đường xem dòng Ví.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.AdminRoles">
            <summary>Đường của LADA (mọi ví).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.ListWalletRoles">
            <summary>Danh sách ví (V-47): LADA xem sổ, kế toán trưởng mở cấu hình, kế toán quỹ chọn bưu cục khi ghi nạp.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.FundsViewRoles">
            <summary>Xem lệnh rút / khoản nạp: bưu cục (ví mình), kế toán (mọi ví), kế toán quỹ (mọi ví).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <summary>Đổi tập role thành cờ. Rỗng = mọi cờ tắt.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavFlags">
            <summary>Cờ role thô của Ví.</summary>
            <param name="CanConfig">Bật ví cho chi nhánh, sửa tham số theo bưu cục (Ví v2 — role <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Config"/> hoặc Founder).</param>
            <param name="CanWithdraw">Tạo / huỷ lệnh rút của ví bưu cục mình (role <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Withdraw"/>) — service còn đòi người
            gọi thuộc đúng bưu cục nhượng quyền có ví, Founder không có ví nên cũng không rút được.</param>
            <param name="CanTreasury">Kế toán quỹ: ghi nhận nạp, chuyển / từ chối lệnh rút của mọi ví (role <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Treasury"/>) —
            không kèm quyền rút.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavFlags.#ctor(System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
            <summary>Cờ role thô của Ví.</summary>
            <param name="CanConfig">Bật ví cho chi nhánh, sửa tham số theo bưu cục (Ví v2 — role <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Config"/> hoặc Founder).</param>
            <param name="CanWithdraw">Tạo / huỷ lệnh rút của ví bưu cục mình (role <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Withdraw"/>) — service còn đòi người
            gọi thuộc đúng bưu cục nhượng quyền có ví, Founder không có ví nên cũng không rút được.</param>
            <param name="CanTreasury">Kế toán quỹ: ghi nhận nạp, chuyển / từ chối lệnh rút của mọi ví (role <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Treasury"/>) —
            không kèm quyền rút.</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavFlags.CanConfig">
            <summary>Bật ví cho chi nhánh, sửa tham số theo bưu cục (Ví v2 — role <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Config"/> hoặc Founder).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavFlags.CanWithdraw">
            <summary>Tạo / huỷ lệnh rút của ví bưu cục mình (role <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Withdraw"/>) — service còn đòi người
            gọi thuộc đúng bưu cục nhượng quyền có ví, Founder không có ví nên cũng không rút được.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavFlags.CanTreasury">
            <summary>Kế toán quỹ: ghi nhận nạp, chuyển / từ chối lệnh rút của mọi ví (role <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavPermissions.Treasury"/>) —
            không kèm quyền rút.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavFlags.CanSeeAll">
            <summary>Thấy mọi ví.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletAccess">
            <summary>Phạm vi truy cập Ví của một người dùng (fail-closed).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletAccess.#ctor(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletNavFlags,System.Int32,System.String,System.Boolean,System.Boolean)">
            <summary>Phạm vi truy cập Ví của một người dùng (fail-closed).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletAccess.CanSeeAll">
            <summary>Xem mọi ví.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletAccess.CanViewOwn">
            <summary>Xem ví của bưu cục mình (role View + thuộc bưu cục nhượng quyền).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletAccess.CanAccessAgency(System.Int32)">
            <summary>Được xem ví này không.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletAccess.CanWithdrawOwn">
            <summary>Tạo / huỷ lệnh rút của ví bưu cục mình (role Withdraw + thuộc bưu cục nhượng quyền) — Ví v2 §3.5.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletAccess.IsTreasury">
            <summary>Kế toán quỹ (Treasury) hoặc Founder: ghi nhận nạp, chuyển / từ chối lệnh rút của mọi ví.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletAccess.CanSeeFunds(System.Int32)">
            <summary>
            Xem lệnh rút / khoản nạp / đơn nợ cước của ví này: LADA (Manage / Approve / Treasury) mọi ví; bưu cục (View hoặc Withdraw) chỉ ví mình.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletAccess.CanSeeAllFunds">
            <summary>Thấy lệnh rút / khoản nạp của mọi ví.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletAccess.CanViewEntries">
            <summary>Đọc dòng Ví / tóm tắt / đơn nợ cước / dự kiến phí: ví mình (bưu cục) hoặc mọi ví (LADA) — plan §3.8.1.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletAccess.CanListWallets">
            <summary>Danh sách ví: LADA xem sổ, kế toán trưởng (Config) mở cấu hình, kế toán quỹ (Treasury) chọn bưu cục khi ghi nạp (V-47).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletService">
            <summary>API Ví bưu cục (SPEC §3.8 <c>api/FranchiseWallet</c>): xem dòng, tóm tắt, điều chỉnh tay duyệt hai người.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletService.EnableWalletAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletEnableModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Bật ví cho một chi nhánh (Ví v2 §1.1) — role Config / Founder; chi nhánh LADA <c>BlockOutbound = false</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletService.ListIssuesAsync(Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor,System.Nullable{Lada.Framework.Data.Domains.Network.FranchiseLedgerIssueKind},System.Nullable{System.Int32},System.Boolean,System.Nullable{System.DateTime},System.Nullable{System.DateTime})">
            <summary>
            Sổ vấn đề (LADA). Không lọc = vấn đề đang mở. <paramref name="kind"/> / <paramref name="agencyId"/> lọc; <paramref name="includeResolved"/>
            gồm cả vấn đề đã tự đóng (số đo "sẽ chặn" tuần đầu); <paramref name="from"/> / <paramref name="to"/> theo ngày gặp gần nhất (giờ VN,
            ngày cuối tính trọn).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletService.UpdateWalletConfigAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletConfigModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Sửa tham số + tài khoản của ví (role Config, plan §3.8.1); ghi lịch sử khi có giá trị đổi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletService.ListWalletConfigChangesAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Lịch sử đổi cấu hình của một ví (role Config), mới nhất trước.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletService.ForecastOrderAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>
            Dự kiến phí nếu đơn giao thành công từ trạng thái hiện tại (planner <c>Forecast</c>, không ghi sổ). LADA thấy mọi dòng; bưu cục chỉ
            dòng của mình và chỉ khi bưu cục mình tham gia đơn (bán / lấy / phát / phát hoàn) — đơn khác 403.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.DualApprovalThresholdKey">
            <summary>Khoá AppConfig ngưỡng duyệt hai người.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService._withdrawalRepo">
            <summary>Lệnh rút — để từ chối khoản hoàn lệnh rút (RUT-HOAN chờ duyệt) mở lại lệnh (review GĐ C); null = dựng không có rút.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService._configChangeRepo">
            <summary>Lịch sử đổi cấu hình ví (GĐ D); null = dựng không ghi lịch sử (test cũ).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.GetAccessAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.DualApprovalThresholdAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.SearchEntriesAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.GetEntryAsync(System.Int64,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.GetSummaryAsync(System.Nullable{System.Int32},System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset},Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.ToListItem(Lada.Framework.Data.Domains.Categories.Agency,Lada.Framework.Data.Domains.Network.FranchiseWallet,System.Decimal,System.Decimal,System.Int32,System.Int32,System.Nullable{System.DateTimeOffset})">
            <summary>Dòng danh sách ví (Các ví + Cấu hình ví) — số dư / thống kê do nơi gọi cộng sẵn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.ListWalletsAsync(Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.UpdateWalletConfigAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletConfigModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.ListWalletConfigChangesAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.EnableWalletAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWalletEnableModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.CreateAdjustmentAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseAdjustmentCreateModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.ApproveAdjustmentAsync(System.Int64,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.RejectAdjustmentAsync(System.Int64,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseAdjustmentRejectModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.ListIssuesAsync(Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor,System.Nullable{Lada.Framework.Data.Domains.Network.FranchiseLedgerIssueKind},System.Nullable{System.Int32},System.Boolean,System.Nullable{System.DateTime},System.Nullable{System.DateTime})">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.IssueKindName(Lada.Framework.Data.Domains.Network.FranchiseLedgerIssueKind)">
            <summary>Tên loại vấn đề (V-24).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.CustodyCodes">
            <inheritdoc/>
            <summary>
            Dòng giữ tiền (E1 / E2 / E3 giữ cước, COD bưu cục đang cầm; E9 trả lại phần giữ) — tiền mặt bưu cục cầm hộ LADA, không phải
            lãi / lỗ: lãi gộp dự kiến không tính chúng (bấm thật D2: đơn GỬI-TRẢ 110.000 đ hiện "lãi gộp −48.000 đ" thay vì +62.000 đ).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.ReconcileOrderAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.GetCustomerOwnerAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.SetCustomerOwnerAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.CustomerOwnerAgencyModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.OrderRoleName(System.Nullable{Lada.Framework.Data.Domains.Network.FranchiseOrderRole})">
            <summary>Tên vai của bưu cục trên đơn (plan §3.8.1) — S / L / P / PH.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.BaseLabel(Lada.Framework.Data.Domains.Network.WalletEntryType,System.Nullable{System.Decimal},System.Boolean,System.Nullable{Lada.Framework.Data.Enums.OrderFinEnum.PayFeeType},System.Nullable{Lada.Framework.Data.Domains.Network.WalletEventType})">
            <summary>
            Cơ sở tính đọc được của một dòng (plan §3.8.1): tiền thu hộ giữ / đảo theo COD, phần phí thu hộ theo phí thu hộ, còn lại theo
            cước — kèm "chính thức" (đã chốt khi nhập kho) hay "tạm tính". null khi dòng không ghi cơ sở (nạp, rút, điều chỉnh tay, mã cũ).
            E1 và E5 của đơn người gửi trả ghi cơ sở = số lái xe THỰC thu khi lấy (V-58) — không phải cước: bấm thật F2 đơn thu 120.000 /
            cước 130.000 từng hiện "Cước tạm tính 120.000 đ".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletService.EventName(Lada.Framework.Data.Domains.Network.WalletEventType)">
            <summary>Tên sự kiện.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletWithdrawalService">
            <summary>
            Lệnh rút tiền ví bưu cục (Ví v2 — plan <c>docs/plan-vi-buu-cuc-v2.md</c> §3.4 "Rút", §3.5; Docs §4 "Rút tiền"): chủ bưu cục tạo lệnh, ví
            trừ NGAY (dòng RUT) trong cùng giao dịch khoá ví; kế toán quỹ chuyển tiền rồi xác nhận, hoặc từ chối (hoàn RUT-HOAN, từ ngưỡng duyệt hai
            người thì chờ người thứ hai); chủ bưu cục huỷ lệnh còn chờ (hoàn ngay).
            </summary>
            <remarks>
            Ví = bưu cục của người gọi, tài khoản nhận = chụp từ <see cref="T:Lada.Framework.Data.Domains.Network.FranchiseWallet"/> do kế toán khai — request không mang bưu cục hay tài
            khoản (chống IDOR). Khoá ví bằng <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerStore.LockWalletAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)"/> (<c>sp_getapplock</c> chủ khoá = giao dịch) rồi mới
            đọc số dư / số lệnh hôm nay: hai lệnh rút song song xếp hàng, lệnh sau thấy lệnh trước.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletWithdrawalService.CreateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalCreateModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Chủ bưu cục tạo lệnh rút từ ví của bưu cục mình (role Withdraw).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletWithdrawalService.CancelAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Chủ bưu cục huỷ lệnh còn chờ của ví mình → hoàn ví ngay (RUT-HOAN đã chốt).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletWithdrawalService.TransferAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalTransferModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Kế toán quỹ xác nhận đã chuyển tiền (role Treasury).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletWithdrawalService.RejectAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalRejectModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Kế toán quỹ từ chối → RUT-HOAN; từ ngưỡng duyệt hai người thì RUT-HOAN chờ người duyệt thứ hai (role Approve) mới vào số dư.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletWithdrawalService.ListAsync(System.Nullable{System.Int32},System.Nullable{Lada.Framework.Data.Domains.Network.FranchiseWithdrawalStatus},Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Danh sách lệnh rút — bưu cục bị ép về ví mình; LADA (Manage / Approve / Treasury) lọc theo bưu cục hoặc xem mọi ví.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletWithdrawalService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseWalletWithdrawalService"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletWithdrawalService.CreateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalCreateModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletWithdrawalService.CancelAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletWithdrawalService.TransferAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalTransferModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletWithdrawalService.RejectAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.FranchiseWithdrawalRejectModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletWithdrawalService.ListAsync(System.Nullable{System.Int32},System.Nullable{Lada.Framework.Data.Domains.Network.FranchiseWithdrawalStatus},Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletWithdrawalService.ReverseAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor,Lada.Framework.Data.Domains.Network.FranchiseWithdrawalStatus,System.String,System.Boolean)">
            <summary>
            Huỷ (chủ bưu cục) / từ chối (kế toán quỹ) một lệnh còn chờ: khoá ví, đọc lại lệnh trong giao dịch, ghi RUT-HOAN (+) trỏ dòng RUT
            gốc. <paramref name="needsApproval"/> = RUT-HOAN chờ người duyệt thứ hai (chưa vào số dư); không thì chốt ngay và RUT gốc đánh dấu đã đảo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletWithdrawalService.LoadForUpdateAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerScope)">
            <summary>Khoá ví của lệnh rồi đọc lại lệnh (đang theo dõi) trong giao dịch — xác nhận / huỷ / từ chối song song xếp hàng ở khoá ví.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletWithdrawalService.RefusalMessage(Lada.Framework.Infrastructures.Services.Network.FranchiseWithdrawDecision)">
            <summary>Thông điệp từ chối luôn nêu số tối đa rút được ngay lúc này (plan §3.4 "Rút").</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletWithdrawalService.StartOfDayVn(System.DateTimeOffset)">
            <summary>Đầu ngày hôm nay theo giờ Việt Nam — "1 lệnh / ngày" không lệch 7 giờ khi máy chủ chạy UTC (bẫy plan §7).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseWalletWithdrawalService.StatusName(Lada.Framework.Data.Domains.Network.FranchiseWithdrawalStatus)">
            <summary>Tên trạng thái lệnh rút.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceExportContext">
            <summary>Đầu vào xuất Excel một phiên bản bảng giá nội bộ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceExportContext.#ctor(Lada.Framework.Data.Domains.Network.InternalPriceVersion,System.String,System.String,System.Collections.Generic.IReadOnlyList{Lada.Framework.Data.Domains.Network.InternalPriceCell},System.DateTimeOffset,System.Boolean)">
            <summary>Đầu vào xuất Excel một phiên bản bảng giá nội bộ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceExcelBuilder">
            <summary>
            Xuất Excel bảng giá nội bộ (SPEC §3.8 <c>GET versions/{id}/export</c>, GĐ5): đúng khung ma trận (hàng = dải cự ly, cột = nấc
            cân) và mã phiên bản ở đầu trang. Hàm THUẦN trả byte[], không lưu ra đĩa.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceExcelBuilder.Build(Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceExportContext)">
            <summary>Dựng workbook một sheet.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceNavPermissions">
            <summary>
            Bó role của bảng giá nội bộ (SPEC Q26, §3.10) và luật THUẦN đổi tập role thành cờ hiển thị.
            </summary>
            <remarks>
            Mỗi cờ tương ứng đúng bó role của endpoint nó gác (rule quyen-hien-thi). Founder vượt ở tầng attribute
            (<c>ServerRoleAuthorizationHandler</c>) nhưng hàm cờ và service phải tự cộng Founder.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceNavPermissions.Founder">
            <summary>Founder — vượt mọi kiểm tra role.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceNavPermissions.Manage">
            <summary>Soạn nháp, sửa, sao chép, sinh theo %, xem mọi bản, kiểm tra cân đối.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceNavPermissions.Approve">
            <summary>Duyệt, huỷ, đặt ngày ngừng áp dụng.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceNavPermissions.View">
            <summary>Bưu cục xem bản đang / sắp áp dụng cho chính mình.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceNavPermissions.AdminRoles">
            <summary>Đường quản trị (xem danh sách, chi tiết, cân đối, danh sách bưu cục).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceNavPermissions.ApplicableRoles">
            <summary>Đường xem bản áp dụng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceNavPermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <summary>Đổi tập role thành cờ. Rỗng / null = mọi cờ tắt (fail-closed).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceNavFlags">
            <summary>Cờ role thô (chưa xét bưu cục của người dùng).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceNavFlags.#ctor(System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
            <summary>Cờ role thô (chưa xét bưu cục của người dùng).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceNavFlags.CanSeeAll">
            <summary>Thấy mọi phiên bản / mọi bưu cục.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor">
            <summary>Người thao tác — controller dựng từ <c>User.GetCurrentUser()</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor.#ctor(System.Int32,System.String)">
            <summary>Người thao tác — controller dựng từ <c>User.GetCurrentUser()</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceAccess">
            <summary>
            Phạm vi truy cập của một người dùng: cờ role + bưu cục của họ. Fail-closed — không role, không bưu cục nhượng
            quyền thì không thấy gì.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceAccess.#ctor(Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceNavFlags,System.Int32,System.String,System.Boolean)">
            <summary>
            Phạm vi truy cập của một người dùng: cờ role + bưu cục của họ. Fail-closed — không role, không bưu cục nhượng
            quyền thì không thấy gì.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceAccess.CanSeeAll">
            <summary>Thấy mọi phiên bản / mọi bưu cục (Manage, Approve, Founder).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceAccess.CanViewOwn">
            <summary>Xem bản áp cho bưu cục mình: có role View VÀ thuộc một bưu cục nhượng quyền (SPEC Q29).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceAccess.CanAccessAgency(System.Int32)">
            <summary>Được xem bảng giá áp cho bưu cục này không.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService">
            <summary>
            Bảng giá nội bộ cho bưu cục nhượng quyền: phiên bản / phạm vi / ô, sinh theo %, duyệt, cân đối, tra bản áp dụng
            (docs/bang-gia-noi-bo/SPEC.md §3.2–§3.3, §3.8). Luật thuần nằm ở <c>Lada.Framework/.../Network/InternalPrice*</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.GetAccessAsync(System.Int32)">
            <summary>Phạm vi truy cập của người dùng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.SearchVersionsAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Danh sách phiên bản (SmartTable). Khoá lọc: kind, status (trạng thái hiển thị), agencyId, effectiveAt, keyword.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.GetVersionAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Chi tiết một phiên bản (header, phạm vi, ô, lệch khung, quyền thao tác, xem trước điều kiện duyệt).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.CreateDraftAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Tạo nháp từ khung niêm yết hiện tại hoặc sao chép bản khác.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.UpdateDraftAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionUpdateModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Sửa nháp.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.GenerateAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceGenerateModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>"Sinh theo %".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.ApproveAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceApproveModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Duyệt.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.CancelAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceCancelModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Huỷ (nháp: người soạn hoặc người duyệt; bản đã duyệt: người duyệt).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.SetEffectiveToAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceEffectiveToModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Đặt / bỏ ngày ngừng áp dụng của bản đã duyệt.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.BalanceCheckAsync(System.Nullable{System.Int32},System.Nullable{System.DateTime},System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Kiểm tra cân đối tại một ngày cho một bưu cục (null = toàn mạng), có thể thay một bảng bằng bản nháp.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.GetApplicableAsync(System.Nullable{System.Int32},System.Nullable{System.DateTime},Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Ba bảng đang áp + sắp áp cho một bưu cục (bưu cục: chỉ bưu cục của mình).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.SuggestVersionCodeAsync(Lada.Framework.Data.Domains.Network.InternalPriceTableKind,System.Nullable{System.DateTime},Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Gợi ý mã phiên bản theo mẫu <c>InternalPrice.VersionCodePattern</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.GetFranchiseAgenciesAsync(Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Bưu cục nhượng quyền để chọn phạm vi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.ResolveAsync(Lada.Framework.Data.Domains.Network.InternalPriceTableKind,System.Nullable{System.Int32},System.DateTime)">
            <summary>Bản áp dụng kèm ô (không kiểm quyền — dùng nội bộ cho Ví bưu cục).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.ExportVersionAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <summary>Xuất Excel một phiên bản (SPEC §3.8 <c>GET versions/{id}/export</c>, GĐ5) — cùng luật xem như <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.GetVersionAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService.SendEffectiveSoonRemindersAsync(System.DateTime)">
            <summary>
            Nhắc bưu cục về các bản bắt đầu áp dụng sau đúng <c>InternalPrice.ReminderDaysBefore</c> ngày (job 08:00, SPEC §3.11);
            trả số người nhận.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IInternalPriceService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.MinRetainPercentKey">
            <summary>Khoá AppConfig ngưỡng % giữ lại.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.VersionCodePatternKey">
            <summary>Khoá AppConfig mẫu mã phiên bản.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.ChangedMessage">
            <summary>Câu trả khi bản đã bị người khác sửa sau lúc mở.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.ReminderDaysKey">
            <summary>Khoá AppConfig: số ngày trước ngày hiệu lực thì nhắc bưu cục (seed 3, migration M202610171200).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.GetAccessAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.SearchVersionsAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.GetVersionAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.CreateDraftAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionCreateModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.UpdateDraftAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceVersionUpdateModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.GenerateAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceGenerateModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.ApproveAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceApproveModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.CancelAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceCancelModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.SetEffectiveToAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Network.InternalPriceEffectiveToModel,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.EvaluateApproval(Lada.Framework.Data.Domains.Network.InternalPriceVersion,System.Collections.Generic.Dictionary{System.Int32,Lada.Framework.Infrastructures.Services.Network.InternalPriceVersionInfo},System.Collections.Generic.List{Lada.Framework.Data.Domains.Network.InternalPriceCell},Lada.Framework.Infrastructures.Services.Network.InternalPriceFrameCheck,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceAccess,System.Collections.Generic.List{System.String})">
            <summary>
            Mọi điều kiện duyệt (SPEC §3.3 mục 4, 6, 7): người duyệt, ngày, phạm vi, lệch khung, giá ô, chồng hiệu lực.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.BalanceCheckAsync(System.Nullable{System.Int32},System.Nullable{System.DateTime},System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.GetApplicableAsync(System.Nullable{System.Int32},System.Nullable{System.DateTime},Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.SuggestVersionCodeAsync(Lada.Framework.Data.Domains.Network.InternalPriceTableKind,System.Nullable{System.DateTime},Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.GetFranchiseAgenciesAsync(Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.ExportVersionAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceActor)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.SendEffectiveSoonRemindersAsync(System.DateTime)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.AffectedAgencyIdsAsync(Lada.Framework.Data.Domains.Network.InternalPriceVersion)">
            <summary>
            Bưu cục nhượng quyền (chưa xoá) mà bản này là bản áp dụng vào chính ngày bắt đầu của nó: bản toàn mạng không tính
            bưu cục đang có bản riêng phủ ngày đó (phạm vi hẹp thắng, SPEC §3.3).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.ResolveAsync(Lada.Framework.Data.Domains.Network.InternalPriceTableKind,System.Nullable{System.Int32},System.DateTime)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.IsVisibleToAgency(Lada.Framework.Infrastructures.Services.Network.InternalPriceVersionInfo,System.Collections.Generic.IEnumerable{Lada.Framework.Infrastructures.Services.Network.InternalPriceVersionInfo},System.Int32,System.DateTime)">
            <summary>Bản có đang áp hoặc sắp áp cho bưu cục này không (luật xem của role View).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.RouteInfoAsync">
            <summary>Hàng = dải (hoặc một hàng cho phí lấy / giao), cột = nấc cân — khuôn ma trận của priceList.vue.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.InternalPriceService.IsStale(Lada.Framework.Data.Domains.Network.InternalPriceVersion,System.Nullable{System.DateTimeOffset})">
            <summary>Bản đã được sửa sau dấu thời gian màn hình đang giữ (lệch quá 1 ms — JS cắt tới ms).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.IOfficialFeeRequoter">
            <summary>
            Tính lại cước theo cân thật khi kho LADA nhập kho (chốt cước chính thức, plan v2 §3.3) — bọc <see cref="T:Lada.Framework.Infrastructures.Services.Fees.IFeeQuoteEngine"/> +
            <see cref="T:Lada.Framework.Infrastructures.Services.IOrderFinCalculationService"/> sau một mặt cắt nhỏ để tầng service test được bằng stub (review GĐ B F5, 26/10/2026:
            nhánh tính lại là nhánh duy nhất làm cước chính thức khác tạm tính, sống ở production mà không có test nào chạy qua).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IOfficialFeeRequoter.VolumetricGram(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerPackage)">
            <summary>
            Cân thể tích (gram) của một kiện × số lượng — cùng luật <see cref="M:Lada.Framework.Infrastructures.Services.IOrderFinCalculationService.CalculateChargeableWeight(System.Int32,System.Int32,System.Int32,System.Int32,System.Int32)"/> với
            cân khai = 0. Kho cân cả đơn một số nên cân tính cước = max(cân bàn, Σ cân thể tích) (review GĐ B F1).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.IOfficialFeeRequoter.RequoteAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerOrderSnapshot,System.Int32)">
            <summary>Cước (gồm VAT, phí thu hộ, phụ phí) theo cân tính cước mới, cùng pipeline tạo đơn (<c>OrderService.GetOrderFin</c>); null = engine báo lỗi.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Network.OfficialFeeRequoter">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Network.IOfficialFeeRequoter"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.OfficialFeeRequoter.VolumetricGram(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerPackage)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Network.OfficialFeeRequoter.RequoteAsync(Ladaer.BackEnd.Infrastructures.Services.Network.FranchiseLedgerOrderSnapshot,System.Int32)">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Notifications.INotificationService">
            <summary>
            Service chính cho hệ thống thông báo.
            Xử lý gửi, nhận, quản lý thông báo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Notifications.INotificationService.SendAsync(System.String,System.Int32,System.Collections.Generic.Dictionary{System.String,System.String},System.String,System.String)">
            <summary>
            Gửi thông báo bằng SystemName (dynamic category).
            Tự động dùng template từ NotificationCategory.
            </summary>
            <param name="systemName">SystemName của NotificationCategory</param>
            <param name="targetUserId">User ID nhận thông báo</param>
            <param name="data">Data để replace template placeholders (VD: OrderCode, OrderId...)</param>
            <param name="titleOverride">Override tiêu đề (null = dùng template)</param>
            <param name="contentOverride">Override nội dung (null = dùng template)</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Notifications.INotificationService.SendToUsersAsync(System.String,System.Collections.Generic.List{System.Int32},System.Collections.Generic.Dictionary{System.String,System.String},System.String,System.String)">
            <summary>
            Gửi thông báo cho nhiều users cùng lúc
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Notifications.INotificationService.SendToRoleAsync(System.String,System.String,System.Collections.Generic.Dictionary{System.String,System.String},System.String,System.String)">
            <summary>
            Gửi thông báo theo role
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Notifications.INotificationService.SendBroadcastAsync(System.String,System.Collections.Generic.Dictionary{System.String,System.String},System.String,System.String)">
            <summary>
            Gửi broadcast cho tất cả users
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Notifications.INotificationService.SendFromAdminAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.SendNotificationModel,System.Int32)">
            <summary>
            Gửi thông báo từ Admin (manual send)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Notifications.INotificationService.GetUserNotificationsAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.NotificationFilter)">
            <summary>
            Lấy danh sách thông báo của user (phân trang)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Notifications.INotificationService.GetUnreadCountAsync(System.Int32)">
            <summary>
            Đếm số thông báo chưa đọc
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Notifications.INotificationService.MarkAsReadAsync(System.Int32,System.Guid)">
            <summary>
            Đánh dấu 1 thông báo đã đọc
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Notifications.INotificationService.MarkAllAsReadAsync(System.Int32)">
            <summary>
            Đánh dấu tất cả thông báo đã đọc
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Notifications.INotificationService.DeleteAsync(System.Int32,System.Guid)">
            <summary>
            Xóa (archive) 1 thông báo
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Notifications.INotificationService.GetPreferencesAsync(System.Int32)">
            <summary>
            Lấy danh sách cấu hình thông báo của user
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Notifications.INotificationService.UpdatePreferencesAsync(System.Int32,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.UpdatePreferenceModel})">
            <summary>
            Cập nhật cấu hình thông báo
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Notifications.INotificationService.RegisterDeviceTokenAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Notifications.RegisterDeviceTokenModel)">
            <summary>
            Đăng ký device token cho push notification
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Notifications.INotificationService.RemoveDeviceTokenAsync(System.Int32,System.Int32)">
            <summary>
            Xóa device token
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Notifications.NotificationCategorySeed">
            <summary>
            Seed data mặc định cho NotificationCategory.
            Chạy khi ứng dụng khởi động để đảm bảo các category cơ bản tồn tại.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Notifications.NotificationService">
            <summary>
            Implementation chính cho NotificationService.
            Xử lý logic gửi thông báo + push qua SignalR + lưu DB.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Notifications.NotificationService.ReplaceTemplatePlaceholders(System.String,System.Collections.Generic.Dictionary{System.String,System.String})">
            <summary>
            Replace {{placeholder}} trong template bằng giá trị thực.
            </summary>
            <remarks>
            Uỷ quyền cho <see cref="T:Lada.Framework.Infrastructures.Services.Notifications.NotificationTemplate"/> — cùng luật với kênh app khách, và có lưới
            dọn placeholder mà nơi gọi quên truyền dữ liệu (bản cũ để lọt nguyên văn ra giao diện).
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.OrderBusiness.IOrderFailReasonService">
            <summary>
            Interface quản lý lý do thất bại lấy/giao hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.OrderBusiness.IOrderFailReasonService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm lý do thất bại
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.OrderBusiness.IOrderFailReasonService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.OrderBusiness.OrderFailReasonModel)">
            <summary>
            Tạo hoặc cập nhật lý do thất bại
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.OrderBusiness.IOrderFailReasonService.GetById(System.Int32)">
            <summary>
            Lấy thông tin lý do thất bại theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.OrderBusiness.IOrderFailReasonService.Delete(Ladaer.BackEnd.Infrastructures.DTO.Models.OrderBusiness.OrderFailReasonModel)">
            <summary>
            Xóa lý do thất bại (soft delete)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.OrderBusiness.IOrderFailReasonService.GetByType(System.Int32)">
            <summary>
            Lấy danh sách lý do thất bại theo loại (cho Driver App)
            Chỉ trả về Active = true
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.OrderBusiness.OrderFailReasonService">
            <summary>
            Service quản lý lý do thất bại lấy/giao hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.OrderBusiness.OrderFailReasonService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm lý do thất bại
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.OrderBusiness.OrderFailReasonService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.OrderBusiness.OrderFailReasonModel)">
            <summary>
            Tạo hoặc cập nhật lý do thất bại
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.OrderBusiness.OrderFailReasonService.GetById(System.Int32)">
            <summary>
            Lấy thông tin lý do thất bại theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.OrderBusiness.OrderFailReasonService.Delete(Ladaer.BackEnd.Infrastructures.DTO.Models.OrderBusiness.OrderFailReasonModel)">
            <summary>
            Xóa lý do thất bại (soft delete)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.OrderBusiness.OrderFailReasonService.GetByType(System.Int32)">
            <summary>
            Lấy danh sách lý do thất bại theo loại (cho Driver App)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportTemplate`1">
            <summary>
            Interface cho template xuất Excel đơn hàng
            </summary>
            <typeparam name="TExportItem">Loại DTO export</typeparam>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportTemplate`1.TemplateName">
            <summary>
            Tên template
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportTemplate`1.Description">
            <summary>
            Mô tả template
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportTemplate`1.DefaultWorksheetName">
            <summary>
            Tên worksheet mặc định
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportTemplate`1.ConvertOrdersToExportItemsAsync(System.Collections.Generic.List{Lada.Framework.Data.Domains.Orders.Order})">
            <summary>
            Chuyển đổi danh sách Order thành danh sách DTO export
            </summary>
            <param name="orders">Danh sách đơn hàng</param>
            <returns>Danh sách DTO export</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportTemplate`1.SetupHeaders(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Thiết lập header cho Excel
            </summary>
            <param name="worksheet">Worksheet</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportTemplate`1.FillDataAsync(OfficeOpenXml.ExcelWorksheet,System.Collections.Generic.List{`0})">
            <summary>
            Điền dữ liệu vào Excel
            </summary>
            <param name="worksheet">Worksheet</param>
            <param name="exportItems">Danh sách DTO export</param>
            <returns>Task</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportTemplate`1.FormatWorksheet(OfficeOpenXml.ExcelWorksheet,System.Int32)">
            <summary>
            Định dạng Excel worksheet
            </summary>
            <param name="worksheet">Worksheet</param>
            <param name="dataRowCount">Số dòng dữ liệu</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportTemplate`1.ValidateDataAsync(System.Collections.Generic.List{Lada.Framework.Data.Domains.Orders.Order})">
            <summary>
            Validate dữ liệu trước khi xuất
            </summary>
            <param name="orders">Danh sách đơn hàng</param>
            <returns>Kết quả validation</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportTemplate`1.GetDefaultFileName(System.String)">
            <summary>
            Lấy tên file mặc định
            </summary>
            <param name="prefix">Prefix tên file</param>
            <returns>Tên file</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.BaseOrderExportTemplate`1">
            <summary>
            Abstract base class cho Order Export Template
            </summary>
            <typeparam name="TExportItem">Loại DTO export</typeparam>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.BaseOrderExportTemplate`1.ValidateDataAsync(System.Collections.Generic.List{Lada.Framework.Data.Domains.Orders.Order})">
            <summary>
            Validation mặc định - có thể override
            </summary>
            <param name="orders">Danh sách đơn hàng</param>
            <returns>Kết quả validation</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.BaseOrderExportTemplate`1.GetDefaultFileName(System.String)">
            <summary>
            Tạo tên file mặc định
            </summary>
            <param name="prefix">Prefix tên file</param>
            <returns>Tên file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.BaseOrderExportTemplate`1.SetupHeaderStyle(OfficeOpenXml.ExcelRange)">
            <summary>
            Thiết lập style chung cho header
            </summary>
            <param name="headerRange">Range header</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.BaseOrderExportTemplate`1.SetupDataStyle(OfficeOpenXml.ExcelRange)">
            <summary>
            Thiết lập style chung cho dữ liệu
            </summary>
            <param name="dataRange">Range dữ liệu</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.BaseOrderExportTemplate`1.FormatCurrencyColumn(OfficeOpenXml.ExcelWorksheet,System.Int32,System.Int32,System.Int32)">
            <summary>
            Định dạng cột tiền tệ
            </summary>
            <param name="worksheet">Worksheet</param>
            <param name="columnIndex">Index cột</param>
            <param name="startRow">Dòng bắt đầu</param>
            <param name="endRow">Dòng kết thúc</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.BaseOrderExportTemplate`1.FormatDecimalColumn(OfficeOpenXml.ExcelWorksheet,System.Int32,System.Int32,System.Int32,System.Int32)">
            <summary>
            Định dạng cột số thập phân
            </summary>
            <param name="worksheet">Worksheet</param>
            <param name="columnIndex">Index cột</param>
            <param name="startRow">Dòng bắt đầu</param>
            <param name="endRow">Dòng kết thúc</param>
            <param name="decimalPlaces">Số chữ số thập phân</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportService">
            <summary>
            Interface cho dịch vụ xuất Excel đơn hàng (Generic)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportService.ExportOrdersAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel)">
            <summary>
            Xuất Excel đơn hàng với template được chỉ định
            </summary>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportService.ExportOrdersWithFilterAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel)">
            <summary>
            Xuất Excel đơn hàng với filter nâng cao
            </summary>
            <param name="model">Model xuất Excel với filter</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportService.GetAvailableTemplates">
            <summary>
            Lấy danh sách template có sẵn
            </summary>
            <returns>Danh sách template</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportService.IsTemplateSupported(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportTemplateType)">
            <summary>
            Kiểm tra template có tồn tại không
            </summary>
            <param name="templateType">Loại template</param>
            <returns>True nếu tồn tại</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.OrderExportService">
            <summary>
            Dịch vụ xuất Excel đơn hàng (Generic)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.OrderExportService.ExportOrdersAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel)">
            <summary>
            Xuất Excel đơn hàng với template được chỉ định
            </summary>
            <param name="model">Model xuất Excel</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.OrderExportService.ExportOrdersWithFilterAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel)">
            <summary>
            Xuất Excel đơn hàng với filter nâng cao
            </summary>
            <param name="model">Model xuất Excel với filter</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.OrderExportService.GetAvailableTemplates">
            <summary>
            Lấy danh sách template có sẵn
            </summary>
            <returns>Danh sách template</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.OrderExportService.IsTemplateSupported(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportTemplateType)">
            <summary>
            Kiểm tra template có tồn tại không
            </summary>
            <param name="templateType">Loại template</param>
            <returns>True nếu tồn tại</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.OrderExportService.QueryOrdersAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel)">
            <summary>
            Query đơn hàng theo model cơ bản
            </summary>
            <param name="model">Model xuất Excel</param>
            <returns>Danh sách đơn hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.OrderExportService.QueryOrdersWithFilterAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportWithFilterModel)">
            <summary>
            Query đơn hàng với filter nâng cao
            </summary>
            <param name="model">Model xuất Excel với filter</param>
            <returns>Danh sách đơn hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.OrderExportService.ExportWithTemplateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportTemplateType,System.Collections.Generic.List{Lada.Framework.Data.Domains.Orders.Order},System.String,Ladaer.BackEnd.Infrastructures.DTO.Results.Orders.OrderExportResult)">
            <summary>
            Xuất Excel với template được chỉ định
            </summary>
            <param name="templateType">Loại template</param>
            <param name="orders">Danh sách đơn hàng</param>
            <param name="filePath">Đường dẫn file</param>
            <param name="result">Kết quả xuất</param>
            <returns>Kết quả xuất đã cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.OrderExportService.CreateExcelFileAsync``1(Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.IOrderExportTemplate{``0},System.Collections.Generic.List{``0},System.String)">
            <summary>
            Tạo file Excel với template
            </summary>
            <typeparam name="TExportItem">Loại DTO export</typeparam>
            <param name="template">Template xuất</param>
            <param name="exportItems">Danh sách items</param>
            <param name="filePath">Đường dẫn file</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.OrderExportService.GenerateFileNameAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportModel)">
            <summary>
            Tạo tên file
            </summary>
            <param name="model">Model xuất Excel</param>
            <returns>Tên file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.OrderExportService.GetFolderPath(System.String)">
            <summary>
            Lấy đường dẫn thư mục
            </summary>
            <param name="folderPath">Đường dẫn tùy chọn</param>
            <returns>Đường dẫn thư mục</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.OrderExportService.GetTemplate(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExportTemplateType)">
            <summary>
            Lấy template theo loại
            </summary>
            <param name="templateType">Loại template</param>
            <returns>Template</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.OrderExportTemplateInfo">
            <summary>
            Thông tin về template xuất Excel
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.Templates.BasicOrderExportTemplate">
            <summary>
            Template xuất Excel cơ bản cho đơn hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.Exports.Templates.FinanceOrderExportTemplate">
            <summary>
            Template xuất Excel cho mục đích tài chính (TransferPaymentBill)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderAddressService">
            <summary>
            Giao diện cho dịch vụ quản lý địa chỉ đơn hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderAddressService.GetById(System.Int32)">
            <summary>
            Lấy thông tin địa chỉ đơn hàng theo ID.
            </summary>
            <param name="id">ID của địa chỉ đơn hàng.</param>
            <returns>Thông tin địa chỉ đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderAddressService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel)">
            <summary>
            Cập nhật thông tin địa chỉ đơn hàng.
            </summary>
            <param name="model">Thông tin địa chỉ đơn hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderAddressService.UpdateCoord(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressCoordModel)">
            <summary>
            Cập nhật riêng định vị (Lat/Long) của một địa chỉ đơn hàng.
            </summary>
            <param name="model">Toạ độ mới (để null cả hai để xoá định vị).</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderAddressService.ResolveMapLink(System.String)">
            <summary>
            Bóc toạ độ từ một link Google Maps (kể cả link rút gọn maps.app.goo.gl).
            </summary>
            <param name="url">Link người dùng dán vào.</param>
            <returns>Toạ độ bóc được hoặc thông báo lỗi.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAddressService">
            <summary>
            Triển khai dịch vụ quản lý địa chỉ đơn hàng.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAddressService._orderPermissionService">
            <summary>Nơi DUY NHẤT giữ luật "ai được sửa đơn này". Đừng kiểm quyền tại chỗ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAddressService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.OrderAddress},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.OrderOps},Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService,Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderTrackService,Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderFinService,Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderPermissionService,System.Net.Http.IHttpClientFactory)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAddressService"/>.
            </summary>
            <param name="orderAddressRepository">Đối tượng IRepository của OrderAddress.</param>
            <param name="locationService">Đối tượng ILocationService.</param>
            <param name="orderTrackService">Đối tượng IOrderTrackService.</param>
            <param name="orderFinService">Đối tượng IOrderFinService.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAddressService.GetById(System.Int32)">
            <summary>
            Lấy thông tin địa chỉ đơn hàng theo ID.
            </summary>
            <param name="id">ID của địa chỉ đơn hàng.</param>
            <returns>Thông tin địa chỉ đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAddressService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel)">
            <summary>
            Cập nhật thông tin địa chỉ đơn hàng.
            </summary>
            <param name="model">Thông tin địa chỉ đơn hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAddressService.UpdateCoord(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressCoordModel)">
            <summary>
            Cập nhật riêng định vị (Lat/Long). Không đụng tới tỉnh/phường nên KHÔNG tính
            lại cước và KHÔNG đổi bưu cục dự kiến — khác hẳn <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAddressService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderAddressModel)"/>.
            </summary>
            <param name="model">Toạ độ mới (null cả hai = xoá định vị).</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAddressService.ResolveMapLink(System.String)">
            <summary>
            Bóc toạ độ từ link Google Maps. Link đầy đủ đã được frontend tự parse, phần
            server lo là link RÚT GỌN (maps.app.goo.gl): browser không đọc được Location
            header của redirect nên phải nhờ server đi theo redirect rồi parse URL cuối.
            </summary>
            <param name="url">Link người dùng dán vào.</param>
            <returns>Toạ độ bóc được hoặc thông báo lỗi.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAddressService.ReadLimitedAsync(System.Net.Http.HttpResponseMessage,System.Int32)">
            <summary>Đọc tối đa <paramref name="maxBytes"/> byte đầu của body dưới dạng chuỗi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAddressService.GetAddressTrackActionType(Lada.Framework.Data.Enums.AddressType)">
            <summary>Loại hành trình tương ứng với loại địa chỉ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAddressService.BuildCoordTrackName(Lada.Framework.Data.Domains.Orders.OrderAddress,System.Boolean,System.String)">
            <summary>Câu mô tả hành trình cho thao tác cập nhật định vị.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyScope">
            <summary>
            Nhóm đơn trên màn "Đơn hàng bưu cục" — đơn nào được coi là "của bưu cục mình".
            </summary>
            <remarks>
            Giá trị đi qua API dạng số (khoá <c>Scope</c> trong <c>Search.PredicateObject</c>) — đừng đánh số lại.
            Năm nhóm theo sơ đồ vai "Chủ bưu cục (nhà đầu tư)": lấy hàng (dự kiến / đã lấy), giao hàng (dự kiến /
            đã nhận từ kho tổng), đơn do nhân sự bưu cục tạo.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyScope.ExpectPickup">
            <summary>Đơn lấy hàng — bưu cục mình dự kiến lấy (<c>OrderOps.ExpectAgencyPickupId</c>, suy từ phường lấy hàng).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyScope.PickedUp">
            <summary>Đơn lấy hàng — bưu cục mình đã lấy (<c>OrderOps.AgencyPickedupId</c>, SP lấy hàng ghi theo chi nhánh người bấm).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyScope.ExpectDelivery">
            <summary>Đơn giao hàng — bưu cục mình dự kiến giao (<c>OrderOps.ExpectAgencyDeliveryId</c>, suy từ phường giao hàng).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyScope.ReceivedFromHub">
            <summary>
            Đơn giao hàng — bưu cục mình đã nhận từ kho tổng: có lượt nhập kho (<see cref="F:Lada.Framework.Data.Enums.TrackActionType.Inbound"/>)
            tại bưu cục mình, kể cả khi bưu cục dự kiến giao là nơi khác.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyScope.CreatedByStaff">
            <summary>Đơn sale hàng — do nhân sự bưu cục mình tạo.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyScopeFilter">
            <summary>
            Luật lọc đơn theo <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyScope"/> — một chỗ duy nhất, test được bằng LINQ trên bộ nhớ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyScopeFilter.Apply(System.Linq.IQueryable{Lada.Framework.Data.Domains.Orders.Order},Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyScope,System.Int32,System.Linq.IQueryable{Lada.Framework.Data.Domains.Identity.User},System.Linq.IQueryable{Lada.Framework.Data.Domains.Orders.OrderTrack})">
            <summary>
            Lọc <paramref name="orders"/> theo nhóm của bưu cục <paramref name="agencyId"/>.
            </summary>
            <remarks>
            <para>
            <b><paramref name="agencyId"/> ≤ 0 trả rỗng</b>, không bao giờ lọc "bằng 0": <c>AgencyPickedupId = 0</c> là mọi đơn
            chưa lấy, <c>CreatedAgencyId = 0</c> là mọi đơn từ app khách — người chưa gắn bưu cục sẽ thấy cả hệ thống.
            </para>
            <para>
            <b>Nhận từ kho tổng</b> quy lượt nhập kho về bưu cục đúng như <c>AnalyticsHubEventFactBuilder</c>: lấy
            <c>OrderTrack.AgencyId</c> nếu có, không thì lấy chi nhánh hiện tại của người bấm (<c>CreatedBy</c>) —
            <c>WarehouseService.Inbound</c> không ghi <c>AgencyId</c> vào dòng lịch sử (đo dev 20/10/2026: 39.294 / 59.995
            lượt nhập kho có <c>AgencyId</c>). Bưu cục nhượng quyền chỉ nhập kho ở chiều giao, nên Ví bưu cục cũng gọi sự
            kiện này là "Nhận hàng từ kho tổng" (<c>WalletEventType.InboundAtBranch</c>).
            </para>
            <para>
            <b>Nhân sự tạo</b> tin <c>Order.CreatedAgencyId</c> trước (Ví bưu cục đóng dấu, giữ đúng bưu cục lúc tạo dù
            nhân sự chuyển chỗ sau này); dấu đó chỉ có khi job Ví đã chạy qua đơn, nên còn trống thì tra chi nhánh
            hiện tại của người tạo.
            </para>
            </remarks>
            <param name="orders">Tập đơn gốc.</param>
            <param name="scope">Nhóm cần lọc.</param>
            <param name="agencyId">Bưu cục của người xem.</param>
            <param name="users">Bảng người dùng — để biết ai là nhân sự của bưu cục.</param>
            <param name="tracks">Lịch sử đơn — để tìm lượt nhập kho.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyScopeFilter.Parse(System.Object)">
            <summary>
            Đọc khoá <c>Scope</c> từ <c>PredicateObject</c>; thiếu hoặc lạ thì về <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyScope.ExpectPickup"/>
            (tab đầu tiên của màn).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyNavFlags">
            <summary>Cờ hiển thị của màn "Đơn hàng bưu cục".</summary>
            <param name="CanView">Có role xem đơn bưu cục (hoặc Founder) <b>và</b> tài khoản đã gắn một bưu cục.</param>
            <param name="HasRole">Có role xem đơn bưu cục (hoặc Founder) — tách riêng để màn nói đúng lý do khi chưa gắn bưu cục.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyNavFlags.#ctor(System.Boolean,System.Boolean)">
            <summary>Cờ hiển thị của màn "Đơn hàng bưu cục".</summary>
            <param name="CanView">Có role xem đơn bưu cục (hoặc Founder) <b>và</b> tài khoản đã gắn một bưu cục.</param>
            <param name="HasRole">Có role xem đơn bưu cục (hoặc Founder) — tách riêng để màn nói đúng lý do khi chưa gắn bưu cục.</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyNavFlags.CanView">
            <summary>Có role xem đơn bưu cục (hoặc Founder) <b>và</b> tài khoản đã gắn một bưu cục.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyNavFlags.HasRole">
            <summary>Có role xem đơn bưu cục (hoặc Founder) — tách riêng để màn nói đúng lý do khi chưa gắn bưu cục.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyNavPermissions">
            <summary>
            Luật "ai xem được màn Đơn hàng bưu cục" — hàm thuần nhận danh sách role đã phân giải (rule quyen-hien-thi).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyNavPermissions.ViewRole">
            <summary>Role gác <c>POST api/Order/SearchByAgency</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyNavPermissions.Founder">
            <summary>Vai bỏ qua mọi kiểm tra role của hệ thống.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyNavPermissions.Resolve(System.Collections.Generic.IEnumerable{System.String},System.Int32)">
            <summary>Tính cờ từ role và bưu cục của người xem.</summary>
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c>; <c>null</c> = không có role nào.</param>
            <param name="agencyId">Bưu cục của người xem (<c>User.AgencyId</c>), 0 = chưa gắn.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderFinService">
            <summary>
            Interface để định nghĩa các phương thức xử lý tài chính đơn hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderFinService.UpdateOrderFinAsync(System.Int32,System.Int32,System.String)">
            <summary>
            Cập nhật tài chính đơn hàng không đồng bộ.
            </summary>
            <param name="orderId">ID của đơn hàng.</param>
            <param name="updatedBy">ID của người cập nhật.</param>
            <param name="updatedByUserName">Tên người cập nhật.</param>
            <returns>Kết quả của hoạt động cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderFinService.GetById(System.Int32)">
            <summary>
            Lấy thông tin tài chính đơn hàng dựa trên ID.
            </summary>
            <param name="id">ID của tài chính đơn hàng.</param>
            <returns>Thông tin tài chính đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderFinService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel)">
            <summary>
            Cập nhật thông tin tài chính đơn hàng.
            </summary>
            <param name="model">Model chứa thông tin tài chính đơn hàng.</param>
            <returns>Kết quả của hoạt động cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderFinService.Collect(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.CollectMoneyModel)">
            <summary>
            Thu tiền
            </summary>
            <param name="model"></param>
            <returns></returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService">
             <summary>
             Lớp triển khai các phương thức xử lý tài chính đơn hàng.
             </summary>
             <remarks>
             ⚠️ <b>Lớp này đang được bóc tách dần sang <c>Lada.Framework</c>.</b> Nợ N18 từng sống được nhiều
             tháng vì luật tiền ở đây không có ca test nào canh.
            
             Phần đã bóc: ba luật quyết định tiền (áp giá cố định, phí thu hộ, phân bổ theo loại trả cước) nay
             ở <see cref="T:Lada.Framework.Infrastructures.Services.IOrderFinCalculationService"/> và được canh bởi <c>OrderFinCalculationServiceTests</c>.
             Phần còn ở đây: truy vấn database, gọi engine tính cước, ghi hành trình — còn cần
             <c>IRepository</c> và DTO của project API. <b>Đừng thêm luật tiền mới vào file này</b>; thêm vào
             service ở Framework rồi gọi sang, để nó có test.
            
             <b>Đính chính 2026-08-07.</b> Ghi chú cũ nói "<c>Ladaer.BackEnd.Tests</c> chỉ tham chiếu
             <c>Lada.Framework</c> ⇒ không test được lớp này" là SAI: csproj test tham chiếu cả hai project,
             nên dựng thẳng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService"/> với repository giả được. <c>Update</c> nay đã có
             <c>OrderFinUpdateRecalculateFeeTests</c> canh hành trình "sửa loại hàng thì tính lại cước"
             (7 ca, đã qua 3 mật thử lật cờ). Các method còn lại vẫn chưa có test — không phải vì không
             viết được, mà vì chưa viết.
             </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService._orderPermissionService">
            <summary>
            Nơi DUY NHẤT giữ luật "ai được sửa đơn này". Đừng tự kiểm quyền tại chỗ: luật cũ từng được dán
            tay ở 6 service và cả 6 đều so sai property nên người quản lý khách hàng chưa từng sửa được đơn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService.#ctor(Microsoft.Extensions.Options.IOptions{Ladaer.BackEnd.Infrastructures.AppSettings.AppSetting},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.Order},Lada.Framework.Infrastructures.Services.IFeeService,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.OrderFin},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.OrderPackage},Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderTrackService,Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService,Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderGoodsAttributeService,Lada.Framework.Infrastructures.Services.IGoodsCategoryPricingService,Lada.Framework.Infrastructures.Services.IOrderFinCalculationService,Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderPermissionService,Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService)">
            <summary>
            Khởi tạo một instance mới của lớp <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService"/>.
            </summary>
            <param name="options">Tùy chọn cấu hình ứng dụng.</param>
            <param name="orderRepository">Kho lưu trữ đơn hàng.</param>
            <param name="feeService">Dịch vụ tính phí.</param>
            <param name="orderFinRepository">Kho lưu trữ tài chính đơn hàng.</param>
            <param name="orderPackageRepository">Kho lưu trữ kiện hàng.</param>
            <param name="orderTrackService">Dịch vụ theo dõi đơn hàng.</param>
            <param name="userService">Dịch vụ người dùng.</param>
            <param name="orderGoodsAttributeService">Dịch vụ snapshot thuộc tính loại hàng của đơn.</param>
            <param name="goodsCategoryPricingService">Dịch vụ áp giá theo loại hàng (resolve giá từ DB).</param>
            <param name="orderFinCalculationService">
            Lớp quyết định tiền đã bóc sang <c>Lada.Framework</c> — nơi duy nhất giữ ba luật: áp giá cố định,
            phí thu hộ, phân bổ theo loại trả cước. Có test canh nên đừng viết lại luật ở đây.
            </param>
            <param name="orderPermissionService">
            Nơi duy nhất giữ luật "ai được sửa đơn này" (người quản lý khách hàng, sale phụ trách, Founder).
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService.GetById(System.Int32)">
            <summary>
            Lấy thông tin tài chính đơn hàng dựa trên ID.
            </summary>
            <param name="id">ID của tài chính đơn hàng.</param>
            <returns>Thông tin tài chính đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel)">
            <summary>
            Cập nhật thông tin tài chính đơn hàng.
            </summary>
            <param name="model">Model chứa thông tin tài chính đơn hàng.</param>
            <returns>Kết quả của hoạt động cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService.UpdateOrderFinAsync(System.Int32,System.Int32,System.String)">
            <summary>
            Cập nhật tài chính đơn hàng không đồng bộ.
            </summary>
            <param name="orderId">ID của đơn hàng.</param>
            <param name="updatedBy">ID của người cập nhật.</param>
            <param name="updatedByUserName">Tên người cập nhật.</param>
            <returns>Kết quả của hoạt động cập nhật.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService.ResolveRouteFeeForOrderAsync(System.Int32,System.Nullable{System.Int32})">
            <summary>
            Tra cước tuyến hiện tại cho một đơn ĐÃ LƯU: nạp địa chỉ + kiện hàng từ database, tính trọng
            lượng tính cước, rồi hỏi engine.
            </summary>
            <param name="orderId">Id đơn hàng (cũng là Id của <c>OrderFin</c>).</param>
            <param name="goodsCategoryId">
            Danh mục hàng hoá dùng để tra cước. Truyền tường minh vì <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel)"/> có thể ĐANG đổi
            danh mục — đọc <c>Order.GoodsCategoryId</c> lúc này sẽ ra giá trị cũ.
            </param>
            <returns>
            Cước tuyến, hoặc <c>null</c> khi không tra được (đơn thiếu địa chỉ / thiếu kiện / tuyến chưa có
            bảng giá). <b>Trả <c>null</c> chứ không trả 0</b>: 0 là một mức cước hợp lệ, còn "không tra được"
            là chuyện khác — nhập nhèm hai cái này sẽ zero hoá cước của đơn có thật.
            </returns>
            <remarks>
            Tách riêng khỏi <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService.UpdateOrderFinAsync(System.Int32,System.Int32,System.String)"/> vì hàm đó còn ghi database, ghi hành trình và
            cập nhật <c>SubTotalWeight</c> — <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderFinModel)"/> chỉ cần con số cước. Dùng chung luật trọng
            lượng ở <see cref="M:Lada.Framework.Infrastructures.Services.IOrderFinCalculationService.CalculateChargeableWeight(System.Int32,System.Int32,System.Int32,System.Int32,System.Int32)"/> để hai đường không
            lệch nhau.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService.CalculateFeeByPackageGoodsAsync(Lada.Framework.Data.Domains.Orders.Order,System.Int32,System.Int32)">
             <summary>
             Dựng lại danh sách lựa chọn thuộc tính loại hàng của một đơn ĐÃ LƯU, từ snapshot
             <c>OrderGoodsAttributes</c>, để truyền xuống engine tính cước.
             </summary>
             <remarks>
             Vì sao cần: <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService.UpdateOrderFinAsync(System.Int32,System.Int32,System.String)"/> tính lại cước cho đơn đã tồn tại nên không có
             payload client. Engine cần <c>OptionId</c> của thuộc tính TRỤC GIÁ để tra ô bảng giá đặc thù;
             không truyền thì engine rơi về trục trọng lượng và cước tụt xuống giá cân.
            
             Chỉ chuyển lại LỰA CHỌN (AttributeId / OptionId / ValueText / ValueNumber), KHÔNG chuyển
             <c>Price</c> đã snapshot: giá luôn resolve lại từ DB, đúng nguyên tắc "không tin giá client gửi".
             Hệ quả phải biết: cước tính lại dùng giá HIỆN TẠI của cấu hình, không phải giá lúc lên đơn —
             đó là đúng ý của chức năng "tính lại cước".
            
             <c>MultiSelect</c> lưu mỗi lựa chọn một dòng snapshot, nên gom theo <c>AttributeId</c> và dồn
             vào <c>OptionIds</c>; nếu chỉ có một dòng thì điền cả <c>OptionId</c> để <c>SingleSelect</c>
             (kiểu của trục giá) đọc được.
             </remarks>
             <summary>
             Cước tuyến của đơn khai loại hàng THEO KIỆN — tra giá từng loại rồi cộng.
             </summary>
             <param name="order">Đơn đã nạp sẵn <c>Packages</c>.</param>
             <param name="sourceWardId">Phường gửi.</param>
             <param name="destWardId">Phường nhận.</param>
             <returns>
             <c>null</c> khi <b>không kiện nào khai loại hàng</b> — nơi gọi giữ nguyên đường tính cũ. Ngược lại
             trả kết quả có <c>Fee</c> là tổng cước, hoặc <c>Result != Success</c> kèm thông báo nêu tên món hỏng.
             </returns>
             <remarks>
             <para>
             Gộp kiện cùng loại + cùng thuộc tính trước khi tra (<see cref="T:Lada.Framework.Infrastructures.Services.GoodsLineGrouper"/>): bảng giá theo
             cân là bậc thang, tra riêng từng kiện rồi cộng sẽ ra số khác với tra trên tổng trọng lượng.
             </para>
             <para>
             ⚠️ Khác engine lúc tạo đơn ở một điểm đã có từ trước: hàm này KHÔNG áp QĐ-1 (điền loại mặc định
             cho dòng không khai) vì nó gọi thẳng <c>IFeeService</c>. Dòng không khai loại vẫn tra bảng giá
             chung theo cân, đúng như hành vi cũ của chính hàm này với <c>order.GoodsCategoryId</c> rỗng.
             </para>
             </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService.BuildSelectedAttributesByPackageAsync(System.Int32)">
            <summary>
            Dựng lựa chọn thuộc tính của TỪNG KIỆN từ snapshot, cho đơn khai loại hàng theo kiện.
            </summary>
            <returns>Từ điển theo <c>OrderPackageId</c>. Rỗng khi đơn không có snapshot gắn kiện nào.</returns>
            <remarks>
            Chỉ lấy dòng có <c>OrderPackageId</c>: dòng để trống là thuộc tính CẤP ĐƠN của đơn cũ, gán bừa
            vào một kiện sẽ làm kiện đó mọc thêm phụ phí không phải của nó.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService.BuildSelected(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderGoodsAttributeItem})">
            <summary>
            Gom snapshot thành lựa chọn thuộc tính — phần dùng chung của hai hàm dựng ở trên.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderFinService.Collect(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.CollectMoneyModel)">
            <summary>
            Thu tiền
            </summary>
            <param name="model">Model chứa thông tin thu tiền của đơn hàng.</param>
            <returns>Kết quả của hoạt động cập nhật.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderGoodsAttributeService">
            <summary>
            Ghi / đọc snapshot thuộc tính loại hàng của đơn (bảng OrderGoodsAttributes).
            Giá LUÔN resolve từ DB qua IGoodsCategoryPricingService, không tin giá client gửi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderGoodsAttributeService.SaveForOrderAsync(System.Int32,System.Nullable{System.Int32},System.Collections.Generic.List{Lada.Framework.DTO.SelectedGoodsAttributeModel},System.Int32,System.String,System.Boolean)">
            <summary>
            Ghi snapshot thuộc tính cho một đơn.
            Khi sửa đơn: xóa CỨNG các dòng cũ rồi ghi lại theo payload mới (snapshot lấy giá hiện tại).
            Đơn không chọn danh mục / không có thuộc tính: không ghi gì, trả về phí = 0.
            </summary>
            <param name="orderId">Id đơn hàng</param>
            <param name="categoryId">Danh mục hàng hóa, null = không phân loại</param>
            <param name="selected">Lựa chọn của client</param>
            <param name="updatedBy">Id người thực hiện</param>
            <param name="updatedByUserName">Tên người thực hiện</param>
            <param name="removeExisting">True khi sửa đơn — xóa cứng dòng cũ trước khi ghi lại</param>
            <returns>Kết quả áp giá của danh mục (phí thuộc tính, có phải giá cố định hay không)</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderGoodsAttributeService.SaveForPackagesAsync(System.Int32,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageGoodsModel},System.Int32,System.String,System.Boolean)">
            <summary>
            Ghi snapshot thuộc tính cho TỪNG KIỆN của một đơn nhiều loại hàng.
            </summary>
            <remarks>
            <para>
            Dùng cho đơn khai loại hàng theo kiện (1 xe máy + 1 kiện hàng): mỗi kiện có loại riêng nên có bộ
            thuộc tính riêng, snapshot phải gắn <c>OrderPackageId</c> để chi tiết đơn hiện đúng thuộc tính
            của từng món.
            </para>
            <para>
            Cố ý KHÔNG gộp vào <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderGoodsAttributeService.SaveForOrderAsync(System.Int32,System.Nullable{System.Int32},System.Collections.Generic.List{Lada.Framework.DTO.SelectedGoodsAttributeModel},System.Int32,System.String,System.Boolean)"/> bằng tham số thêm: hàm kia trả về
            <see cref="T:Lada.Framework.Infrastructures.Services.GoodsCategoryPricingResult"/> của <b>một</b> danh mục và nơi gọi đang dùng kết quả đó
            để lấy phí thuộc tính; đơn nhiều loại thì phí ấy đến từ engine cước, không phải từ một lời gọi
            resolve đơn lẻ. Trộn hai việc vào một hàm là mời gọi lấy nhầm số.
            </para>
            <para>
            ⚠️ Xoá cứng dòng cũ theo <b>đơn</b> (không theo kiện) khi <paramref name="removeExisting"/> bật:
            sửa đơn có thể xoá hẳn một kiện, xoá theo kiện sẽ để lại thuộc tính mồ côi.
            </para>
            </remarks>
            <param name="orderId">Id đơn hàng</param>
            <param name="packages">Danh sách kiện kèm loại hàng và lựa chọn thuộc tính của từng kiện</param>
            <param name="updatedBy">Id người thực hiện</param>
            <param name="updatedByUserName">Tên người thực hiện</param>
            <param name="removeExisting">True khi sửa đơn — xóa cứng dòng cũ của cả đơn trước khi ghi lại</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderGoodsAttributeService.GetByOrderIdAsync(System.Int32)">
            <summary>
            Lấy snapshot thuộc tính của đơn để hiển thị chi tiết đơn
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderGoodsAttributeService.GetByOrderIdsAsync(System.Collections.Generic.List{System.Int32})">
            <summary>
            Lấy snapshot thuộc tính của nhiều đơn (gom theo OrderId) — dùng cho danh sách đơn
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderGoodsAttributeService.GetSelectedByPackageAsync(System.Int32)">
            <summary>
            Lựa chọn thuộc tính của từng kiện, dạng client gửi lên (<see cref="T:Lada.Framework.DTO.SelectedGoodsAttributeModel"/>).
            </summary>
            <param name="orderId">Id đơn hàng</param>
            <returns>Từ điển <c>OrderPackageId</c> → lựa chọn; bỏ qua snapshot cấp đơn (không có kiện).</returns>
            <remarks>
            Đây là chiều NGƯỢC của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderGoodsAttributeService.SaveForPackagesAsync(System.Int32,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageGoodsModel},System.Int32,System.String,System.Boolean)"/>: dựng lại lựa chọn để màn sửa kiện mở
            ra đúng những gì đã chọn, và để đường tính lại cước biết từng kiện chọn gì.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageGoodsModel">
            <summary>
            Một kiện hàng cần ghi snapshot thuộc tính: kiện nào, loại hàng gì, khách chọn những gì.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageGoodsModel.OrderPackageId">
            <summary>Id kiện hàng đã lưu — phải &gt; 0, kiện chưa có Id thì không ghi được snapshot.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageGoodsModel.GoodsCategoryId">
            <summary>Loại hàng của kiện, <c>null</c> = không khai.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageGoodsModel.GoodsAttributes">
            <summary>Lựa chọn thuộc tính của kiện.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderGoodsAttributeService">
            <summary>
            Triển khai ghi / đọc snapshot thuộc tính loại hàng của đơn
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderGoodsAttributeService.SaveForOrderAsync(System.Int32,System.Nullable{System.Int32},System.Collections.Generic.List{Lada.Framework.DTO.SelectedGoodsAttributeModel},System.Int32,System.String,System.Boolean)">
            <summary>
            Ghi snapshot thuộc tính cho một đơn
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderGoodsAttributeService.SaveForPackagesAsync(System.Int32,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageGoodsModel},System.Int32,System.String,System.Boolean)">
            <summary>
            Ghi snapshot thuộc tính cho từng kiện của một đơn nhiều loại hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderGoodsAttributeService.GetByOrderIdAsync(System.Int32)">
            <summary>
            Lấy snapshot thuộc tính của đơn
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderGoodsAttributeService.GetByOrderIdsAsync(System.Collections.Generic.List{System.Int32})">
            <summary>
            Lấy snapshot thuộc tính của nhiều đơn
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderGoodsAttributeService.GetSelectedByPackageAsync(System.Int32)">
            <summary>
            Lựa chọn thuộc tính của từng kiện (chiều ngược của SaveForPackagesAsync)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderGoodsAttributeService.BuildSelected(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderGoodsAttributeItem})">
            <summary>
            Gom snapshot của MỘT kiện thành lựa chọn: mỗi thuộc tính một dòng, chọn nhiều thì gom OptionIds
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderGoodsAttributeService.ToItem(Lada.Framework.Data.Domains.Orders.OrderGoodsAttribute)">
            <summary>
            Map entity snapshot sang item hiển thị
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderPackageService">
            <summary>
            Giao diện cho dịch vụ quản lý kiện hàng trong đơn hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderPackageService.GetByOrderId(System.Int32)">
            <summary>
            Lấy thông tin kiện hàng theo ID đơn hàng.
            </summary>
            <param name="orderId">ID của đơn hàng.</param>
            <returns>Thông tin kiện hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderPackageService.GetByOrderIdWithUnits(System.Int32)">
            <summary>
            Lấy thông tin kiện hàng theo ID đơn hàng với thông tin đơn vị đo.
            </summary>
            <param name="orderId">ID của đơn hàng.</param>
            <returns>Thông tin kiện hàng với đơn vị đo.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderPackageService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderPackageModel)">
            <summary>
            Cập nhật thông tin kiện hàng.
            </summary>
            <param name="model">Model chứa thông tin kiện hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageService">
            <summary>
            Triển khai dịch vụ quản lý kiện hàng trong đơn hàng.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageService._orderGoodsAttributeService">
            <summary>
            Snapshot thuộc tính loại hàng theo kiện — nguồn để màn sửa mở đúng lựa chọn cũ và ghi lại
            lựa chọn mới. Giá luôn resolve từ DB trong service này, không tin số client gửi.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageService._orderFinCalculationService">
            <summary>
            Lớp quyết định tiền ở <c>Lada.Framework</c> — dùng cho luật trọng lượng tính cước (có test canh).
            Đừng viết lại công thức trọng lượng tại chỗ: đó là cách hai đường tạo đơn / sửa kiện lệch số.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageService._orderPermissionService">
            <summary>Nơi DUY NHẤT giữ luật "ai được sửa đơn này". Đừng kiểm quyền tại chỗ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.Order},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.OrderPackage},Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderTrackService,Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderFinService,Lada.Framework.Infrastructures.Services.IOrderFinCalculationService,Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderPermissionService,Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderGoodsAttributeService)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageService"/>.
            </summary>
            <param name="orderRepository">Đối tượng IRepository của Order.</param>
            <param name="orderPackageRepository">Đối tượng IRepository của OrderPackage.</param>
            <param name="orderTrackService">Đối tượng IOrderTrackService.</param>
            <param name="orderFinService">Đối tượng IOrderFinService.</param>
            <param name="orderFinCalculationService">Lớp quyết định tiền ở Lada.Framework.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageService.GetByOrderId(System.Int32)">
            <summary>
            Lấy thông tin kiện hàng theo ID đơn hàng.
            </summary>
            <param name="orderId">ID của đơn hàng.</param>
            <returns>Thông tin kiện hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageService.ApDungLoaiHangCapDon(System.Int32,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel})">
             <summary>
             Đổ loại hàng + thuộc tính CẤP ĐƠN xuống từng kiện, cho đơn khai theo đường cũ.
             </summary>
             <param name="orderId">Id đơn hàng</param>
             <param name="packages">Kiện của đơn, sẽ được điền tại chỗ</param>
             <remarks>
             Đơn tạo trước khi loại hàng chuyển xuống cấp kiện có snapshot KHÔNG mang <c>OrderPackageId</c>,
             nên tra theo kiện ra rỗng. Không đổ xuống thì màn sửa mở ra trống trơn, và người dùng bấm Lưu là
             XOÁ SẠCH thuộc tính của đơn (đường ghi xoá theo đơn rồi ghi lại theo kiện) — cước tính lại ngay
             sau đó mất phụ phí thuộc tính hoặc tụt khỏi bảng giá riêng.
            
             Điền cho MỌI kiện chứ không riêng kiện đầu: engine gộp các kiện cùng loại + cùng thuộc tính
             (<c>GoodsLineGrouper.Merge</c>) nên chúng lại thành đúng một dòng cước như đường cũ. Điền cho
             một kiện thôi sẽ tách đơn thành hai dòng khác nhau ⇒ ĐỔI TIỀN.
             </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageService.GetByOrderIdWithUnits(System.Int32)">
            <summary>
            Lấy thông tin kiện hàng theo ID đơn hàng với thông tin đơn vị đo.
            </summary>
            <param name="orderId">ID của đơn hàng.</param>
            <returns>Thông tin kiện hàng với đơn vị đo.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPackageService.Update(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Shared.UpdateOrderPackageModel)">
            <summary>
            Cập nhật thông tin kiện hàng.
            </summary>
            <param name="model">Model chứa thông tin kiện hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderPermissionService">
            <summary>
            Nơi DUY NHẤT trả lời câu hỏi "người này có được sửa đơn hàng này không".
            </summary>
            <remarks>
            <para>
            <b>Vì sao tồn tại.</b> Luật này trước đây được dán tay ở <b>6 chỗ</b> —
            <c>OrderFinService.Update</c>, <c>OrderAddressService</c> (2 chỗ), <c>OrderPackageService</c>,
            <c>OrderService.Cancel</c> và <c>OrderService.RemoveCancel</c> — mỗi chỗ một bản
            <c>manager.Id != userId &amp;&amp; order.SaleId != userId</c> giống hệt nhau. Sáu bản sao của một
            luật <b>quyền hạn</b> nghĩa là: đổi luật thì phải nhớ đủ 6 nơi, sót một nơi là lỗ phân quyền hoặc
            chặn oan người có quyền. Đây đúng loại lặp vừa gây ra lệch số ở luật trọng lượng tính cước.
            </para>
            <para>
            🐞 <b>Và việc lặp đã che một bug thật suốt thời gian dài:</b> cả 6 bản sao đều so sai property nên
            điều kiện "là người quản lý khách hàng" <b>chưa từng đúng một lần nào</b> — xem
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPermissionService.CanEditOrderAsync(System.Int32,System.Nullable{System.Int32},System.Int32)"/>. Một chỗ sai thì dễ thấy;
            sáu chỗ sai giống nhau thì trông như đúng.
            </para>
            <para>
            ⚠️ <b>Chưa có test tự động, và đây là lý do — không phải sự bỏ sót.</b> Service này cần
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService"/> + <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserRoleResolver"/>, cả hai đều nằm ở project
            <c>Ladaer.BackEnd</c> mà <c>Ladaer.BackEnd.Tests</c> chỉ tham chiếu <c>Lada.Framework</c>. Phần
            luật ở đây <b>không bóc thuần được</b> như đã làm với <c>OrderFinCalculationService</c>: nó chính là
            việc đi lấy dữ liệu rồi hợp lại, chứ không có phép tính nào để tách. Bóc một phép OR ba biến sang
            Framework chỉ để "có test" là tự lừa mình. ⇒ <b>Sửa luật ở đây thì phải bấm thật để xác minh.</b>
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderPermissionService.CanEditOrderAsync(Lada.Framework.Data.Domains.Orders.Order,System.Int32)">
            <summary>
            Người dùng có quyền sửa đơn hàng này hay không.
            </summary>
            <param name="order">Đơn hàng cần sửa — chỉ đọc <c>CustomerId</c> và <c>SaleId</c>.</param>
            <param name="userId">Id người đang thao tác.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderPermissionService.CanEditOrderAsync(System.Int32,System.Nullable{System.Int32},System.Int32)">
            <summary>
            Người dùng có quyền sửa đơn của khách hàng này hay không — dùng khi trong tay chỉ có
            <c>CustomerId</c> / <c>SaleId</c> chứ không có cả entity <see cref="T:Lada.Framework.Data.Domains.Orders.Order"/>.
            </summary>
            <param name="customerId">Khách hàng của đơn.</param>
            <param name="saleId">Sale phụ trách đơn, <c>null</c> nếu đơn không gán sale.</param>
            <param name="userId">Id người đang thao tác.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPermissionService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderPermissionService"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPermissionService.#ctor(Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService,Ladaer.BackEnd.Infrastructures.Services.Identity.IUserRoleResolver)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPermissionService"/>.
            </summary>
            <param name="customerService">Dùng để tìm người quản lý khách hàng của đơn.</param>
            <param name="userRoleResolver">
            Nguồn duy nhất để biết vai trò người dùng (đọc DB, có cache). Role <b>không</b> nằm trong JWT nên
            <c>User.IsInRole(...)</c> luôn trả <c>false</c> — đừng dùng.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPermissionService.CanEditOrderAsync(Lada.Framework.Data.Domains.Orders.Order,System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderPermissionService.CanEditOrderAsync(System.Int32,System.Nullable{System.Int32},System.Int32)">
            <inheritdoc/>
            <remarks>
            <para>
            Thứ tự kiểm tra là <b>cố ý</b>: hai điều kiện rẻ (so sánh id) chạy trước, chỉ khi cả hai trượt
            mới hỏi vai trò — vì <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Identity.IUserRoleResolver"/> có thể phải đọc database. Đừng đảo lại thành
            hỏi vai trò trước cho "dễ đọc".
            </para>
            <para>
            🐞 <b>Đây là chỗ sửa một BUG PHÂN QUYỀN có thật, phát hiện 2026-08-05.</b> Cả 6 bản sao cũ đều
            so <c>manager.Id != userId</c>, nhưng <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService.GetManagerById(System.Int32)"/>
            <b>chưa bao giờ gán <c>result.Id</c></b> — nó chỉ gán <c>ManagerId</c> /
            <c>ManagerUserName</c> / <c>ManagerFullName</c>. Nên <c>manager.Id</c> <b>luôn bằng 0</b> và điều
            kiện "là người quản lý" <b>chưa từng đúng một lần nào</b>: thực tế chỉ sale phụ trách sửa được
            đơn. Đo trên DB: <b>3.054 / 27.853 đơn</b> có người quản lý khác sale ⇒ đúng số đơn mà người quản
            lý bị <b>chặn oan</b>. Ở đây so <c>manager.ManagerId</c> — đúng ý định mà tên biến và câu thông
            báo lỗi ("không do mình tạo / quản lý") vẫn luôn nói tới.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService">
            <summary>
            Giao diện cho dịch vụ quản lý đơn hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel,System.String)">
            <summary>
            Tạo mới đơn hàng.
            </summary>
            <param name="model">Thông tin đơn hàng.</param>
            <param name="apiKey">API key.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm đơn hàng.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService.SearchByAgency(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm đơn của bưu cục người đang đăng nhập theo nhóm (khoá <c>Scope</c>, xem <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderAgencyScope"/>) —
            màn "Đơn hàng bưu cục". Bưu cục luôn lấy từ tài khoản, không nhận từ tham số.
            </summary>
            <param name="param">Thông số tìm kiếm — cùng bộ lọc với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)"/>, thêm khoá <c>Scope</c>.</param>
            <param name="userId">Người đang đăng nhập.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService.GetAgencyScopeAsync(System.Int32)">
            <summary>
            Cờ hiển thị + bưu cục + option bộ lọc cho màn "Đơn hàng bưu cục".
            </summary>
            <param name="userId">Người đang đăng nhập.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService.OrderDetailByCode(System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy chi tiết đơn hàng theo mã đơn hàng.
            </summary>
            <param name="code">Mã đơn hàng.</param>
            <returns>Thông tin chi tiết đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService.OrderDetailByCodeWithUnits(System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy chi tiết đơn hàng theo mã đơn hàng với thông tin đơn vị đo.
            </summary>
            <param name="code">Mã đơn hàng.</param>
            <returns>Thông tin chi tiết đơn hàng với đơn vị đo.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService.PickupAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Updates.UpdateStatusModel)">
            <summary>
            Cập nhật trạng thái đơn hàng khi lấy hàng.
            </summary>
            <param name="model">Thông tin cập nhật trạng thái.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService.Cancel(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Updates.UpdateStatusModel)">
            <summary>
            Hủy đơn hàng.
            </summary>
            <param name="model">Thông tin cập nhật trạng thái.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService.RemoveCancel(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Updates.UpdateStatusModel)">
            <summary>
            Gỡ bỏ trạng thái hủy của đơn hàng.
            </summary>
            <param name="model">Thông tin cập nhật trạng thái.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService.ExportOrdersAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel)">
            <summary>
            Xuất Excel danh sách đơn hàng.
            </summary>
            <param name="model">Model xuất Excel.</param>
            <returns>Kết quả xuất file.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService.GetByIdAsync(System.Int32)">
            <summary>
            Lấy đơn hàng theo ID.
            </summary>
            <param name="orderId">ID của đơn hàng.</param>
            <returns>Thông tin đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService.GetOrderDetailGeneral(System.Int32)">
            <summary>
            Lấy thông tin chi tiết đơn hàng.
            </summary>
            <param name="orderId">ID của đơn hàng.</param>
            <returns>Thông tin chi tiết đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService.GetOrderDetailGeneralByCode(System.String)">
            <summary>
            Lấy thông tin chi tiết đơn hàng theo mã đơn hàng.
            </summary>
            <param name="code">Mã đơn hàng.</param>
            <returns>Thông tin chi tiết đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderService.PrepareOrderListFilterAsync(Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderListFilter)">
            <summary>
            Chuẩn bị dữ liệu bộ lọc danh sách đơn hàng
            </summary>
            <param name="filter">Filter đầu vào để lấy thêm dữ liệu liên quan</param>
            <returns>Các danh sách option</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService">
            <summary>
            Triển khai dịch vụ quản lý đơn hàng.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService._orderFinCalculationService">
            <summary>
            Lớp quyết định tiền ở <c>Lada.Framework</c> — dùng cho luật trọng lượng tính cước (có test canh,
            đã vá bug tràn số int32). Đừng viết lại công thức trọng lượng tại chỗ.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService._orderPermissionService">
            <summary>Nơi DUY NHẤT giữ luật "ai được sửa đơn này". Đừng kiểm quyền tại chỗ.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService._goodsCategoryPricingService">
            <summary>
            Cấu hình giá loại hàng — ở đây chỉ dùng để lấy trọng lượng quy ước theo lựa chọn thuộc tính.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService._userRepository">
            <summary>Người dùng — để biết ai là nhân sự của một bưu cục (màn "Đơn hàng bưu cục").</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService._agencyRepository">
            <summary>Chi nhánh / bưu cục — lấy tên bưu cục cho màn "Đơn hàng bưu cục".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.#ctor(System.Data.IDbConnection,Lada.Framework.Infrastructures.Services.IFeeService,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.Order},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.OrderTrack},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Medias.Media},Ladaer.BackEnd.Infrastructures.Services.Categories.ILocationService,Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService,Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderTrackService,Lada.Framework.Infrastructures.Services.IUnifiedMediaService,Ladaer.BackEnd.Infrastructures.Services.Crm.IVatInfoService,Lada.Framework.Infrastructures.Services.Fees.IFeeQuoteEngine,Ladaer.BackEnd.Infrastructures.Services.Crm.ICustomerService,Lada.Framework.Infrastructures.Services.IExcelFileService,Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderGoodsAttributeService,Lada.Framework.Infrastructures.Services.IOrderFinCalculationService,Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderPermissionService,Lada.Framework.Infrastructures.Services.IGoodsCategoryPricingService,Ladaer.BackEnd.Infrastructures.Services.Network.IFranchiseLedgerService,Lada.Framework.Data.Repositories.IUserRepository{Lada.Framework.Data.Domains.Identity.User},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Categories.Agency})">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService"/>.
            </summary>
            <param name="dbConnection">Đối tượng IDbConnection.</param>
            <param name="feeService">Đối tượng IFeeService.</param>
            <param name="orderRepository">Đối tượng IRepository của Order.</param>
            <param name="orderTrackRepository">Đối tượng IRepository của OrderTrack.</param>
            <param name="mediaRepository">Đối tượng IRepository của Media.</param>
            <param name="locationService">Đối tượng ILocationService.</param>
            <param name="userService">Đối tượng IUserService.</param>
            <param name="orderTrackService">Đối tượng IOrderTrackService.</param>
            <param name="unifiedMediaService">Đối tượng IUnifiedMediaService.</param>
            <param name="vatInfoService">Đối tượng IVatInfoService.</param>
            <param name="feeQuoteEngine">Engine báo giá theo dòng phí — thay thế <c>OrderFeeCalculationHelper</c> cũ (Việc 3).</param>
            <param name="orderGoodsAttributeService">Dịch vụ ghi snapshot thuộc tính loại hàng của đơn.</param>
            <param name="goodsCategoryPricingService">Cấu hình giá loại hàng — nguồn trọng lượng quy ước.</param>
            <param name="userRepository">Người dùng — nhân sự của bưu cục.</param>
            <param name="agencyRepository">Chi nhánh / bưu cục.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.GetByIdAsync(System.Int32)">
            <summary>
            Lấy đơn hàng theo ID.
            </summary>
            <param name="orderId">ID của đơn hàng.</param>
            <returns>Thông tin đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel,System.String)">
            <summary>
            Tạo mới đơn hàng.
            </summary>
            <param name="model">Thông tin đơn hàng.</param>
            <param name="apiKey">API key.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.Create(Lada.Framework.Data.Domains.Orders.Order,System.Int32)">
            <summary>
            Tạo mới đơn hàng.
            </summary>
            <param name="order">Thông tin đơn hàng.</param>
            <param name="retry">Số lần thử lại.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Tìm kiếm đơn hàng.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.SearchByAgency(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.GetAgencyScopeAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.SearchFilteredAsync(System.Linq.IQueryable{Lada.Framework.Data.Domains.Orders.Order},Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Phần chung của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)"/> và <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.SearchByAgency(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)"/>: áp bộ lọc của <c>PredicateObject</c> lên tập
            đơn đã giới hạn phạm vi, rồi phân trang. Phạm vi (ai được thấy đơn nào) là việc của nơi gọi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.OrderDetailByCode(System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy chi tiết đơn hàng theo mã đơn hàng.
            </summary>
            <param name="code">Mã đơn hàng.</param>
            <returns>Thông tin chi tiết đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.OrderDetailByCodeWithUnits(System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Lấy chi tiết đơn hàng theo mã đơn hàng với thông tin đơn vị đo.
            </summary>
            <param name="code">Mã đơn hàng.</param>
            <returns>Thông tin chi tiết đơn hàng với đơn vị đo.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.PickupAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Updates.UpdateStatusModel)">
            <summary>
            Cập nhật trạng thái đơn hàng khi lấy hàng.
            </summary>
            <param name="model">Thông tin cập nhật trạng thái.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.Cancel(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Updates.UpdateStatusModel)">
            <summary>
            Hủy đơn hàng.
            </summary>
            <param name="model">Thông tin cập nhật trạng thái.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.RemoveCancel(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Updates.UpdateStatusModel)">
            <summary>
            Gỡ bỏ trạng thái hủy của đơn hàng.
            </summary>
            <param name="model">Thông tin cập nhật trạng thái.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.UpdateStatus(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.Updates.UpdateStatusModel)">
            <summary>
            Cập nhật trạng thái đơn hàng.
            </summary>
            <param name="model">Thông tin cập nhật trạng thái.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.ValidateUpdateStatus(Lada.Framework.Data.Enums.OrderStatus,Lada.Framework.Data.Enums.OrderPhysicalStatus,Lada.Framework.Data.Enums.OrderStatus,Lada.Framework.Data.Enums.OrderPhysicalStatus)">
            <summary>
            Kiểm tra tính hợp lệ của việc cập nhật trạng thái đơn hàng.
            </summary>
            <param name="currentStatus">Trạng thái hiện tại của đơn hàng.</param>
            <param name="currentPhysicalStatus">Trạng thái vật lý hiện tại của đơn hàng.</param>
            <param name="newStatus">Trạng thái mới của đơn hàng.</param>
            <param name="newPhysicalStatus">Trạng thái vật lý mới của đơn hàng.</param>
            <returns>True nếu việc cập nhật trạng thái hợp lệ, ngược lại false.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.GenerateCodeAsync(System.Int32)">
            <summary>
            Tạo mã đơn hàng ngẫu nhiên.
            </summary>
            <param name="radVal">Giá trị ngẫu nhiên.</param>
            <returns>Mã đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.LayTrongLuongQuyUoc(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderPackageModel)">
             <summary>
             Trọng lượng quy ước (kg) của một kiện, lấy từ lựa chọn thuộc tính đã khai.
             </summary>
             <param name="package">Kiện hàng client gửi — nguồn loại hàng và lựa chọn thuộc tính.</param>
             <returns>Cân quy ước, hoặc <c>0</c> khi không được phép can thiệp / lựa chọn chưa khai cân.</returns>
             <remarks>
             Cân nằm ở <c>GoodsAttributeOption.Weight</c> vì mỗi lựa chọn một số riêng (xe số ≠ xe phân khối
             lớn), không phải một số chung cho cả danh mục.
            
             Ranh giới an toàn, đừng nới: CHỈ áp cho danh mục áp giá cố định hoặc bảng giá riêng theo tuyến.
             Hai mode còn lại (<c>Surcharge</c>, <c>None</c>) VẪN tra bảng giá theo bậc trọng lượng, ghi đè
             cân khách khai ở đó là ĐỔI TIỀN của đơn.
             </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.BuildPackageGoods(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel,Lada.Framework.Data.Domains.Orders.Order)">
            <summary>
            Ghép kiện hàng đã lưu với loại hàng / thuộc tính client gửi, để ghi snapshot theo kiện.
            </summary>
            <param name="model">Đơn client gửi lên — nguồn của loại hàng và lựa chọn thuộc tính.</param>
            <param name="order">Đơn đã lưu — nguồn của <c>OrderPackage.Id</c>.</param>
            <returns>Danh sách kiện kèm loại hàng, hoặc <c>null</c> khi không ghép được.</returns>
            <remarks>
            Ghép theo <b>thứ tự</b>: <c>order.Packages</c> dựng từ <c>model.Packages</c> qua <c>ToEntity()</c>
            nên hai danh sách cùng số lượng và cùng thứ tự. Trả <c>null</c> khi số lượng lệch thay vì ghép
            bừa — ghép lệch một nhịp là gán thuộc tính xe máy cho kiện quần áo, sai âm thầm và chỉ lộ ra khi
            khách nhìn hoá đơn.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.GetOrderFin(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderModel,System.Decimal,System.String,System.Collections.Generic.List{Lada.Framework.DTO.GoodsLineModel})">
            <summary>
            Tính toán thông tin tài chính của đơn hàng.
            </summary>
            <param name="orderModel">Thông tin đơn hàng.</param>
            <param name="totalWeight">Tổng trọng lượng.</param>
            <param name="apiKey">API key.</param>
            <param name="goodsLines">
            Dòng hàng theo loại (đã gộp) khi đơn khai loại hàng theo kiện. <c>null</c> = đơn một loại hàng,
            engine dùng <paramref name="totalWeight"/> + loại hàng cấp đơn đúng như trước.
            </param>
            <returns>Thông tin tài chính của đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.GetOrderDetailGeneral(System.Int32)">
            <summary>
            Lấy thông tin chi tiết đơn hàng.
            </summary>
            <param name="orderId">ID của đơn hàng.</param>
            <returns>Thông tin chi tiết đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.GetOrderDetailGeneralByCode(System.String)">
            <summary>
            Lấy thông tin chi tiết đơn hàng theo mã đơn hàng.
            </summary>
            <param name="code">Mã đơn hàng.</param>
            <returns>Thông tin chi tiết đơn hàng.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.GetMediaByOrderIdAsync(System.Int32)">
            <summary>
            Lấy danh sách media theo Order ID
            </summary>
            <param name="orderId">ID của đơn hàng</param>
            <returns>Danh sách media items</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.GetMediaByOrderIdOptimizedAsync(System.Int32)">
            <summary>
            Lấy danh sách media theo Order ID - tối ưu hóa để tránh timeout
            </summary>
            <param name="orderId">ID của đơn hàng</param>
            <returns>Danh sách media items</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.BuildAddressCoordLookupAsync(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Helpers.IAddressCoord})">
             <summary>
             Nạp toạ độ tâm đơn vị hành chính cho một loạt địa chỉ đơn hàng.
            
             Dùng chung cho trang tra cứu (OrderDetailByCode / ...WithUnits) để hai hàm
             đó không lệch nhau về cách xác định "đã định vị hay chưa".
             </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.MediaComparer">
            <summary>
            Comparer để so sánh Media entities
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.EnrichOrderItemsAsync(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderItem})">
            <summary>
            Phục vụ cho cả 2 method Search để thêm thông tin địa chỉ và tên người bán
            </summary>
            <param name="orderItems">Danh sách OrderItem cần thêm thông tin.</param>
            <returns>Task.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.PrepareOrderListFilterAsync(Ladaer.BackEnd.Infrastructures.DTO.Filters.Orders.OrderListFilter)">
            <summary>
            Chuẩn bị dữ liệu bộ lọc danh sách đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.ExportOrdersAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel)">
            <summary>
            Xuất Excel danh sách đơn hàng.
            </summary>
            <param name="model">Model xuất Excel.</param>
            <returns>Kết quả xuất file.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.CreateOrderExcelPackageAsync(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderItem},Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel)">
            <summary>
            Tạo ExcelPackage danh sách đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.SetupOrderHeaders(OfficeOpenXml.ExcelWorksheet,Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel)">
            <summary>
            Thiết lập header cho danh sách đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.FillOrderData(OfficeOpenXml.ExcelWorksheet,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Orders.OrderItem},Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderExcelExportModel)">
            <summary>
            Điền dữ liệu danh sách đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderService.FormatOrderWorksheet(OfficeOpenXml.ExcelWorksheet,System.Int32)">
            <summary>
            Định dạng worksheet danh sách đơn hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderTrackService">
            <summary>
            Giao diện cho dịch vụ quản lý hành trình đơn hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderTrackService.CreateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderTrackModel)">
            <summary>
            Tạo mới hành trình đơn hàng.
            </summary>
            <param name="model">Thông tin hành trình đơn hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.IOrderTrackService.CreateAsync(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderTrackModel})">
            <summary>
            Tạo mới danh sách hành trình đơn hàng.
            </summary>
            <param name="models">Danh sách thông tin hành trình đơn hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderTrackService">
            <summary>
            Triển khai dịch vụ quản lý hành trình đơn hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderTrackService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Orders.OrderTrack})">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderTrackService"/>.
            </summary>
            <param name="orderTrackRepository">Đối tượng IRepository của OrderTrack.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderTrackService.CreateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderTrackModel)">
            <summary>
            Tạo mới hành trình đơn hàng.
            </summary>
            <param name="model">Thông tin hành trình đơn hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Orders.OrderTrackService.CreateAsync(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.Orders.OrderTrackModel})">
            <summary>
            Tạo mới danh sách hành trình đơn hàng.
            </summary>
            <param name="models">Danh sách thông tin hành trình đơn hàng.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Promotions.AutoApplyResult">
            <summary>
            Kết quả auto-apply
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Promotions.IPromotionAutoApplyService.FindBestPromotion(System.Int32,System.Decimal)">
            <summary>
            Tìm chương trình auto-apply tốt nhất cho đơn hàng
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Promotions.PromotionBackgroundService">
            <summary>
            Background service chạy các job định kỳ cho module khuyến mãi:
            - Kiểm tra hết hạn chương trình (mỗi ngày)
            - Cảnh báo ngân sách (mỗi ngày)
            - Tính hoàn thưởng cuối kỳ (ngày 1 hàng tháng)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Promotions.PromotionValidationResult">
            <summary>
            Kết quả validate mã khuyến mãi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Promotions.IPromotionValidationService.ValidateAndCalculate(System.String,System.Int32,System.Decimal)">
            <summary>
            Kiểm tra và tính toán giảm giá cho mã khuyến mãi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Promotions.IPromotionValidationService.RecordUsage(System.Int32,System.Nullable{System.Int32},System.Int32,System.Int32,System.Decimal,System.Decimal,System.Decimal,System.String)">
            <summary>
            Ghi nhận sử dụng khuyến mãi khi đơn được tạo thành công
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Promotions.IPromotionValidationService.ReverseUsage(System.Int32)">
            <summary>
            Hoàn lại lượt sử dụng khi đơn bị hủy
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Promotions.IPromotionValidationService.GetUsageLogs(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Nullable{System.Int32})">
            <summary>
            Lấy log sử dụng theo chương trình
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.CostControlExcelService.AddCompanyHeader(OfficeOpenXml.ExcelWorksheet,System.Int32,System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Company header with logo + title (rows 1-3)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.CostControlExcelService.WriteRow(OfficeOpenXml.ExcelWorksheet,Ladaer.BackEnd.Infrastructures.DTO.Items.Finances.CostControlRowItem,System.Collections.Generic.List{System.String},System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Int32)">
            <summary>
            Recursively write a row and its children
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.IFinanceReportService">
            <summary>
            Interface cho service báo cáo tài chính
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.IFinanceReportService.GetCostControlReportAsync(System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Lấy báo cáo kiểm soát chi phí theo khoảng thời gian
            </summary>
            <param name="startDate">Ngày bắt đầu</param>
            <param name="endDate">Ngày kết thúc</param>
            <returns>Kết quả báo cáo dạng cây</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.IFinanceReportService.BackfillPaymentsDateAsync">
            <summary>
            Backfill PaymentsDate từ ExpenseHistory cho các expense đã Paid nhưng chưa có PaymentsDate
            </summary>
            <returns>Số lượng bản ghi đã cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.IFinanceReportService.GetCashFlowReportAsync(System.DateTimeOffset,System.DateTimeOffset,System.String)">
            <summary>
            Lấy báo cáo dòng tiền tổng hợp (Cash Flow Dashboard)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.IFinanceReportService.GetShortTermLiabilityReportAsync(System.Int32,System.Int32)">
            <summary>
            Lấy báo cáo nợ ngắn hạn (thẻ dầu + vay xe)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.IFinanceReportService.GetCustomerArReportAsync(System.Int32,System.Int32,System.Nullable{System.Int32},System.Nullable{System.Int32})">
            <summary>
            Lấy báo cáo công nợ phải thu khách hàng (cước CK kế toán chưa thanh toán)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.IFinanceReportService.GetFeeInflowDetailAsync(System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Drill-down: danh sách đơn hàng thu cước (theo HeadTime) trong khoảng thời gian
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.IFinanceReportService.GetCodInflowDetailAsync(System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Drill-down: danh sách đơn hàng thu COD từ shipper trong khoảng thời gian
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.FinanceReportService">
            <summary>
            Service báo cáo tài chính
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.FinanceReportService.GetCostControlReportAsync(System.DateTimeOffset,System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.FinanceReportService.BackfillPaymentsDateAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.FinanceReportService.GetCashFlowReportAsync(System.DateTimeOffset,System.DateTimeOffset,System.String)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.FinanceReportService.GetShortTermLiabilityReportAsync(System.Int32,System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.FinanceReportService.GetCustomerArReportAsync(System.Int32,System.Int32,System.Nullable{System.Int32},System.Nullable{System.Int32})">
            <summary>
            Báo cáo Công nợ phải thu khách hàng
            Lấy các đơn hàng có PayFeeType = BankTransfer(3) mà TransferFeeStage chưa thanh toán
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.FinanceReportService.GetFeeInflowDetailAsync(System.DateTimeOffset,System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.FinanceReportService.GetCodInflowDetailAsync(System.DateTimeOffset,System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.FinanceReportService.FeeInflowSpRow">
            <summary>Row trả về từ sp_GetCashFlowFeeInflow</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.Finances.FinanceReportService.CodInflowSpRow">
            <summary>Row trả về từ sp_GetCashFlowCodInflow</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IIncomeExpenseReportService">
            <summary>
            Interface cho service báo cáo thu chi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IIncomeExpenseReportService.GetIncomeExpenseReportAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeExpenseReportRequest,System.Int32)">
            <summary>
            Lấy báo cáo thu chi theo khoảng thời gian
            </summary>
            <param name="request">Thông tin khoảng thời gian</param>
            <param name="userId">ID người dùng</param>
            <returns>Báo cáo thu chi</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IncomeExpenseReportService">
            <summary>
            Service báo cáo thu chi
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IncomeExpenseReportService.#ctor(System.Data.IDbConnection)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IncomeExpenseReportService"/>.
            </summary>
            <param name="dbConnection">Kết nối cơ sở dữ liệu.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IncomeExpenseReportService.GetIncomeExpenseReportAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Finance.IncomeExpenseReportRequest,System.Int32)">
            <summary>
            Lấy báo cáo thu chi theo khoảng thời gian
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IncomeExpenseReportService.GenerateDateColumns(System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Tạo danh sách các cột ngày
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IncomeExpenseReportService.BuildReportMatrix(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow},System.Collections.Generic.List{System.String})">
            <summary>
            Xây dựng ma trận dữ liệu báo cáo
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IncomeExpenseReportService.BuildIncomeRows(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow},System.Collections.Generic.List{System.String})">
            <summary>
            Xây dựng các dòng THU
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IncomeExpenseReportService.BuildExpenseRows(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow},System.Collections.Generic.List{System.String})">
            <summary>
            Xây dựng các dòng CHI
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IncomeExpenseReportService.BuildSingleCategoryRow(System.String,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow},System.Collections.Generic.List{System.String},System.Int32)">
            <summary>
            Xây dựng dòng cho một danh mục đơn
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IncomeExpenseReportService.BuildExpenseTreeRows(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.TransactionReportRow},System.Collections.Generic.List{System.String})">
            <summary>
            Xây dựng cây chi phí vận hành
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IncomeExpenseReportService.CreateTotalRow(System.String,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportRowItem},System.Collections.Generic.List{System.String},System.String)">
            <summary>
            Tạo dòng tổng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IncomeExpenseReportService.CreateEmptyTotalRow(System.String,System.Collections.Generic.List{System.String},System.String)">
            <summary>
            Tạo dòng tổng rỗng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IncomeExpenseReportService.CreateNetAmountRow(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportRowItem},System.Collections.Generic.List{System.String})">
            <summary>
            Tạo dòng chênh lệch (Thu - Chi)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Finance.IncomeExpenseReportService.CalculateTotals(Ladaer.BackEnd.Infrastructures.DTO.Results.Finance.IncomeExpenseReportResult)">
            <summary>
            Tính tổng thu, tổng chi, chênh lệch
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.IFuelRefillReportExcelService">
            <summary>
            Interface cho dịch vụ xuất Excel báo cáo đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.IFuelRefillReportExcelService.ExportByDriverAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Xuất Excel báo cáo đổ dầu theo lái xe (nhóm theo ngày)
            </summary>
            <param name="param">Tham số tìm kiếm và sắp xếp</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.IFuelRefillReportExcelService.ExportByDateAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Xuất Excel báo cáo đổ dầu theo ngày
            </summary>
            <param name="param">Tham số tìm kiếm và sắp xếp</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.IFuelRefillReportExcelService.ExportByTruckAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Xuất Excel báo cáo đổ dầu theo xe (nhóm theo xe, chi tiết lái xe bên trong)
            </summary>
            <param name="param">Tham số tìm kiếm và sắp xếp</param>
            <returns>Kết quả xuất file</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService">
            <summary>
            Dịch vụ xuất Excel báo cáo đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.ExportByDriverAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Xuất Excel báo cáo đổ dầu theo lái xe (nhóm theo ngày)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.ExportByDateAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Xuất Excel báo cáo đổ dầu theo ngày
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.ExportByTruckAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Xuất Excel báo cáo đổ dầu theo xe (nhóm theo xe, chi tiết lái xe bên trong)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.GetReportDataAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy dữ liệu chi tiết báo cáo đổ dầu theo ngày, lái xe và xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.GetTruckReportDataAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy dữ liệu chi tiết báo cáo đổ dầu theo xe và lái xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.CreateExcelPackageByTruck(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.TruckDriverExportRow})">
            <summary>
            Tạo ExcelPackage báo cáo theo xe (nhóm theo xe, chi tiết lái xe bên trong)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.SetupHeadersByTruck(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Thiết lập header cho báo cáo theo xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.FillDataGroupedByTruck(OfficeOpenXml.ExcelWorksheet,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.TruckDriverExportRow})">
            <summary>
            Điền dữ liệu nhóm theo xe (chi tiết lái xe bên trong)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.WriteTruckSubtotalRow(OfficeOpenXml.ExcelWorksheet,System.Int32,System.Int32,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.TruckDriverExportRow})">
            <summary>
            Ghi dòng subtotal/tổng cho báo cáo theo xe.
            Bố cục cột từ startCol: Số lần đổ | Km | Lít thực tế | Tiền thực tế | Đơn giá BQ | Tiền thẻ | Tiền mặt
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.ParseIdList(System.Object)">
            <summary>
            Parse mảng ID từ dynamic object
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.GetStatusName(System.Int32)">
            <summary>
            Tên trạng thái phiếu đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.CreateExcelPackageByDriver(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.DateDriverTruckReportRow})">
            <summary>
            Tạo ExcelPackage báo cáo theo lái xe (nhóm theo ngày)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.CreateExcelPackageByDate(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.DateDriverTruckReportRow})">
            <summary>
            Tạo ExcelPackage báo cáo theo ngày
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.SetupHeadersByDriver(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Thiết lập header cho báo cáo theo lái xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.SetupHeadersByDate(OfficeOpenXml.ExcelWorksheet)">
            <summary>
            Thiết lập header cho báo cáo theo ngày
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.FillDataGroupedByDate(OfficeOpenXml.ExcelWorksheet,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.DateDriverTruckReportRow})">
            <summary>
            Điền dữ liệu nhóm theo ngày (cho báo cáo theo lái xe)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.FillDataByDate(OfficeOpenXml.ExcelWorksheet,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.DateDriverTruckReportRow})">
            <summary>
            Điền dữ liệu theo ngày (cho báo cáo theo ngày - có cột Status)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.WriteSubtotalRow(OfficeOpenXml.ExcelWorksheet,System.Int32,System.Int32,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.DateDriverTruckReportRow})">
            <summary>
            Ghi dòng subtotal/tổng cho cả 2 kiểu báo cáo.
            Bố cục cột từ startCol: Số lần đổ | Km | Lít thực tế | Tiền thực tế | Tiền thẻ | Tiền mặt
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.FormatWorksheet(OfficeOpenXml.ExcelWorksheet,System.Int32,System.Int32)">
            <summary>
            Định dạng worksheet
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.DateDriverTruckReportRow">
            <summary>
            DTO để map kết quả từ stored procedure theo ngày
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportExcelService.TruckDriverExportRow">
            <summary>
            DTO để map kết quả từ stored procedure chi tiết theo xe và lái xe
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.IFuelRefillReportService">
            <summary>
            Interface cho dịch vụ báo cáo đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.IFuelRefillReportService.GetFuelRefillReportByDriverAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy báo cáo đổ dầu theo lái xe từ stored procedure
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Danh sách báo cáo đổ dầu theo lái xe</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.IFuelRefillReportService.GetFuelRefillReportByDateAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy báo cáo đổ dầu theo ngày từ stored procedure
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Danh sách báo cáo đổ dầu theo ngày</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.IFuelRefillReportService.GetFuelRefillReportByTruckAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy báo cáo đổ dầu theo xe từ stored procedure
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Danh sách báo cáo đổ dầu theo xe</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportService">
            <summary>
            Dịch vụ báo cáo đổ dầu
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportService.GetFuelRefillReportByDriverAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy báo cáo đổ dầu theo lái xe từ stored procedure
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Danh sách báo cáo đổ dầu theo lái xe</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportService.GetFuelRefillReportByDateAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy báo cáo đổ dầu theo ngày từ stored procedure
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Danh sách báo cáo đổ dầu theo ngày (nhóm theo ngày, chi tiết bên trong)</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportService.GetFuelRefillReportByTruckAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy báo cáo đổ dầu thực tế theo xe từ stored procedure
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <returns>Danh sách báo cáo đổ dầu theo xe (nhóm theo xe, chi tiết lái xe bên trong)</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportService.ParseSearchParams(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Parse tham số tìm kiếm từ SmartTableParam
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportService.ParseIdList(System.Object)">
            <summary>
            Parse mảng ID từ dynamic object (hỗ trợ cả JArray và IEnumerable)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportService.DriverTruckDetailRow">
            <summary>
            DTO tạm để map kết quả từ stored procedure chi tiết lái xe + xe
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportService.DateDriverTruckReportRow">
            <summary>
            DTO tạm để map kết quả từ stored procedure theo ngày
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.FuelCards.FuelRefillReportService.TruckDriverDetailRow">
            <summary>
            DTO tạm để map kết quả từ stored procedure chi tiết xe + lái xe
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.OperationReports.IBranchReportService">
             <summary>
             Báo cáo cấp bưu cục / chi nhánh.
             </summary>
             <remarks>
             File này từng rỗng 0 byte; hồi sinh ở GĐ C của đợt KPI để phục vụ chỉ số
             <c>agency.revenue</c> (plan §7.7).
            
             Service **không tự lọc theo quyền của người đang đăng nhập** — khác các service báo cáo có
             màn hình đi kèm. Lý do: người gọi đầu tiên là provider KPI, nơi chủ thể là bưu cục **được
             chấm điểm** chứ không phải người đang xem. Bên nào gắn màn hình vào đây sau này phải tự ép
             phạm vi trước khi truyền <c>agencyIds</c>.
             </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.OperationReports.IBranchReportService.GetAgencyRevenueStatisticsAsync(System.DateTimeOffset,System.DateTimeOffset,System.Collections.Generic.IReadOnlyList{System.Int32})">
            <summary>
            Doanh số theo bưu cục bán hàng trong một khoảng ngày.
            </summary>
            <param name="fromDate">Đầu khoảng, tính cả mốc này</param>
            <param name="toDate">Cuối khoảng, tính cả mốc này</param>
            <param name="agencyIds">Giới hạn ở các bưu cục này; rỗng/null = mọi bưu cục</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.OperationReports.BranchReportService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Report.OperationReports.IBranchReportService" />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.OperationReports.IDriverReportService">
            <summary>
            Interface cho dịch vụ báo cáo lái xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.OperationReports.IDriverReportService.GetDriverProductivityReportByDateAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy báo cáo năng suất lái xe theo từng ngày
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng</param>
            <returns>Kết quả báo cáo năng suất lái xe theo ngày</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.OperationReports.DriverReportService">
            <summary>
            Dịch vụ báo cáo lái xe
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.OperationReports.DriverReportService.#ctor(System.Data.IDbConnection,Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Report.OperationReports.DriverReportService"/>.
            </summary>
            <param name="dbConnection">Kết nối cơ sở dữ liệu.</param>
            <param name="userService">Service quản lý người dùng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.OperationReports.DriverReportService.GetDriverProductivityReportByDateAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.IOrderBacklogService">
            <summary>
            Interface service thống kê tồn đọng đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.IOrderBacklogService.GetBacklogSummaryAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy thống kê tồn đọng đơn hàng theo trạng thái và thời gian
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.IOrderBacklogService.GetBacklogSummaryByAgencyAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy thống kê tồn đọng đơn hàng phân nhóm theo Agency
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.IOrderBacklogService.GetBacklogDetailAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Lấy danh sách chi tiết đơn hàng drill-down theo trạng thái + số ngày
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderBacklogService">
            <summary>
            Service thống kê tồn đọng đơn hàng sử dụng Stored Procedure và Dapper
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderBacklogService.GetBacklogSummaryAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderBacklogService.GetBacklogSummaryByAgencyAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderBacklogService.GetBacklogDetailAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderBacklogService.ParseAgencyIds(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Parse danh sách AgencyIds từ SmartTableParam.Search.PredicateObject
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderBacklogService.ParseCityFilters(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Parse SourceCityId và DestCityId từ SmartTableParam.Search.PredicateObject
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.IOrderFinReportService">
            <summary>
            Giao diện cho dịch vụ báo cáo tài chính đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.IOrderFinReportService.GetBankTransferSummaryBySaleAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy thống kê chuyển khoản ngân hàng theo sale
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng hiện tại</param>
            <returns>Trang dữ liệu thống kê chuyển khoản theo sale</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.IOrderFinReportService.GetBankTransferSummaryBySaleTotalsAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy dòng Tổng toàn cục (summary cards) cho báo cáo CK theo sale — tính trên
            toàn bộ sale khớp bộ lọc, không phụ thuộc trang đang xem.
            </summary>
            <param name="param">Tham số bảng thông minh (dùng cùng bộ lọc với search)</param>
            <param name="userId">ID người dùng hiện tại</param>
            <returns>Dòng tổng toàn cục</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.IOrderFinReportService.GetBankTransferSummaryByCustomerAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy thống kê chuyển khoản ngân hàng theo khách hàng (phân trang server-side)
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng hiện tại</param>
            <returns>Trang dữ liệu thống kê chuyển khoản theo khách hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.IOrderFinReportService.GetBankTransferSummaryByCustomerTotalsAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy dòng Tổng toàn cục (summary cards) cho báo cáo CK theo khách hàng — tính trên
            toàn bộ khách hàng khớp bộ lọc, không phụ thuộc trang đang xem.
            </summary>
            <param name="param">Tham số bảng thông minh (dùng cùng bộ lọc với search)</param>
            <param name="userId">ID người dùng hiện tại</param>
            <returns>Dòng tổng toàn cục</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.IOrderFinReportService.GetBankTransferOrdersDetailAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy danh sách đơn CK kế toán chi tiết theo ô số liệu (metric), phân trang server-side.
            Dùng cho dialog danh sách chi tiết khi click vào từng ô số liệu trên báo cáo tổng hợp.
            </summary>
            <param name="param">Tham số lọc + phân trang + sắp xếp, bổ sung SaleId/CustomerId và Metric</param>
            <param name="userId">ID người dùng hiện tại</param>
            <returns>Trang dữ liệu đơn chi tiết</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService">
            <summary>
            Dịch vụ báo cáo tài chính đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService.#ctor(System.Data.IDbConnection,Ladaer.BackEnd.Infrastructures.Services.Identity.IUserService)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService"/>.
            </summary>
            <param name="dbConnection">Kết nối cơ sở dữ liệu.</param>
            <param name="userService">Dịch vụ quản lý người dùng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService.GetBankTransferSummaryBySaleAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy thống kê chuyển khoản ngân hàng theo sale
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng hiện tại</param>
            <returns>Danh sách thống kê chuyển khoản theo sale</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService.GetBankTransferSummaryBySale(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy thống kê chuyển khoản ngân hàng theo sale (phân trang server-side, synchronous)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService.GetBankTransferSummaryBySaleTotals(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy dòng Tổng toàn cục cho báo cáo CK theo sale (synchronous).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService.GetBankTransferSummaryByCustomerAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy thống kê chuyển khoản ngân hàng theo khách hàng
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng hiện tại</param>
            <returns>Danh sách thống kê chuyển khoản theo khách hàng</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService.BankTransferByCustomerFilter">
            <summary>
            Bộ lọc đã chuẩn hóa cho báo cáo CK theo khách hàng (dùng chung search + totals).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService.ParseBankTransferByCustomerFilter(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Đọc &amp; chuẩn hóa bộ lọc từ SmartTableParam + áp dụng scope phân quyền
            (không phải Founder/Accountant chỉ được xem dữ liệu của chính mình).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService.AddBankTransferByCustomerFilterParams(Microsoft.Data.SqlClient.SqlCommand,Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService.BankTransferByCustomerFilter)">
            <summary>
            Thêm 6 tham số lọc chung vào command (dùng cho cả SP search &amp; SP totals).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService.GetBankTransferSummaryByCustomer(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy thống kê chuyển khoản ngân hàng theo khách hàng (phân trang server-side, synchronous)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService.GetBankTransferSummaryByCustomerTotals(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy dòng Tổng toàn cục cho báo cáo CK theo khách hàng (synchronous).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService.MapMetricToStageCsv(System.String)">
            <summary>
            Map metric (ô số liệu) -> danh sách stage tương ứng (CSV).
            Tổng đơn / Phí CK => tất cả stage hợp lệ (null => SP tự dùng 1,4,9).
            </summary>
        </member>
        <!-- Badly formed XML comment ignored for member "M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService.MapMetricToLabel(System.String)" -->
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderFinReportService.GetBankTransferOrdersDetailAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Xuất Excel danh sách đơn CK kế toán chi tiết theo sale + theo ô số liệu (metric)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.IOrderReportService.GetOrderProductionAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy thống kê đơn hàng theo ngày từ stored procedure
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng</param>
            <returns>Danh sách thống kê đơn hàng theo ngày</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.IOrderReportService.GetSaleDebtReportAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy báo cáo công nợ theo sale từ stored procedure
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng</param>
            <returns>Danh sách báo cáo công nợ theo sale</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.IOrderReportService.GetOrderReportByRouteAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy báo cáo số lượng đơn và doanh số theo tuyến
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng</param>
            <returns>Danh sách báo cáo theo tuyến và trạng thái</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderReportService">
            <summary>
            Dịch vụ báo cáo đơn hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderReportService.GetOrderProductionAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy thống kê đơn hàng theo ngày từ stored procedure
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng</param>
            <returns>Danh sách thống kê đơn hàng theo ngày</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderReportService.GetSaleDebtReportAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy báo cáo công nợ theo sale từ stored procedure
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng</param>
            <returns>Danh sách báo cáo công nợ theo sale</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.Orders.OrderReportService.GetOrderReportByRouteAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy báo cáo số lượng đơn và doanh số theo tuyến
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng</param>
            <returns>Danh sách báo cáo theo tuyến và trạng thái</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.IOrderRevenueDimensionExcelService">
            <summary>
            Xuất Excel ba báo cáo doanh số theo chiều (plan §3.3).
            </summary>
            <remarks>
            Dữ liệu lấy qua CHÍNH <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.IOrderRevenueDimensionReportService"/> — đã ép phạm vi người xem — không gọi SP
            riêng, để đường Excel và đường màn hình không bao giờ lệch hàng rào. Tên trong dòng "Bộ lọc" cũng lấy từ ô lọc đã
            ép phạm vi của service đó, nên id ngoài phạm vi không có tên nào để lộ.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionExcelService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.IOrderRevenueDimensionExcelService" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionExcelService.NgoaiPhamVi">
            <summary>Bộ lọc trỏ tới một bưu cục / nhóm không nằm trong ô lọc của người xuất — file khi đó không có dòng nào.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionExcelService.ExportByAgencyAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionExcelService.ExportByTeamAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionExcelService.ExportByWardAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionExcelService.AppliedFilters">
            <summary>Bộ lọc của MỘT chiều (chỉ những khoá chiều đó thật sự dùng) để ghi lên file.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionExcelService.AppliedFilters.#ctor(System.String,System.Nullable{System.Int32},System.Nullable{System.Int32},System.Nullable{System.Int32},System.String)">
            <summary>Bộ lọc của MỘT chiều (chỉ những khoá chiều đó thật sự dùng) để ghi lên file.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionExcelService.Parse(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Cùng bộ đọc tham số với service đọc — chỉ để ghi loại địa chỉ và bộ lọc lên file. Tham số sai thì service đọc
            đã từ chối trước khi file được dựng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionExcelService.FilterLineAsync(Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionExcelService.AppliedFilters,System.Int32)">
            <summary>Dòng "Bộ lọc" của file — xem <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueExcelBuilder.FilterLine(System.Collections.Generic.IReadOnlyCollection{System.ValueTuple{System.String,System.String}})"/>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter">
            <summary>
            Bộ lọc của ba báo cáo doanh số theo chiều + drill-down, đọc từ <c>SmartTableParam.Search.PredicateObject</c>
            và đã kiểm miền giá trị — giá trị sai bị chặn ở đây với một câu tiếng Việt, không để SQL <c>THROW</c> thành HTTP 500.
            </summary>
            <remarks>
            <para>
            <b>Kỳ</b> tính theo NGÀY giờ Việt Nam: <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.FromDate"/> = 00:00 +07:00 ngày đầu, <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.ToDate"/> =
            23:59:59 +07:00 ngày cuối, luôn mang offset — SP quy về +07:00 rồi lấy ngày, nên mốc UTC kiểu axios
            <c>toISOString</c> cũng đúng ngày. Không bao giờ chuyển sang <c>DateTime</c>: SqlClient coi <c>DateTime</c> không
            offset là UTC và mốc 23:59:59 sang ngày hôm sau. Thiếu mốc nào thì lấy theo tháng hiện tại (Q8); khoảng dài hơn
            12 tháng bị từ chối.
            </para>
            <para>Khoá đọc không phân biệt hoa thường; giá trị không đọc được coi như không gửi.</para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.VietNam">
            <summary>Giờ Việt Nam — múi duy nhất của kỳ báo cáo.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.MaxPageSize">
            <summary>Trần số đơn một trang drill-down — bằng trần của SP.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.FromDate">
            <summary>00:00 giờ Việt Nam của ngày đầu kỳ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.ToDate">
            <summary>23:59:59 giờ Việt Nam của ngày cuối kỳ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.AgencyId">
            <summary>Bưu cục client chọn (báo cáo bưu cục, phường/xã, drill-down chiều 3) — chỉ thu hẹp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.ManagerId">
            <summary>
            Nhóm client chọn (báo cáo nhóm); <c>0</c> = "Chưa có quản lý trực tiếp", <c>-1</c> = "Đơn không có sale" — chỉ
            thu hẹp. Nhỏ hơn -1 hoặc không gửi = không lọc.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.AddressType">
            <summary>1 điểm lấy (mặc định), 2 điểm giao.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.CityId">
            <summary>Tỉnh 2 cấp; <c>null</c> = mọi tỉnh.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.Keyword">
            <summary>Từ khoá tên xã, có dấu hay không dấu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.Dimension">
            <summary>Chiều của drill-down (1/2/3); <c>null</c> khi không gửi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.Key">
            <summary>Khoá dòng của drill-down (AgencyId / ManagerId / WardId); <c>null</c> khi không gửi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.StatusGroup">
            <summary>Cột của drill-down: 0 = Tổng (mọi nhóm), 1–4 = <c>OrderStatusGroup</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.PageIndex">
            <summary>Trang drill-down, đánh từ 1.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.PageSize">
            <summary>Cỡ trang drill-down, trần <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.MaxPageSize"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.TryParse(Lada.Framework.DTO.SmartTable.SmartTableParam,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter@,System.String@)">
            <summary>Đọc và kiểm bộ lọc.</summary>
            <param name="param">Tham số client gửi.</param>
            <param name="now">Thời điểm hiện tại — để tính kỳ mặc định.</param>
            <param name="filter">Bộ lọc đã kiểm; <c>null</c> khi trả false.</param>
            <param name="error">Câu báo lỗi tiếng Việt khi trả false.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter.ReadDay(Newtonsoft.Json.Linq.JObject,System.String)">
            <summary>
            Ngày giờ Việt Nam chứa mốc client gửi. Newtonsoft có thể đã đổi chuỗi ngày thành <c>DateTime</c> (theo giờ máy
            chủ hoặc UTC) — vẫn đúng thời điểm, đổi sang +07:00 rồi lấy ngày. Chuỗi không có offset hiểu là giờ Việt Nam.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.IOrderRevenueDimensionReportService">
            <summary>
            Báo cáo doanh số theo bưu cục / nhóm / phường xã × 4 nhóm trạng thái đơn + drill-down
            (docs/plan-bao-cao-doanh-so-theo-chieu.md §3.3).
            </summary>
            <remarks>
            Mọi đường đọc — kể cả drill-down và Excel (Excel gọi lại chính các hàm này) — ép phạm vi người xem ở đây qua
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope"/>. Phạm vi rỗng ⇒ trả rỗng, KHÔNG gọi stored procedure.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.IOrderRevenueDimensionReportService.GetByAgencyAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>Doanh số theo bưu cục bán (<c>Order.SaleAgencyId</c>).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.IOrderRevenueDimensionReportService.GetByTeamAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>Doanh số theo nhóm (quản lý trực tiếp của sale).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.IOrderRevenueDimensionReportService.GetByWardAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>Doanh số theo phường/xã của điểm lấy hoặc điểm giao.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.IOrderRevenueDimensionReportService.GetDetailAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Danh sách đơn của một ô. Kiểm role của chiều ngay trong service (action chỉ đòi đăng nhập), rồi dùng CÙNG
            hàm phạm vi với báo cáo của chiều đó.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.IOrderRevenueDimensionReportService.GetFilterOptionsAsync(System.Int32)">
            <summary>Bưu cục và nhóm trong phạm vi người xem, kèm tỉnh/thành phố bộ 2 cấp, cho ô lọc của ba trang.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.IOrderRevenueDimensionReportService" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService.TenNhomKhongCoSale">
            <summary>Tên dòng nhóm <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope.NoSaleGroupId"/> — trùng tên SP đặt.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService._visibilityResolver">
            <summary>
            Nguồn luật "ai xem được doanh số của ai" và luật Founder/kế toán không giới hạn — dùng lại, không dựng cây
            phân cấp thứ ba.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService._userRepository">
            <summary><c>IUserRepository</c> chứ không phải <c>IRepository&lt;User&gt;</c> — xem ghi chú ở <c>ReconciliationVisibilityResolver</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService.GetByAgencyAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService.GetByTeamAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService.GetByWardAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService.GetDetailAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService.GetFilterOptionsAsync(System.Int32)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService.AgencyScopeResult">
            <summary>Phạm vi bưu cục đã thu hẹp theo bộ lọc, kèm cờ gom đơn không có bưu cục bán.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService.AgencyScopeResult.#ctor(Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueIdScope,System.Boolean)">
            <summary>Phạm vi bưu cục đã thu hẹp theo bộ lọc, kèm cờ gom đơn không có bưu cục bán.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService.ResolveAgencyScopeAsync(System.Int32,System.Nullable{System.Int32})">
            <summary>
            Phạm vi bưu cục: Founder/kế toán → mọi bưu cục kể cả đã xoá mềm; người đứng tên bưu cục → các bưu cục đó +
            con cháu; còn lại rỗng (plan §6.3). Bộ lọc <paramref name="requestedAgencyId"/> chỉ thu hẹp; node Region mở
            thành con cháu trên cây ĐẦY ĐỦ (kể cả bưu cục đã xoá).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService.ResolveSaleScopeAsync(System.Int32)">
            <summary>Phạm vi sale: nguyên <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Finance.IReconciliationVisibilityResolver"/>; Founder/kế toán → mọi user kể cả đã xoá mềm.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService.LoadManagerOfSaleAsync">
            <summary>
            Quản lý trực tiếp của từng sale — đúng nguồn cột <c>ManagerId</c> của <c>vw_OrderRevenueFact</c>
            (<c>UserPreference</c> chưa xoá, <c>ManagerId &gt; 0</c>).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService.MarkDeletedAgenciesAsync(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueByAgencyItem})">
            <summary>Gắn cờ bưu cục đã xoá mềm — giao diện ghi "(đã ngừng)".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService.TryBegin``1(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Reports.Results.OrderRevenueDimensionResult{``0},Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter@)">
            <summary>Kiểm người dùng + bộ lọc, ghi kỳ thực dùng vào kết quả. False = kết quả đã mang lỗi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService.PeriodParameters(Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionFilter)">
            <summary>
            Kỳ truyền xuống SP — luôn <c>DateTimeOffset</c> +07:00. <c>DateTime</c> bị SqlClient coi là UTC, mốc 23:59:59
            khi đó sang ngày hôm sau.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionReportService.Fail(Lada.Framework.DTO.BaseResult,System.Exception,System.String,System.Int32)">
            <summary>Ghi log đầy đủ, trả người dùng một câu chung — không lộ chi tiết lỗi SQL.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueIdScope">
            <summary>
            Một tập id phạm vi (bưu cục hoặc sale) truyền xuống <c>@AgencyIds</c> / <c>@SaleIds</c> của
            <c>sp_GetOrderRevenueBy*</c>.
            </summary>
            <remarks>
            Không có trạng thái "không giới hạn": bốn SP doanh số theo chiều không có nhánh "tất cả", nên Founder/kế toán
            cũng mang danh sách tường minh. Tập rỗng = <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueIdScope.CanRead"/> false = KHÔNG gọi SP.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueIdScope.Ids">
            <summary>Id đã lọc &gt; 0, không trùng, tăng dần.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueIdScope.CanRead">
            <summary>Có dòng nào để đọc. False thì service trả rỗng và không gọi stored procedure.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueIdScope.ToCsv">
            <summary>Danh sách ngăn cách dấu phẩy cho tham số SP — chỉ gọi khi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueIdScope.CanRead"/>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueTeamScope">
            <summary>
            Phạm vi của một lần đọc báo cáo doanh số theo nhóm (hoặc drill-down chiều nhóm), đã tính bộ lọc nhóm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueTeamScope.CanRead">
            <summary>Có dòng nào để đọc. False thì không được gọi stored procedure.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueTeamScope.SaleIdsCsv">
            <summary><c>@SaleIds</c> — không bao giờ rỗng khi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueTeamScope.CanRead"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueTeamScope.ManagerIdsCsv">
            <summary>
            <c>@ManagerIds</c>: <c>null</c> = không thu hẹp theo nhóm. Không bao giờ là chuỗi rỗng — SP hiểu <c>''</c>
            là "0 dòng", nhưng hàng rào phải ở đây chứ không trông vào SP.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueTeamScope.IncludeUnassigned">
            <summary>
            <c>@IncludeUnassigned</c>: thêm dòng <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope.NoSaleGroupId"/> "Đơn không có sale" —
            chỉ Founder/kế toán (plan §6.3).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueAgencyFacts">
            <summary>
            Dữ kiện để tính phạm vi bưu cục — service đọc từ DB, <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope.ResolveAgencies(Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueAgencyFacts)"/>
            áp luật.
            </summary>
            <param name="Unrestricted">Founder / kế toán (cùng luật <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibility.Unrestricted"/>).</param>
            <param name="AllAgencyIds">Mọi <c>Agency</c> KỂ CẢ đã xoá mềm — chỉ đọc khi <paramref name="Unrestricted"/>.</param>
            <param name="ManagedAgencyIds">Bưu cục người xem đứng tên <c>Agency.ManagerId</c>, đã mở con cháu.</param>
            <param name="RegionAgencyIds">Node <c>AgencyType.Region</c> — node gộp, không bao giờ là một dòng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueAgencyFacts.#ctor(System.Boolean,System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>
            Dữ kiện để tính phạm vi bưu cục — service đọc từ DB, <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope.ResolveAgencies(Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueAgencyFacts)"/>
            áp luật.
            </summary>
            <param name="Unrestricted">Founder / kế toán (cùng luật <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibility.Unrestricted"/>).</param>
            <param name="AllAgencyIds">Mọi <c>Agency</c> KỂ CẢ đã xoá mềm — chỉ đọc khi <paramref name="Unrestricted"/>.</param>
            <param name="ManagedAgencyIds">Bưu cục người xem đứng tên <c>Agency.ManagerId</c>, đã mở con cháu.</param>
            <param name="RegionAgencyIds">Node <c>AgencyType.Region</c> — node gộp, không bao giờ là một dòng.</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueAgencyFacts.Unrestricted">
            <summary>Founder / kế toán (cùng luật <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibility.Unrestricted"/>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueAgencyFacts.AllAgencyIds">
            <summary>Mọi <c>Agency</c> KỂ CẢ đã xoá mềm — chỉ đọc khi <paramref name="Unrestricted"/>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueAgencyFacts.ManagedAgencyIds">
            <summary>Bưu cục người xem đứng tên <c>Agency.ManagerId</c>, đã mở con cháu.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueAgencyFacts.RegionAgencyIds">
            <summary>Node <c>AgencyType.Region</c> — node gộp, không bao giờ là một dòng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueAgencyNode">
            <summary>Một nút của cây bưu cục ĐẦY ĐỦ (kể cả đã xoá mềm) — để mở con cháu khi lọc theo khu vực.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueAgencyNode.#ctor(System.Int32,System.Int32)">
            <summary>Một nút của cây bưu cục ĐẦY ĐỦ (kể cả đã xoá mềm) — để mở con cháu khi lọc theo khu vực.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope">
            <summary>
            Dịch phạm vi xem của người dùng thành tham số của bốn SP doanh số theo chiều
            (plan-bao-cao-doanh-so-theo-chieu §3.3, quyết định §6.3).
            </summary>
            <remarks>
            <para>
            Hàm thuần cùng khuôn <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueSaleScope"/>, và cùng lý do: service gọi Dapper thẳng nên luật
            phạm vi chỉ kiểm chứng được bằng test khi nằm riêng ở đây.
            </para>
            <para>
            Hai phạm vi:
            </para>
            <list type="bullet">
            <item><b>Bưu cục</b> (báo cáo bưu cục, phường/xã, drill-down chiều 1 và 3): Founder/kế toán → mọi bưu cục kể cả
            đã xoá mềm (để tổng = tổng KPI); người đứng tên <c>Agency.ManagerId</c> → các bưu cục đó + con cháu; còn lại →
            <b>rỗng</b>. Cố ý KHÔNG mở theo <c>User.AgencyId</c>: role báo cáo cấp cho cả nhóm "Kinh doanh", mở theo bưu cục
            của bản thân thì một sale ngồi HQ thấy danh sách đơn (kèm tên khách) của cả HQ — đúng điều
            <c>ReconciliationVisibilityResolver</c> đã chữa.</item>
            <item><b>Sale</b> (báo cáo nhóm, drill-down chiều 2): nguyên <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibility"/> — bản thân +
            cấp dưới đệ quy + nhân sự bưu cục mình đứng tên; Founder/kế toán → mọi user kể cả đã xoá mềm (sale đã nghỉ vẫn
            có đơn — thiếu họ là tổng báo cáo nhóm hụt).</item>
            </list>
            <para>
            Bộ lọc của client chỉ được <b>thu hẹp</b>: id ngoài phạm vi bị bỏ im lặng, lọc xong không còn id nào thì
            rỗng — không bao giờ lấy thêm được dòng nào (chống IDOR, §3.8).
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope.NoSaleGroupId">
            <summary>
            Khoá nhóm "Đơn không có sale" (SaleId không trỏ User nào — đơn khách tự tạo qua Lada.App ghi cứng
            <c>SaleId = 0</c>). Chỉ Founder/kế toán thấy, để tổng báo cáo nhóm = tổng view (plan §6.3).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope.ResolveAgencies(Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueAgencyFacts)">
            <summary>Phạm vi bưu cục của người xem.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope.NarrowAgencies(Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueIdScope,System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>
            Thu hẹp phạm vi bưu cục theo bộ lọc của client.
            </summary>
            <param name="scope">Phạm vi của người xem.</param>
            <param name="requestedAgencyIds">
            Bưu cục client chọn, đã mở con cháu nếu là node Region (lọc theo khu vực = lọc theo con cháu).
            <c>null</c> = không lọc; tập rỗng = lọc ra không gì.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope.IncludeUnassignedAgencies(System.Boolean,System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>
            Báo cáo phường/xã (và drill-down chiều 3) có gồm đơn không có bưu cục bán thật (<c>SaleAgencyId</c> = 0, trỏ
            bưu cục không tồn tại hoặc node khu vực) hay không: chỉ Founder/kế toán, và chỉ khi KHÔNG lọc bưu cục — đơn
            đó không thuộc bưu cục nào nên lọc theo bưu cục là phải mất.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope.Descendants(System.Int32,System.Collections.Generic.IReadOnlyCollection{Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueAgencyNode})">
            <summary>
            Chính nó + mọi con cháu trên cây bưu cục ĐẦY ĐỦ, kể cả nút đã xoá mềm và nhánh nằm dưới chúng — để Founder lọc
            theo khu vực vẫn thấy bưu cục đã ngừng (DS-7). Khác <c>IAgencyService.GetAgencyWithDescendantIdsAsync</c>
            (chỉ cây đang sống, dùng cho phạm vi người đứng tên). Có chặn vòng lặp dữ liệu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope.ResolveSales(Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibility,System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>Phạm vi sale của người xem.</summary>
            <param name="visibility">Kết quả <c>IReconciliationVisibilityResolver.ResolveAsync</c>.</param>
            <param name="allUserIds">Mọi <c>User.Id</c> kể cả đã xoá mềm — chỉ đọc khi <c>Unrestricted</c>.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope.NarrowTeam(Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueIdScope,System.Collections.Generic.IReadOnlyDictionary{System.Int32,System.Int32},System.Nullable{System.Int32},System.Boolean)">
            <summary>
            Phạm vi báo cáo nhóm sau bộ lọc nhóm của client.
            </summary>
            <param name="sales">Phạm vi sale của người xem.</param>
            <param name="managerOfSale">
            <c>UserPreference.ManagerId</c> &gt; 0 theo sale (dòng chưa xoá) — đúng nguồn cột <c>ManagerId</c> của view.
            Sale vắng mặt = nhóm 0 "Chưa có quản lý trực tiếp". Chỉ cần khi có <paramref name="requestedManagerId"/>.
            </param>
            <param name="requestedManagerId">
            Nhóm client chọn; <c>0</c> = "chưa có quản lý"; <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope.NoSaleGroupId"/> = "Đơn không có sale";
            <c>null</c> hoặc nhỏ hơn <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope.NoSaleGroupId"/> = không lọc.
            </param>
            <param name="unrestricted">Founder/kế toán — người duy nhất thấy nhóm "Đơn không có sale".</param>
            <remarks>
            Lọc theo nhóm thu hẹp luôn <c>@SaleIds</c> xuống các sale của nhóm đó trong phạm vi: nhóm ngoài phạm vi (không
            sale nào của mình thuộc nhóm ấy) ra rỗng ngay ở đây, không gọi SP. Người bị giới hạn xin nhóm "Đơn không có
            sale" cũng rỗng.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueDimensionScope.ManagersInScope(Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueIdScope,System.Collections.Generic.IReadOnlyDictionary{System.Int32,System.Int32})">
            <summary>Các nhóm (quản lý trực tiếp, kể cả 0) có ít nhất một sale trong phạm vi — cho ô lọc nhóm.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueExcelColumn`1">
            <summary>Một cột chiều (cột đứng trước 4 cặp số) của file Excel doanh số theo chiều.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueExcelColumn`1.#ctor(System.String,System.Func{`0,System.Object})">
            <summary>Một cột chiều (cột đứng trước 4 cặp số) của file Excel doanh số theo chiều.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueExcelBuilder">
            <summary>
            File Excel của báo cáo doanh số theo chiều — đúng bảng trên màn hình: cột chiều + 4 cặp (số đơn, doanh số) theo
            nhóm trạng thái + tổng, dòng "Tổng cộng" cuối.
            </summary>
            <remarks>
            Hàm thuần: nhận dòng ĐÃ ép phạm vi, trả byte. Mọi ô ghi dạng giá trị (không công thức), nên tên bắt đầu bằng
            <c>=</c> không thành công thức.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueExcelBuilder.HeaderRow">
            <summary>Dòng tiêu đề nhóm cột (dòng dưới nó là "Số đơn" / "Doanh số").</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueExcelBuilder.FirstDataRow">
            <summary>Dòng dữ liệu đầu tiên.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueExcelBuilder.Groups">
            <summary>4 nhóm trạng thái theo thứ tự cột, rồi "Tổng".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueExcelBuilder.Build``1(System.String,System.String,System.String,System.String,System.String,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueExcelColumn{``0}},System.Collections.Generic.IReadOnlyList{``0},Ladaer.BackEnd.Infrastructures.DTO.Reports.Items.Orders.OrderRevenueStatusAmounts)">
            <param name="sheetName">Tên sheet.</param>
            <param name="title">Dòng tiêu đề (dòng 1).</param>
            <param name="period">Dòng kỳ báo cáo (dòng 2).</param>
            <param name="filters">Dòng bộ lọc đang áp (dòng 3) — dựng bằng <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueExcelBuilder.FilterLine(System.Collections.Generic.IReadOnlyCollection{System.ValueTuple{System.String,System.String}})"/>.</param>
            <param name="exportedBy">Dòng người xuất (dòng 4).</param>
            <param name="columns">Cột chiều.</param>
            <param name="items">Các dòng đã ép phạm vi.</param>
            <param name="summary">Dòng tổng cộng.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueExcelBuilder.FilterLine(System.Collections.Generic.IReadOnlyCollection{System.ValueTuple{System.String,System.String}})">
            <summary>
            Dòng "Bộ lọc" của file. File tách khỏi màn hình ngay khi tải về: không ghi bộ lọc thì dòng "Tổng cộng" của một
            file đã lọc theo bưu cục / nhóm / tỉnh bị đọc thành tổng cả kỳ, và hai lần xuất khác bộ lọc ra hai file không
            phân biệt được (review GĐ C2).
            </summary>
            <param name="applied">Từng bộ lọc đang áp dạng (nhãn, giá trị hiển thị); rỗng = không lọc.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.SaleRevenueScope">
            <summary>
            Phạm vi nhân sự của một lần đọc báo cáo doanh số theo Sale, đã tính cả bộ lọc người dùng chọn.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.SaleRevenueScope.CanRead">
            <summary>Có dòng nào để đọc hay không. False thì không được gọi stored procedure.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.SaleRevenueScope.SaleIdsCsv">
            <summary>
            Danh sách nhân sự truyền xuống <c>@SaleIds</c>, ngăn cách dấu phẩy.
            <c>null</c> nghĩa là không giới hạn (Founder / kế toán). Không bao giờ là chuỗi rỗng —
            stored procedure hiểu chuỗi rỗng là "mọi sale", nên rỗng phải đi đường <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.SaleRevenueScope.CanRead"/>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueSaleScope">
            <summary>
            Dịch phạm vi xem của người dùng thành tham số của
            <c>sp_GetOrderRevenueStatisticsBySale_Optimized</c>.
            </summary>
            <remarks>
            <para>
            Hàm thuần, tách khỏi <c>SaleReportService</c> vì service gọi Dapper thẳng nên không có cách
            nào kiểm chứng luật phạm vi bằng test nếu luật nằm lẫn trong đó.
            </para>
            <para>
            Nguồn luật "ai xem được doanh số của ai" vẫn là <c>IReconciliationVisibilityResolver</c> —
            bản thân + cấp dưới theo <c>UserPreference.ManagerId</c> (đệ quy hết cây) + nhân sự các chi
            nhánh mình đứng tên quản lý. Tên kiểu còn mang tiền tố <c>Reconciliation</c> vì miền đối soát
            là nơi luật này ra đời; cố ý dùng lại thay vì dựng cây phân cấp thứ hai.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueSaleScope.Resolve(Ladaer.BackEnd.Infrastructures.Services.Finance.ReconciliationVisibility,System.Nullable{System.Int32})">
            <summary>
            Tính phạm vi cho một lần đọc.
            </summary>
            <param name="visibility">Phạm vi nhân sự của người đang đăng nhập.</param>
            <param name="requestedSaleId">Sale mà người dùng chọn trên bộ lọc, nếu có.</param>
            <remarks>
            Bộ lọc của client chỉ được <b>thu hẹp</b>: chọn một người ngoài phạm vi thì kết quả rỗng
            chứ không lấy thêm được dòng nào (chống IDOR).
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavPermissions">
            <summary>
            Ba báo cáo doanh số theo chiều, nút Xuất Excel và link mã đơn của drill-down có được hiện cho một người hay
            không (rule <c>quyen-hien-thi</c>).
            </summary>
            <remarks>
            <para>
            Hàm thuần cùng khuôn <c>FranchisePriceNavPermissions</c>: nhận role đã phân giải qua <c>IUserRoleResolver</c>, trả
            cờ — để luật "ai thấy gì" có ca test gọi thẳng vào nó, và để drill-down kiểm role theo chiều bằng CÙNG một luật
            (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavPermissions.CanViewDimension(Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavFlags,System.Int32)"/>).
            </para>
            <para>
            Bốn role riêng tiền tố <c>RevenueReport.</c>, không mượn role miền khác (plan §3.6). Đổi role ở đây thì sửa cả
            <c>[Authorize]</c> của <c>RevenueReportController</c>, script seed role và script menu — test reflection canh
            cờ ↔ <c>[Authorize]</c>. Riêng <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavPermissions.TrackOrder"/> là role của MIỀN ĐƠN HÀNG: cờ phải đọc đúng bó quyền
            của thứ nó gác (trang tra cứu đơn), không phải bó quyền của báo cáo.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavPermissions.Founder">
            <summary>Vai bỏ qua mọi kiểm tra role (<c>ServerRoleAuthorizationHandler</c>) — ẩn nút của Founder là dựng hàng rào không có thật.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavPermissions.ByAgency">
            <summary>Báo cáo doanh số theo bưu cục.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavPermissions.ByTeam">
            <summary>Báo cáo doanh số theo nhóm.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavPermissions.ByWard">
            <summary>Báo cáo doanh số theo phường/xã.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavPermissions.Export">
            <summary>Xuất Excel — đi KÈM role của chiều (hai <c>[Authorize]</c> trên action Export là phép AND).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavPermissions.TrackOrder">
            <summary>
            Role của <c>GET Order/TrackingWithUnits</c> — lời gọi duy nhất của trang tra cứu đơn mà link mã đơn trong
            hộp thoại drill-down mở ra. Người xem báo cáo mà thiếu role này bấm link là cả SPA bị đá sang trang
            "không có quyền" (bấm thật GĐ C2, vai kế toán).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavPermissions.DimensionAgency">
            <summary>Chiều 1 bưu cục, 2 nhóm, 3 phường/xã — đúng <c>@Dimension</c> của <c>sp_GetOrderRevenueDetail</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavPermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c>; <c>null</c> = không có role nào.</param>
            <remarks>So khớp phân biệt hoa thường — đúng như <c>ServerRoleAuthorizationHandler</c> (<c>roles.Contains</c>).</remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavPermissions.CanViewDimension(Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavFlags,System.Int32)">
            <summary>Người có cờ này có được đọc chiều <paramref name="dimension"/> không — luật kiểm role của drill-down.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavFlags">
            <summary>Cờ hiển thị của ba báo cáo doanh số theo chiều — FE đọc bằng <c>=== true</c>, mặc định false, ẩn hẳn phần tử.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.RevenueReportNavFlags.#ctor(System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
            <summary>Cờ hiển thị của ba báo cáo doanh số theo chiều — FE đọc bằng <c>=== true</c>, mặc định false, ẩn hẳn phần tử.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.ISaleReportService">
            <summary>
            Interface dịch vụ báo cáo bán hàng
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.ISaleReportService.GetSaleRevenueStatisticsAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy thống kê doanh thu theo sale từ stored procedure
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng</param>
            <returns>Kết quả thống kê doanh thu</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.ISaleReportService.GetOrderRevenueStatisticsByDateAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy thống kê đơn hàng và doanh thu theo ngày từ stored procedure
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng</param>
            <returns>Danh sách thống kê đơn hàng và doanh thu theo ngày</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.ISaleReportService.GetOrderRevenueByCollectionDateAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy thống kê doanh thu theo ngày nhận tiền từ stored procedure
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng</param>
            <returns>Danh sách thống kê doanh thu theo ngày nhận tiền</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.ISaleReportService.GetOrderRevenueBySaleAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy thống kê doanh thu theo Sale (chỉ thống kê tài chính) từ stored procedure
            </summary>
            <remarks>
            Trả về doanh số của <b>mọi nhân sự trong phạm vi quản lý</b> của người gọi, không chỉ của
            riêng người đó: bản thân + cấp dưới theo cây quản lý + nhân sự các chi nhánh mình đứng tên
            quản lý; Founder và kế toán xem toàn công ty. Bên gọi cần đúng doanh số cá nhân thì phải
            tự lọc theo <c>SaleId</c> — xem <c>SalesPersonalRevenueProvider</c>.
            </remarks>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng</param>
            <returns>Danh sách thống kê theo Sale</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.ISaleReportService.GetCustomerRevenueStatisticsAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Lấy thống kê doanh thu theo khách hàng từ stored procedure
            </summary>
            <param name="param">Tham số bảng thông minh</param>
            <param name="userId">ID người dùng</param>
            <returns>Kết quả thống kê doanh thu theo khách hàng</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.ISaleReportService.GetCustomerRevenuePermissionsAsync(System.Int32)">
            <summary>
            Lấy thông tin quyền của user cho báo cáo doanh thu theo khách hàng
            </summary>
            <param name="userId">ID người dùng</param>
            <returns>Thông tin quyền</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.SaleReportService">
            <summary>
            Dịch vụ báo cáo bán hàng
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.SaleReportService._visibilityResolver">
            <summary>
            Nguồn luật "ai xem được doanh số của ai" — xem <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.OrderRevenueSaleScope"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.SaleReportService.GetSaleRevenueStatisticsAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.SaleReportService.GetOrderRevenueStatisticsByDateAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.SaleReportService.GetOrderRevenueByCollectionDateAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.SaleReportService.GetOrderRevenueBySaleAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.SaleReportService.GetCustomerRevenueStatisticsAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Report.SaleReports.SaleReportService.GetCustomerRevenuePermissionsAsync(System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Rewards.IAutoPenaltyConfigService.GetCurrentConfig">
            <summary>
            Lấy cấu hình đang hiệu lực
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Rewards.IAutoPenaltyConfigService.UpdateConfig(Ladaer.BackEnd.Infrastructures.Services.Rewards.AutoPenaltyConfigModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Cập nhật cấu hình (tạo version mới)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Rewards.IAutoPenaltyConfigService.TogglePause(System.Boolean,System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạm dừng / Mở lại
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Rewards.IAutoPenaltyConfigService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh sách cấu hình
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Rewards.IAutoPenaltyConfigService.GetById(System.Int32)">
            <summary>
            Lấy chi tiết cấu hình theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Rewards.IAutoPenaltyConfigService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.Services.Rewards.AutoPenaltyConfigModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo mới hoặc cập nhật cấu hình
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Rewards.IAutoPenaltyConfigService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa cấu hình
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Rewards.AutoPenaltyConfigService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm danh sách cấu hình
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Rewards.AutoPenaltyConfigService.GetById(System.Int32)">
            <summary>
            Lấy chi tiết cấu hình theo ID
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Rewards.AutoPenaltyConfigService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.Services.Rewards.AutoPenaltyConfigModel,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo mới hoặc cập nhật cấu hình
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Rewards.AutoPenaltyConfigService.Delete(System.Int32,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Xóa cấu hình (soft delete)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Rewards.RewardPenaltyService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm phiếu thưởng/phạt
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Rewards.RewardPenaltyService.CreateFromCashierViolation(System.Int32,System.String,Lada.Framework.Infrastructures.CurrentUser)">
            <summary>
            Tạo biên bản vi phạm nộp tiền trễ từ trang Cashier
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.IBotVisitService">
             <summary>
             Đọc số lượt bot cho màn hình. <b>Không gọi ra ngoài lần nào</b> — mọi con số đã nằm sẵn trong
             <c>BotVisitDaily</c>, do middleware của website ghi.
            
             <para>
             <b>Con số ở đây là theo User-Agent TỰ KHAI.</b> Không reverse-DNS, không đối chiếu dải IP của
             Google (nợ SC-11). Mọi màn hình đọc service này phải nói câu đó ra, vì con số trông y hệt một
             con số đã xác minh.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.IBotVisitService.GetSummaryAsync(System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>Các con số tổng hợp đầu tab, kèm câu trả lời cho "vì sao đang là 0".</summary>
            <param name="days">Độ dài khoảng ngày</param>
            <param name="bot">Lọc theo một bot; <c>null</c> là mọi bot</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.IBotVisitService.GetTopPathsAsync(System.Int32,System.String,System.Int32,System.Boolean,System.Threading.CancellationToken)">
            <summary>Xếp hạng đường dẫn theo số lượt bot trong khoảng ngày.</summary>
            <param name="days">Độ dài khoảng ngày</param>
            <param name="bot">Lọc theo một bot; <c>null</c> là mọi bot</param>
            <param name="take">Số dòng tối đa</param>
            <param name="chiLoi">Chỉ lấy đường dẫn có lượt trả mã từ 400 trở lên</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.BotVisitService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.IBotVisitService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.BotVisitService.MaxTake">
            <summary>Trần số dòng trả về một lượt, chống <c>?take=999999</c> kéo cả bảng.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.BotVisitService.MaxDays">
            <summary>
            Trần số ngày hỏi được một lượt. Đặt bằng 400 chứ không bằng hạn giữ dữ liệu (90): hạn giữ
            là một khoá cấu hình có thể bị nâng lên, còn đây là hàng rào chống một lời gọi quét cả bảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.BotVisitService.NoiVoiTonKhoAsync(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.BotVisitPathItem},System.Threading.CancellationToken)">
            <summary>
            Gắn cờ "đường dẫn này hệ thống có biết không" cho từng dòng.
            </summary>
            <remarks>
            <para>
            <b>So giữa hai dạng ĐÃ chuẩn hoá, không so thẳng hai cột.</b> <c>SearchUrl.Path</c> được
            ghi bằng <c>Uri.AbsolutePath</c> nên giữ nguyên chữ hoa và giữ nguyên dạng mã hoá phần
            trăm; <c>BotVisitDaily.Path</c> thì đã hạ chữ thường và bỏ <c>/</c> cuối. So thẳng là cách
            chắc chắn ra kết quả sai — đúng cái bẫy đã cắn ở giai đoạn E (nối <c>UrlNormalized</c> với
            <c>SearchUrl.Url</c> thô) và lặp lại ở giai đoạn F. Cả hai bên vì thế cùng đi qua
            <c>UrlRedirectHelper.NormalizeLookupPath</c>.
            </para>
            <para>
            Nạp trọn hàng tồn kho vào bộ nhớ vì phép chuẩn hoá là một hàm C#, không dịch được sang
            SQL. Đo 2026-09-17 trên DB dev: 148 dòng — không đáng để đổi lấy một phép so sai.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.BotVisitService.PathGopTran">
            <summary>Rổ gộp của bộ đếm khi chạm trần số khoá — khớp <c>BotVisitCounter.PathTran</c> bên website.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchAnalyticsClient">
             <summary>
             Lớp duy nhất biết giao thức đọc số liệu hiệu suất tìm kiếm.
            
             <para>
             Tách khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleClient"/> dù <b>cùng</b> tên miền và <b>cùng</b> phạm vi
             OAuth <c>webmasters</c>, vì hình dạng việc khác hẳn: đây là lời gọi <b>phân trang</b>, trả về
             hàng nghìn dòng, và có một khái niệm riêng — <c>dataState</c> — mà ba endpoint kia không có.
             Nhét nó vào giao diện kia sẽ làm mọi cài đặt giả trong test phải cài thêm một phương thức
             chúng không dùng.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchAnalyticsClient.Engine">
            <summary>Công cụ tìm kiếm mà cài đặt này nói chuyện.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchAnalyticsClient.QueryAsync(Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsRequest,System.Threading.CancellationToken)">
            <summary>
            Đọc <b>một trang</b> kết quả. Trả kết quả bị chặn (và <b>không</b> có lời gọi nào đi ra)
            khi công tắc đọc còn tắt.
            </summary>
            <param name="request">Khoảng ngày, các chiều, và vị trí phân trang.</param>
            <param name="cancellationToken">Thẻ huỷ.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsRequest">
            <summary>Một lời gọi đọc số liệu — đúng một trang kết quả.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsRequest.StartDate">
            <summary>Ngày đầu khoảng (bao gồm).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsRequest.EndDate">
            <summary>Ngày cuối khoảng (bao gồm).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsRequest.Dimensions">
             <summary>
             Các chiều, theo đúng chữ của Google (<c>date</c>, <c>page</c>, <c>query</c>).
            
             <para>
             <b>Chiều <c>date</c> luôn đứng đầu ở mọi lời gọi của giai đoạn này</b>, và đó là một
             quyết định đo được: thêm nó vào thì một lời gọi phủ trọn một khoảng ngày mà <i>vẫn giữ
             nguyên độ mịn theo ngày</i>. Đối chứng 2026-09-16 cho ngày 13/09: <c>date+page</c> trả
             117 dòng, gọi riêng ngày ấy với <c>page</c> cũng trả đúng 117. Nhờ vậy job hằng ngày gọi
             3 lần thay vì 30, và lượt kéo bù 16 tháng gọi ~51 lần thay vì ~1.500.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsRequest.StartRow">
            <summary>Dòng bắt đầu — phân trang. Google trả tối đa <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsRequest.RowLimit"/> dòng mỗi lượt.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsRequest.RowLimit">
            <summary>Số dòng tối đa mỗi lượt. Trần của Google là 25.000.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsRequest.MaxRowLimit">
            <summary>Trần Google cho phép cho <c>rowLimit</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPage">
            <summary>Một trang kết quả đã đọc xong.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPage.Rows">
            <summary>Các dòng của trang này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPage.CoTheConTrangSau">
            <summary>
            Còn trang sau hay không. Google <b>không</b> nói ra điều này; suy từ việc trang hiện tại
            đầy đúng bằng <c>rowLimit</c>. Suy sai theo chiều thừa chỉ tốn một lời gọi trả về rỗng;
            suy sai theo chiều thiếu là mất dữ liệu im lặng, nên chọn chiều thừa.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsRow">
            <summary>Một dòng số liệu thô như Google trả về.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsRow.Keys">
            <summary>
            Các giá trị chiều, đúng thứ tự đã hỏi trong <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsRequest.Dimensions"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsRow.Position">
            <summary>Vị trí trung bình của dòng này. <b>Chưa</b> nhân trọng số — xem chỗ lưu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchAnalyticsClient">
             <summary>
             Cài đặt cho Google Search Analytics (<c>searchanalytics.query</c> của Search Console API).
            
             <para>
             <b><c>dataState</c> viết cứng là <c>final</c>, không để thành tham số.</b> Đây là hàng rào duy
             nhất chống việc ghi vào DB một con số Google chưa chốt — mà số chưa chốt thì ghi rồi là sai
             vĩnh viễn, vì lượt kéo sau sẽ không bao giờ quay lại ngày đó nữa nếu nó đã ra khỏi cửa sổ
             trượt. Mở nó thành tham số là để lại đúng một chỗ cho ai đó truyền <c>all</c> vào rồi không ai
             biết. Đo thật 2026-09-16: <c>final</c> trả tới T-3, <c>all</c> trả tới T-1, và với 13 ngày
             trùng nhau thì hai bên cho số <b>giống hệt</b> — nghĩa là <c>final</c> không làm mất gì, nó
             chỉ từ chối trả những ngày chưa xong.
             </para>
            
             <para>
             <b>Cách xử lý lỗi giống hệt hai client kia</b>, cố ý: 403 là lỗi quyền nên không thử lại; 429
             ném <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchQuotaExceededException"/> để lượt chạy dừng hẳn; 5xx và lỗi mạng thử lại
             tối đa ba lần, giãn cách <c>2^lần</c> giây.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchAnalyticsClient.HttpClientName">
            <summary>Tên named client riêng — để đo và cấu hình tách khỏi hai đường gọi kia.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchAnalyticsClient.DataState">
            <summary>
            Chỉ nhận số đã chốt. Xem XML-doc của lớp về việc vì sao đây không phải tham số.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchAnalyticsClient.ParsePage(System.String,System.Int32)">
            <summary>
            Đọc phản hồi. Google <b>bỏ hẳn</b> khoá <c>rows</c> khi không có dòng nào (chứ không trả
            mảng rỗng), nên "không có <c>rows</c>" là một kết quả hợp lệ chứ không phải lỗi đọc.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchAnalyticsClient.ReadLong(System.Text.Json.JsonElement,System.String)">
            <summary>
            Google trả <c>clicks</c> và <c>impressions</c> dưới dạng số thực trong JSON (ví dụ
            <c>44.0</c>), nên đọc thẳng bằng <c>GetInt64</c> sẽ ném. Đọc qua <c>double</c> rồi làm tròn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchAnalyticsClient.SendAsync``1(System.Func{System.Net.Http.HttpRequestMessage},System.Func{System.String,``0},System.Threading.CancellationToken)">
            <summary>
            Gửi một lời gọi, thử lại khi lỗi tạm thời, rồi đọc kết quả. Hàm dựng request truyền vào
            dưới dạng factory vì <see cref="T:System.Net.Http.HttpRequestMessage"/> chỉ gửi được một lần.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchAnalyticsClient.Summarize(System.String,System.Int32)">
            <summary>
            Rút gọn phản hồi lỗi để ghi nhật ký. Cắt ngắn vì phản hồi lỗi của Google có thể rất dài,
            và cột nhật ký có trần.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleClient">
             <summary>
             Lớp duy nhất biết giao thức của một công cụ tìm kiếm.
            
             <para>
             Đây là điểm cắm cho công cụ thứ hai: thuộc tính <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleClient.Engine"/> cho phép phân giải theo enum
             đúng như <c>IWidgetDataProvider</c> phân giải theo <c>Code</c>. Hôm nay chỉ có một cài đặt
             (Google) — quyết định Q6c là chuẩn bị mô hình dữ liệu, không dựng sẵn đường gọi Bing/IndexNow.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleClient.Engine">
            <summary>Công cụ tìm kiếm mà cài đặt này nói chuyện.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleClient.InspectAsync(System.String,System.Threading.CancellationToken)">
            <summary>Hỏi trạng thái index của một URL.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleClient.GetSitemapAsync(System.String,System.Threading.CancellationToken)">
            <summary>Đọc trạng thái một tệp sitemap.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleClient.SubmitSitemapAsync(System.String,System.Threading.CancellationToken)">
            <summary>
            Nộp một tệp sitemap. Chỉ chạy khi <b>cả hai</b> công tắc bật; công tắc ghi tắt thì trả về
            kết quả bị chặn và <b>không</b> có lời gọi nào đi ra.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleClient.TestConnectionAsync(System.Threading.CancellationToken)">
            <summary>
            Thử kết nối bằng một lời gọi đọc nhẹ nhất (liệt kê sitemap của property).
            Chỉ trả về được hay không được kèm lý do — <b>không</b> trả về email service account hay bất
            cứ mẩu nào của khoá, vì kết quả này hiện lên giao diện quản trị.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchConsoleClient">
             <summary>
             Cài đặt cho Google Search Console, gọi REST qua <see cref="T:System.Net.Http.IHttpClientFactory"/>.
            
             <para>
             <b>Vì sao gọi REST thẳng thay vì dùng gói <c>Google.Apis.SearchConsole.v1</c>.</b> Đã kiểm
             2026-09-15: gói đó cài chung với <c>Google.Ads.GoogleAds 26.1.0</c> <b>không</b> xung đột
             (build 0 lỗi) — nên lý do không phải xung đột. Lý do là kiểm thử: gói chính chủ tự dựng và tự
             giữ <c>HttpClient</c> bên trong, muốn chặn lời gọi trong test phải luồn một
             <c>ConfigurableMessageHandler</c> mà repo chưa có mẫu nào. Gọi REST qua
             <c>IHttpClientFactory</c> thì dùng lại được <c>FakeHttpClientFactory</c> sẵn có (đang dùng cho
             Zalo và Facebook), và kiểm được đúng thứ quan trọng nhất của đợt này: <b>công tắc tắt thì có
             đúng 0 lời gọi đi ra</b>. Phần ký JWT — chỗ dễ sai và nguy hiểm nhất — vẫn giao cho thư viện
             chính chủ <c>Google.Apis.Auth</c>.
             </para>
            
             <para>
             <b>Công tắc được canh ở đây, không chỉ ở job.</b> Job cũng đọc công tắc để quyết định chạy thử
             hay chạy thật, nhưng hàng rào cuối cùng đặt trong client: một đường gọi mới thêm về sau (nút bấm
             tay, một job khác) sẽ không tự biết phải kiểm công tắc, còn client thì luôn nằm trên đường đi.
             </para>
            
             <para>
             <b>Cách xử lý lỗi, theo hậu quả chứ không theo mã.</b>
             <list type="bullet">
             <item><b>403</b>: lỗi quyền — service account chưa phải owner của property, hoặc
             <c>SiteUrl</c> sai dạng. Thử lại bao nhiêu lần cũng vẫn 403, nên báo thẳng.</item>
             <item><b>429</b>: hết hạn mức — <b>không</b> thử lại, ném <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchQuotaExceededException"/>
             để job dừng hẳn. Cố ý khác chữ trong kế hoạch (ở đó 429 nằm trong nhóm "lỗi tạm thời"): thử lại
             429 chính là đốt thêm hạn mức đang hết, mâu thuẫn với yêu cầu "429 dừng job, không đốt quota"
             trong cùng kế hoạch.</item>
             <item><b>5xx, lỗi mạng, hết giờ chờ</b>: lỗi tạm thời — thử lại tối đa 3 lần, giãn cách
             <c>2^lần</c> giây theo mẫu <c>GoogleAdsAdapter.ExecuteWithRetryAsync</c>.</item>
             </list>
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchConsoleClient.HttpClientName">
            <summary>Tên named client — theo nếp <c>ZaloApiService.HttpClientName</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchConsoleClient.MaxRawJsonLength">
            <summary>
            Trần độ dài phần JSON thô lưu vào DB. Phản hồi của Google thường dưới 4 KB; phần vượt quá
            64 KB không mang thêm thông tin nào mà chỉ làm nặng bảng và nặng cả màn xem chi tiết.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchConsoleClient.BuildSitemapEndpoint(System.String,System.String)">
            <summary>
            Dựng endpoint cho một tệp sitemap. Cả định danh property lẫn địa chỉ tệp đều phải mã hoá:
            property Domain chứa dấu hai chấm (<c>sc-domain:ladaexpress.vn</c>) và địa chỉ tệp chứa
            dấu gạch chéo — để nguyên thì chúng bị hiểu thành phân đoạn đường dẫn và Google trả 404.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchConsoleClient.SendAsync``1(System.Func{System.Net.Http.HttpRequestMessage},System.Func{System.String,``0},System.Threading.CancellationToken)">
            <summary>
            Gửi một lời gọi, thử lại khi lỗi tạm thời, rồi đọc kết quả. Hàm dựng request được truyền vào
            dưới dạng factory vì <see cref="T:System.Net.Http.HttpRequestMessage"/> chỉ gửi được một lần — lần thử lại
            phải có một đối tượng mới.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchConsoleClient.IsTransient(System.Exception)">
            <summary>
            Lỗi tạm thời: mạng trục trặc hoặc hết giờ chờ. Hết hạn mức và lỗi quyền <b>không</b> nằm ở đây.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchConsoleClient.Summarize(System.String,System.Int32)">
            <summary>
            Rút thông báo lỗi của Google về một dòng đọc được, có cắt ngắn: thân lỗi đôi khi là cả trang
            HTML, nhét nguyên vào cột <c>ErrorMessage</c> thì vừa tràn vừa không ai đọc.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchConsoleClient.TrimRaw(System.String)">
            <summary>Cắt JSON thô về trần lưu trữ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleSearchConsoleClient.ReadCount(System.Text.Json.JsonElement,System.String)">
            <summary>
            Đọc một con số mà Google có thể trả dưới dạng chuỗi hoặc số — hai kiểu này lẫn lộn ngay
            trong cùng một phản hồi.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleTokenProvider">
             <summary>
             Lấy access token để gọi Search Console.
            
             <para>
             <b>Vì sao tách khỏi client.</b> Lấy token là việc chạm đĩa (đọc tệp khoá) và chạm mạng (đổi JWT
             lấy token) — trộn vào client thì không lớp test nào kiểm được client mà không có khoá thật.
             Tách ra thì test bơm một token giả, còn phần ký JWT giao hẳn cho thư viện chính chủ của Google.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleTokenProvider.GetAccessTokenAsync(System.Threading.CancellationToken)">
            <summary>
            Access token dùng cho header <c>Authorization</c>. Ném <see cref="T:System.InvalidOperationException"/>
            khi chưa cấu hình đường dẫn khoá hoặc tệp khoá không đọc được.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleTokenProvider.GetAccessTokenAsync(System.String,System.Threading.CancellationToken)">
             <summary>
             Access token cho một phạm vi cụ thể.
            
             <para>
             <b>Vì sao phải có tham số phạm vi.</b> Cùng một service account, nhưng Search Console và
             Indexing API là hai API khác nhau với hai phạm vi khác nhau
             (<c>auth/webmasters</c> và <c>auth/indexing</c>). Một token xin cho phạm vi này gọi API kia
             sẽ bị từ chối, và thông báo lỗi của Google <b>không</b> nói rằng nguyên nhân là sai phạm vi.
             </para>
             </summary>
             <param name="scope">Phạm vi OAuth đầy đủ, ví dụ <c>https://www.googleapis.com/auth/indexing</c>.</param>
             <param name="cancellationToken">Thẻ huỷ.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleServiceAccountTokenProvider">
             <summary>
             Lấy access token từ tệp khoá JSON của một service account Google Cloud.
            
             <para>
             <b>Tệp khoá nằm ngoài repo và ngoài <c>wwwroot</c></b>, đường dẫn khai ở
             <c>Search:Google:ServiceAccountKeyPath</c> trong <c>appsettings</c> hoặc biến môi trường — cùng
             nếp với <c>Security:SecretKey</c>. Cố ý <b>không</b> cất vào DB: đổi khoá là việc vận hành, và
             một khoá nằm trong DB sẽ theo mọi bản sao lưu đi khắp nơi.
             </para>
            
             <para>
             <b>Nội dung khoá không bao giờ được ghi log</b>, kể cả khi lỗi: thông báo lỗi chỉ nói đường dẫn
             và triệu chứng. Token cũng vậy — nó nằm ở header và không đi vào nhật ký lời gọi.
             </para>
            
             <para>
             Service account phải được thêm làm <b>delegated owner</b> của property trong Search Console.
             Quyền Full hay Restricted đều trả 403 ở mọi lời gọi, và thông báo lỗi của Google không nói rằng
             nguyên nhân là mức quyền.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleServiceAccountTokenProvider.Scope">
            <summary>
            Phạm vi đủ cho cả đọc (kiểm tra URL, đọc sitemap) lẫn ghi (nộp sitemap).
            Bản <c>webmasters.readonly</c> không nộp được sitemap.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleServiceAccountTokenProvider.IndexingScope">
             <summary>
             Phạm vi của Indexing API — <b>khác</b> phạm vi Search Console và phải xin riêng.
            
             <para>
             Ngoài phạm vi, Indexing API còn phải được <b>bật riêng</b> trên project Google Cloud. Đo
             thật 2026-09-16 trên project <c>lada-ads-manager</c>: lấy token phạm vi này thành công, và
             lời gọi đọc đầu tiên vẫn trả 403 <c>SERVICE_DISABLED</c> kèm câu "Web Search Indexing API
             has not been used in project … before or it is disabled", trong khi cùng khoá ấy gọi
             Search Console vẫn 200. Nghĩa là khoá và quyền không phải nguyên nhân — cái thiếu là một
             nút bật trên bảng điều khiển Google Cloud.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleServiceAccountTokenProvider.KeyPathConfigKey">
            <summary>Khoá cấu hình chứa đường dẫn tới tệp khoá JSON.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchIndexingClient">
             <summary>
             Lớp duy nhất biết giao thức báo chủ động một URL cho công cụ tìm kiếm.
            
             <para>
             Tách khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleClient"/> vì đây là một API <b>khác</b>: khác tên miền, khác
             phạm vi OAuth, khác hạn mức, và phải bật riêng trên project Google Cloud. Gộp hai thứ vào một
             giao diện sẽ tạo ra một lớp mà nửa số phương thức chạy được còn nửa kia trả 403, tuỳ vào một
             nút bật ở nơi khác.
             </para>
            
             <para>
             Đây cũng là điểm cắm cho <c>IndexNow</c> về sau — cùng hình dạng "gửi một URL, nhận một kết
             quả", chỉ khác giao thức bên dưới. Thuộc tính <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchIndexingClient.Engine"/> cho phép phân giải theo enum.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchIndexingClient.Engine">
            <summary>Công cụ tìm kiếm mà cài đặt này nói chuyện.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchIndexingClient.PublishAsync(System.String,Lada.Framework.Data.Enums.SearchNotificationType,System.Threading.CancellationToken)">
            <summary>
            Báo một URL. Trả kết quả bị chặn (và <b>không</b> có lời gọi nào đi ra) khi công tắc còn tắt.
            </summary>
            <param name="url">URL tuyệt đối của trang.</param>
            <param name="type">Báo cập nhật hay báo đã gỡ.</param>
            <param name="cancellationToken">Thẻ huỷ.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleIndexingClient">
             <summary>
             Cài đặt cho Google Indexing API.
            
             <para>
             <b>Google chỉ chấp nhận hai loại trang</b>: tin tuyển dụng (<c>JobPosting</c>) và sự kiện phát
             trực tiếp (<c>BroadcastEvent</c>). Website này chỉ có loại thứ nhất, nên hàng rào "URL nào
             được báo" nằm ở chỗ xếp hàng đợi (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchNotificationOutbox"/>) chứ không ở đây —
             client thì gửi đúng thứ nó được đưa.
             </para>
            
             <para>
             <b>Cách xử lý lỗi giống hệt client Search Console</b>, cố ý: 403 là lỗi quyền hoặc API chưa bật
             nên không thử lại; 429 ném <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchQuotaExceededException"/> để job dừng hẳn thay vì
             đốt thêm hạn mức đang cạn; 5xx và lỗi mạng thử lại tối đa ba lần, giãn cách <c>2^lần</c> giây.
             Hai client nói cùng một ngôn ngữ lỗi thì job không phải nhớ hai bộ quy tắc.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleIndexingClient.HttpClientName">
            <summary>Tên named client riêng — để đo và cấu hình tách khỏi lời gọi Search Console.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleIndexingClient.ToApiType(Lada.Framework.Data.Enums.SearchNotificationType)">
            <summary>
            Tên loại thông báo theo đúng chữ của Google. Cố ý viết tường minh thay vì suy từ tên enum:
            đổi tên một giá trị enum trong C# là việc bình thường, còn đổi chuỗi gửi lên Google thì
            không — tách ra thì trình biên dịch không im lặng cho qua.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.GoogleIndexingClient.Summarize(System.String,System.Int32)">
            <summary>
            Rút thông báo lỗi của Google về một dòng đọc được, có nói thêm cách sửa cho hai nguyên nhân
            hay gặp nhất mà lời của Google không chỉ ra được.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchNotificationOutbox">
             <summary>
             Xếp một URL vào hàng đợi báo cho công cụ tìm kiếm.
            
             <para>
             <b>Chỉ ghi vào bảng, không gọi ra ngoài.</b> Đây là ranh giới cố ý: thao tác lưu của người dùng
             không được phụ thuộc vào một dịch vụ bên ngoài. Việc gửi thật là của
             <c>SearchUrlNotifyJob</c>.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchNotificationOutbox.EnqueueJobPostAsync(Lada.Framework.Data.Domains.Hr.JobPost,Lada.Framework.Data.Enums.SearchNotificationType,System.Threading.CancellationToken)">
            <summary>
            Xếp hàng một thông báo cho tin tuyển dụng vừa đổi.
            </summary>
            <param name="jobPost">Tin tuyển dụng, đã nạp <c>UrlRecord</c>.</param>
            <param name="type">Báo cập nhật hay báo đã gỡ.</param>
            <param name="cancellationToken">Thẻ huỷ.</param>
            <returns>Dòng vừa ghi, hoặc <c>null</c> nếu không dựng nổi URL để báo.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchNotificationOutbox.EnqueueAsync(System.String,Lada.Framework.Data.Enums.SearchNotificationType,System.Threading.CancellationToken)">
            <summary>
            Xếp hàng một URL bất kỳ. Mọi hàng rào nằm ở đây, và URL không đạt hàng rào vẫn được ghi
            một dòng <see cref="F:Lada.Framework.Data.Enums.SearchNotificationStatus.Skipped"/> kèm lý do — im lặng bỏ đi thì
            không ai biết hệ thống vừa suýt báo nhầm cái gì.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchNotificationOutbox">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchNotificationOutbox"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchNotificationOutbox.BaseUrlConfigKey">
            <summary>Khoá <c>AppConfig</c> chứa địa chỉ gốc của website công khai.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchNotificationOutbox.JobPostPathPrefix">
             <summary>
             Tiền tố đường dẫn của nhóm URL <b>duy nhất</b> được phép báo chủ động.
            
             <para>
             Google chỉ nhận Indexing API cho trang mang dữ liệu có cấu trúc <c>JobPosting</c> hoặc
             <c>BroadcastEvent</c>; website này chỉ có loại thứ nhất, và toàn bộ nó nằm dưới
             <c>/tuyen-dung/</c>. Báo một trang ngoài nhóm này là dùng sai API — Google nêu thẳng đó là
             lý do rút quyền gọi.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchNotificationOutbox.SkipAsync(System.String,Lada.Framework.Data.Enums.SearchNotificationType,System.String,System.Threading.CancellationToken)">
            <summary>
            Ghi một dòng "cố ý không báo" kèm lý do, rồi ghi cảnh báo.
            </summary>
            <remarks>
            Cảnh báo ở mức <c>Warning</c> chứ không phải <c>Information</c>: mọi lời gọi tới đây đều
            xuất phát từ code của chính mình, nên một URL bị chặn nghĩa là có một đường sinh sự kiện
            đang gọi sai chỗ — thứ cần sửa, không phải thứ để ghi nhận rồi quên.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchAnalyticsService">
             <summary>
             Kéo số liệu hiệu suất tìm kiếm về <c>SearchMetricDaily</c>.
            
             <para>
             Một lớp duy nhất phục vụ <b>cả hai</b> đường chạy — job hằng ngày (cửa sổ trượt) và lượt kéo bù
             lịch sử (bấm tay, từng lô 30 ngày). Hai đường ấy chỉ khác nhau ở khoảng ngày truyền vào; gộp
             logic lại thì không có chuyện lượt kéo bù ghi kiểu này còn job hằng ngày ghi kiểu khác.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchAnalyticsService.PullRangeAsync(Lada.Framework.Data.Enums.SearchEngine,System.DateOnly,System.DateOnly,System.Threading.CancellationToken)">
            <summary>
            Kéo trọn một khoảng ngày, cả bốn mức, rồi ghi đè-hoặc-chèn vào bảng.
            </summary>
            <param name="engine">Công cụ tìm kiếm.</param>
            <param name="startDate">Ngày đầu (bao gồm).</param>
            <param name="endDate">Ngày cuối (bao gồm).</param>
            <param name="cancellationToken">Thẻ huỷ.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchAnalyticsService.GetNgayCoSoMoiNhatAsync(Lada.Framework.Data.Enums.SearchEngine,System.Threading.CancellationToken)">
            <summary>
            Ngày gần nhất đã có số trong bảng, ở mức <see cref="F:Lada.Framework.Data.Enums.SearchMetricLevel.Site"/>.
            <c>null</c> nghĩa là <b>chưa kéo lần nào</b> — khác hẳn "đã kéo và bằng không".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchAnalyticsService.GetNgayCoSoSomNhatAsync(Lada.Framework.Data.Enums.SearchEngine,System.Threading.CancellationToken)">
            <summary>Ngày sớm nhất đã có số — để biết lượt kéo bù đã đi ngược tới đâu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult">
            <summary>Kết quả một lượt kéo, đủ để ghi nhật ký và để job in ra.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult.ApiCalls">
            <summary>Số lời gọi API đã đi ra (gồm cả lời gọi phân trang).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult.RowsReturned">
            <summary>Số dòng Google trả về, trước khi lọc ngưỡng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult.RowsFilteredOut">
            <summary>Số dòng bị ngưỡng <c>AnalyticsMinImpressions</c> loại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult.RowsInserted">
            <summary>Số dòng mới chèn vào bảng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult.RowsUpdated">
            <summary>Số dòng đã có và được ghi đè.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult.WasBlocked">
            <summary>Lời gọi bị công tắc chặn nên chưa hề đi ra.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult.Message">
            <summary>Lý do bị chặn, hoặc lý do thất bại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult.HasError">
            <summary>Có lỗi thật (khác với bị chặn) hay không.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult.QuotaExceeded">
             <summary>
             Google trả 429 — hết hạn mức.
            
             <para>
             Tách khỏi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult.HasError"/> vì hai thứ đòi hai phản ứng khác nhau ở phía job: một lỗi
             thật thì nên báo <c>Failed</c> để Hangfire thử lại, còn hết hạn mức thì thử lại là
             <b>đốt thêm hạn mức đang cạn</b> — Hangfire thử tới 10 lần. Phải dừng êm.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult.Truncated">
            <summary>
            Có mức nào chạm trần phân trang mà vẫn còn dòng chưa lấy không. Dữ liệu bị cắt cụt mà
            <b>không</b> báo gì là cách hỏng tệ nhất của một bảng số liệu: nó trông vẫn đầy đủ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult.SiteDays">
            <summary>Số ngày khác nhau có ít nhất một dòng ở mức toàn site.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchAnalyticsService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsService.ActionName">
             <summary>
             Tên việc ghi vào <c>SearchEngineApiLog</c> cho <b>mọi</b> lời gọi đọc số liệu — cả job
             hằng ngày lẫn lượt kéo bù.
            
             <para>
             <b>Phải khác <c>SearchIndexInspectJob.ActionName</c>.</b> Cột <c>Action</c> của bảng nhật
             ký chính là sổ đếm hạn mức dùng chung (<c>ISearchApiLogger.CountTodayAsync</c>), và hạn
             mức kiểm URL <c>Search.Google.InspectDailyBudget</c> đếm theo đúng tên ấy. Đặt trùng tên
             thì một lượt kéo bù 16 tháng sẽ ăn hết hạn mức kiểm URL của ngày hôm đó, và trang dashboard
             sẽ báo "đã dùng 51/300 lượt kiểm" trong khi chưa kiểm URL nào.
             </para>
             <para>
             <b>Ngược lại, job hằng ngày và lượt kéo bù cố ý dùng CHUNG một tên.</b> Chúng tiêu cùng một
             hạn mức thật của Google, nên tách tên sẽ làm con số đọc ra thấp hơn mức thật.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsService.MaxPagesPerLevel">
            <summary>
            Trần số trang phân trang cho <b>một</b> mức trong <b>một</b> khoảng ngày. Đây là dây an
            toàn chống vòng lặp vô tận, không phải một giới hạn nghiệp vụ: đo 2026-09-16 thì lô 30 ngày
            nhiều dòng nhất (05/2025) trả 13.657 dòng — chưa tới một trang. 20 trang = 500.000 dòng.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsService.LevelDimensions">
             <summary>
             Bốn mức và các chiều tương ứng, theo đúng chữ của Google.
            
             <para>
             <b>Chiều <c>date</c> đứng đầu ở cả bốn</b> — nhờ vậy một lời gọi phủ trọn khoảng ngày mà
             vẫn giữ độ mịn theo ngày. Đối chứng 2026-09-16: <c>date+page</c> cho một ngày trả đúng
             bằng số dòng của lời gọi chỉ có <c>page</c> cho ngày ấy (117 = 117).
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsService.PullLevelAsync(Lada.Framework.Data.Enums.SearchEngine,Lada.Framework.Data.Enums.SearchMetricLevel,System.String[],System.DateOnly,System.DateOnly,System.Int32,Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult,System.Threading.CancellationToken)">
            <summary>
            Kéo một mức. Trả <c>null</c> khi chạy xong bình thường; trả kết quả đã đánh dấu khi bị chặn
            hoặc gặp lỗi để chỗ gọi dừng hẳn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsService.UpsertAsync(Lada.Framework.Data.Enums.SearchEngine,Lada.Framework.Data.Enums.SearchMetricLevel,System.String[],System.DateOnly,System.DateOnly,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsRow},System.Int32,Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsPullResult,System.Threading.CancellationToken)">
             <summary>
             Ghi đè-hoặc-chèn các dòng của một mức trong một khoảng ngày.
            
             <para>
             <b>Chỉ ghi đè, không xoá dòng cũ không còn thấy.</b> Google lọc bớt truy vấn quá hiếm để
             giữ ẩn danh, nên một dòng có mặt hôm qua mà vắng hôm nay chưa chắc đã là "số ấy không còn
             đúng" — nó có thể chỉ rơi xuống dưới ngưỡng ẩn danh của Google. Xoá đi là đổi một con số
             đúng lấy một khoảng trống.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsService.TinhPositionWeighted(Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsRow)">
            <summary>
            Vị trí × lượt hiển thị. Quy về <see cref="T:System.Decimal"/> ở đúng một chỗ để mọi dòng làm tròn
            giống nhau.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsService.TinhDimensionHash(System.String,System.String)">
             <summary>
             Băm cặp chiều thành khoá duy nhất.
            
             <para>
             <b>Băm trên chuỗi GỐC, không phải chuỗi đã chuẩn hoá.</b> Đo 2026-09-16: 31/239 URL Google
             trả về mang neo <c>#…</c> và chúng thuộc chỉ 9 trang gốc — băm sau khi bỏ neo sẽ làm 38
             dòng đè lên nhau, và con số đè sau thắng chứ không phải cộng lại. Mất số im lặng.
             </para>
             <para>
             Ký tự <c>'\n'</c> ngăn giữa hai chiều để cặp (<c>"a"</c>, <c>"b"</c>) không băm ra cùng giá
             trị với (<c>"ab"</c>, <c>null</c>). Dùng <c>\n</c> vì URL và truy vấn đều không chứa nó.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchAnalyticsService.CatTruyVan(System.String)">
            <summary>Cắt truy vấn cho vừa cột. Truy vấn dài hơn 500 ký tự gần như chắc chắn là rác.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchMetricUrl">
             <summary>
             Luật chuẩn hoá URL của miền số liệu tìm kiếm — <b>đúng một bản</b>, dùng chung cho cả chỗ ghi
             lẫn chỗ đọc.
            
             <para>
             Tách ra thành lớp tĩnh riêng vì bài học của giai đoạn trước: hai nơi cùng nói về một URL mà
             mỗi nơi tự chuẩn hoá theo cách của mình thì chúng sẽ không bao giờ khớp, và triệu chứng là một
             bảng trống chứ không phải một lỗi. Chỗ ghi dựng cột <c>UrlNormalized</c> bằng hàm này; chỗ đọc
             nối sang <c>SearchUrl</c> cũng phải bằng đúng hàm này.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchMetricUrl.MaxLength">
            <summary>Trần độ dài của cột <c>Url</c> và <c>UrlNormalized</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchMetricUrl.ChuanHoa(System.String)">
             <summary>
             Bỏ neo <c>#…</c> và dấu <c>/</c> ở cuối.
            
             <para>
             <b>Chỉ hai phép ấy, cố ý không làm gì hơn.</b> Không hạ chữ thường (đường dẫn phân biệt
             hoa thường trên máy chủ này), không giải mã phần trăm (đo 2026-09-16 thấy có URL như
             <c>/bang-gia-gui-xe-m%E1%BA%A3i-…</c> — một slug gõ nhầm dấu; giải mã nó ra là đổi danh
             tính của một trang), không bỏ <c>www.</c> (property này không có URL <c>www.</c> nào).
             Mỗi phép thêm vào là một cách nữa để hai URL khác nhau bị gộp thành một.
             </para>
             <para>
             Neo là phần Google thêm khi kết quả có mục "nhảy tới phần" — đo 2026-09-16: 31 dòng thuộc
             9 trang gốc. Giữ neo trong <c>Url</c> (đó là sự thật Google báo) nhưng gộp theo bản không
             neo, vì người đọc hỏi "trang này có bao nhiêu lượt bấm" chứ không hỏi từng mục lục.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchMetricUrl.CatTheoCot(System.String)">
            <summary>Cắt cho vừa cột. URL dài nhất đo được là 176 ký tự nên đây là dây an toàn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchApiLogger">
             <summary>
             Ghi nhật ký lời gọi ra công cụ tìm kiếm — gồm cả lượt chạy thử không gửi đi thật.
            
             <para>
             Gom về một lớp vì ba job đều phải ghi giống nhau, và vì đây là chỗ duy nhất biết luật cắt ngắn:
             nhật ký không bao giờ được chứa token, khoá, hay một thân phản hồi dài vô hạn.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchApiLogger.Add(Lada.Framework.Data.Enums.SearchEngine,System.String,System.String,System.Boolean,System.Nullable{System.Int32},System.String,System.String,System.Int64,System.String,System.String)">
            <summary>Ghi một dòng nhật ký. Không tự lưu — chỗ gọi quyết định khi nào lưu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchApiLogger.CountTodayAsync(Lada.Framework.Data.Enums.SearchEngine,System.String,System.Threading.CancellationToken)">
            <summary>
            Đếm số lượt gọi của một việc trong ngày hôm nay — cơ sở để dừng ở hạn mức.
            Chỉ đếm lượt <b>đã đi ra ngoài</b>: lượt chạy thử không tốn hạn mức nào.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchApiLogger">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchApiLogger"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchApiLogger.MaxSummaryLength">
            <summary>Trần độ dài phần tóm tắt request/response lưu vào nhật ký.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleActionService">
             <summary>
             Ba nút bấm tay của dashboard đồng bộ công cụ tìm kiếm — đây là <b>đường duy nhất</b> mà một
             người dùng có thể làm phát sinh lời gọi ra Google.
            
             <para>
             <b>Vì sao tách hẳn khỏi service đọc dashboard.</b> Service đọc chỉ chạm 5 bảng đã có sẵn và
             không bao giờ gọi ra ngoài; ba hàm ở đây thì có. Nhìn danh sách DI là biết ngay cái nào tiêu
             hạn mức, cái nào không — và mọi ràng buộc an toàn (công tắc, hàng tồn kho, sổ hạn mức) chỉ phải
             canh ở đúng một lớp.
             </para>
            
             <para>
             <b>Bấm tay tiêu hạn mức y hệt job.</b> Không có sổ đếm riêng, không có đường gọi riêng: cả job
             lẫn nút bấm đều đếm trên cùng một bảng <c>SearchEngineApiLog</c> với cùng tên việc
             <see cref="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchIndexInspectJob.ActionName"/>. Dựng sổ thứ hai là cách chắc chắn nhất để hai
             bên cùng tưởng mình còn hạn mức rồi cùng vượt trần của Google.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleActionService.InspectNowAsync(System.String,System.Threading.CancellationToken)">
            <summary>
            Kiểm ngay trạng thái index của <b>một</b> URL đã có trong hàng tồn kho.
            URL lạ bị từ chối trước khi có bất kỳ lời gọi nào đi ra.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleActionService.SubmitSitemapNowAsync(System.Threading.CancellationToken)">
            <summary>
            Nộp lại tệp sitemap đang cấu hình. <b>Không nhận tham số</b> — địa chỉ tệp luôn lấy từ
            <c>Search.Google.SitemapUrl</c>, để không ai nộp hộ Google một tệp của miền khác.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleActionService.TestConnectionAsync(System.Threading.CancellationToken)">
            <summary>
            Thử kết nối bằng một lời gọi đọc nhẹ nhất, để người vận hành biết khoá và quyền đã đúng chưa.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleActionService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleActionService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleActionService.InspectEndpoint">
            <summary>
            Endpoint ghi vào nhật ký cho lượt kiểm URL — <b>giữ đúng chuỗi mà</b>
            <see cref="T:Ladaer.BackEnd.Infrastructures.Jobs.SearchIndexInspectJob"/> <b>đang ghi</b>, để lọc nhật ký theo endpoint là ra cả
            lượt tự động lẫn lượt bấm tay.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleActionService.ManualSummary">
             <summary>
             Câu đánh dấu lượt bấm tay trong nhật ký.
            
             <para>
             Tên việc (<c>Action</c>) bắt buộc phải giống job vì nó là khoá của sổ đếm hạn mức; nếu đánh
             dấu lượt bấm tay bằng một tên việc mới thì nó không còn bị trừ vào hạn mức nữa. Nên chỗ để
             phân biệt "ai gây ra lời gọi này" là phần tóm tắt, không phải tên việc.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleActionService.InspectNowAsync(System.String,System.Threading.CancellationToken)">
            <summary>
            Kiểm ngay một URL rồi trả về đúng dòng mà bảng chính đang hiển thị, để giao diện thay dòng
            tại chỗ thay vì nạp lại cả trang.
            </summary>
            <remarks>
            <para>
            <b>Bốn cửa phải qua trước khi có lời gọi nào đi ra</b>, theo đúng thứ tự rẻ tiền trước:
            (1) URL không rỗng; (2) công tắc đọc đang bật; (3) URL <b>có thật trong bảng</b>
            <c>SearchUrl</c>; (4) hạn mức hôm nay còn chỗ. Cửa thứ ba làm hai việc cùng lúc: nó chặn
            SSRF (không ai gửi được một địa chỉ tự do cho máy chủ gọi hộ) và chặn đường đốt hạn mức
            (danh sách kiểm được là hữu hạn và do chính website sinh ra, không do người bấm gõ vào).
            </para>
            <para>
            <b>Không lọc theo <c>InSitemap</c></b> dù job có lọc: một URL vừa rơi khỏi sitemap chính là
            URL người vận hành cần kiểm tay nhất — để biết Google đã bỏ nó ra chưa. Job thì khác, job
            chia hạn mức cho hàng trăm URL nên phải ưu tiên những trang còn đang phục vụ.
            </para>
            <para>
            <b>Trả số hạn mức trong mọi nhánh</b>, kể cả nhánh từ chối: người bấm phải thấy ngay còn
            bao nhiêu lượt, nếu không họ sẽ bấm lại vài lần nữa để thử.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleActionService.ApplyStatusAsync(Lada.Framework.Data.Domains.SearchEngines.SearchUrl,Ladaer.BackEnd.Infrastructures.Services.SearchEngines.UrlInspectionResult,System.Threading.CancellationToken)">
            <summary>
            Ghi đè trạng thái index hiện tại và ghi thêm một dòng lịch sử <b>chỉ khi</b>
            <c>CoverageState</c> hoặc <c>Verdict</c> đổi.
            </summary>
            <remarks>
            <b>Cố ý lặp lại nguyên luật của</b> <c>SearchIndexInspectJob.ApplyStatus</c>: một lượt bấm
            tay và một lượt tự động phải để lại dữ liệu giống hệt nhau, nếu không thì đường xu hướng
            dựng từ <c>SearchIndexStatusHistory</c> sẽ gãy đúng ở chỗ có người bấm tay. Luật ấy đang nằm
            trong một hàm <c>private</c> của job nên không gọi lại được — sửa một bên thì phải sửa cả
            hai bên.
            </remarks>
            <returns><c>true</c> nếu trạng thái vừa đổi.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleActionService.SubmitSitemapNowAsync(System.Threading.CancellationToken)">
            <summary>Nộp lại tệp sitemap đang cấu hình và đóng mốc "lần nộp gần nhất".</summary>
            <remarks>
            <para>
            <b>Không nhận tham số là một ràng buộc an toàn, không phải sự tiện tay.</b> Nhận địa chỉ tệp
            từ người bấm nghĩa là cho phép nộp một tệp bất kỳ dưới danh nghĩa property của LADA — Google
            sẽ đi tải đúng địa chỉ đó. Địa chỉ tệp chỉ đổi được bằng cách sửa khoá <c>AppConfig</c>,
            tức là qua một migration.
            </para>
            <para>
            <b>Từ chối khi công tắc ghi còn tắt.</b> Client cũng tự canh công tắc, nhưng chặn ngay từ
            đây thì người bấm nhận được đúng câu giải thích (<c>BlockReason</c>) thay vì một lỗi kỹ thuật.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleActionService.RefreshSitemapStatusAsync(System.String,System.Threading.CancellationToken)">
            <summary>
            Hỏi Google trạng thái tệp sitemap rồi ghi đè dòng trạng thái — cùng việc mà
            <see cref="T:Ladaer.BackEnd.Infrastructures.Jobs.SearchSitemapSubmitJob"/> làm ở đầu mỗi lượt chạy.
            </summary>
            <remarks>
            <b>Lỗi ở đây không làm hỏng lượt nộp.</b> Tệp đã nộp xong rồi; đọc lại chỉ để màn hình có
            số thật. Đọc không được thì dòng trạng thái giữ <c>RawJson</c> rỗng, và màn hình sẽ nói
            "chưa đọc được trạng thái từ Google" thay vì in số 0 như thể đã đo.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleActionService.StampSubmittedAsync(System.String,System.Threading.CancellationToken)">
            <summary>
            Đóng mốc "LADA vừa nộp" lên dòng trạng thái tệp sitemap — giống hệt việc
            <see cref="T:Ladaer.BackEnd.Infrastructures.Jobs.SearchSitemapSubmitJob"/> làm sau một lượt nộp thành công.
            </summary>
            <remarks>
            Thiếu bước này thì màn hình vẫn hiện mốc nộp cũ ngay sau khi vừa bấm nộp, và người vận hành
            sẽ bấm lại lần nữa vì tưởng lần đầu không ăn.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleActionService.TestConnectionAsync(System.Threading.CancellationToken)">
            <summary>Thử kết nối tới công cụ tìm kiếm và ghi lại kết quả vào nhật ký lời gọi.</summary>
            <remarks>
            <para>
            <b>Chặn trước bằng công tắc đọc</b> để không ghi một dòng nhật ký cho lời gọi chưa hề đi ra:
            client cũng trả về <c>BlockReason</c> trong trường hợp này, nhưng từ ngoài nhìn vào thì
            "bị công tắc chặn" và "gọi rồi nhưng hỏng" giống nhau, mà sổ nhật ký phải phân biệt được.
            </para>
            <para>
            <b>Ghi dưới tên việc</b> <see cref="F:Ladaer.BackEnd.Infrastructures.Jobs.SearchSitemapSubmitJob.GetActionName"/> chứ không phải
            một tên mới: lời gọi này đúng là một lượt đọc danh sách sitemap. Quan trọng hơn, nó
            <b>không</b> được ghi dưới tên việc kiểm URL, vì như vậy mỗi lần thử kết nối lại ăn mất một
            suất trong hạn mức kiểm URL của ngày hôm đó.
            </para>
            <para>
            Dòng nhật ký không có mã HTTP và thời gian gọi: <c>TestConnectionAsync</c> cố ý chỉ trả
            được/không được kèm lý do, vì câu trả lời của nó hiện thẳng lên giao diện quản trị và không
            được để lộ chi tiết của khoá hay của service account.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleActionService.FillQuotaAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchInspectNowResult,Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings,System.Threading.CancellationToken)">
            <summary>Đếm lại sổ hạn mức rồi điền vào kết quả.</summary>
            <remarks>
            Đếm lại sau khi lưu chứ không cộng thêm 1 vào số đã đọc: job theo lịch có thể đang chạy song
            song và cũng đang tiêu vào cùng sổ ấy, nên con số duy nhất đáng tin là con số vừa đọc từ DB.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleActionService.SetQuota(Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchInspectNowResult,Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings,System.Int32)">
            <summary>Điền số hạn mức đã biết, kẹp phần còn lại về tối thiểu 0 để giao diện không hiện số âm.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleActionService.Cut(System.String,System.Int32)">
            <summary>Cắt một chuỗi về đúng độ dài cột; <c>null</c> giữ nguyên là <c>null</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleDashboardService">
             <summary>
             Đọc số cho dashboard đồng bộ công cụ tìm kiếm.
            
             <para>
             <b>Chỉ đọc.</b> Mọi con số ở đây lấy từ 5 bảng đã có sẵn trong DB, không lời gọi nào đi ra
             ngoài — tách hẳn khỏi service nút-bấm-tay để nhìn danh sách phụ thuộc là biết ngay cái nào có
             thể tiêu hạn mức của Google.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleDashboardService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>Bảng chính: một dòng cho mỗi URL trong hàng tồn kho kèm trạng thái index.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleDashboardService.GetSummaryAsync(Lada.Framework.Data.Enums.SearchEngine)">
            <summary>Các con số tổng, bảng đếm theo nhóm và tình trạng công tắc/hạn mức.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleDashboardService.GetSitemapStatusAsync(Lada.Framework.Data.Enums.SearchEngine)">
            <summary>Trạng thái tệp sitemap; trả <c>HasData = false</c> khi chưa đo lần nào.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleDashboardService.GetApiLogsAsync(Lada.Framework.Data.Enums.SearchEngine,System.Int32)">
            <summary>Những lời gọi gần nhất đã đi ra công cụ tìm kiếm, mới nhất trước.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleDashboardService.GetItemAsync(System.Guid,Lada.Framework.Data.Enums.SearchEngine)">
            <summary>
            Một dòng của bảng chính theo khoá <c>SearchUrl</c> — dùng để trả trạng thái mới ngay sau
            một lượt "kiểm ngay", bằng đúng phép chiếu của bảng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleDashboardService"/>
            <remarks>
            <para>
            <b>Dùng thẳng <c>LadaDbContext</c> chứ không qua <c>IRepository</c>.</b> Mọi câu hỏi của màn
            hình này đều là phép nối <c>SearchUrl</c> với <c>SearchIndexStatus</c> — một bảng trung lập với
            công cụ tìm kiếm nối với một bảng theo từng công cụ. Không có entity nào là "chủ" của dòng kết
            quả, nên repository theo một entity chỉ thêm một lớp trung gian mà không che giấu được gì.
            Cùng lý do với <c>SearchIndexInspectJob</c>.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.VerdictPass">
            <summary>Kết luận "đã lập chỉ mục" của Google — mã ổn định duy nhất được phép dùng để đếm.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.RedirectWordVi">
            <summary>
            Cách Google diễn đạt "trang có lệnh chuyển hướng" trong <c>CoverageState</c> — bản tiếng
            Việt, là thứ property của LADA đang trả về (đo thật 2026-09-15).
            </summary>
            <remarks>
            <b>Đây là phép dò theo chuỗi, và phải biết là mình đang làm thế.</b> <c>urlInspection</c>
            không có trường riêng nào cho việc này; <c>CoverageState</c> là câu hiển thị trên giao diện
            Search Console nên nó đổi theo ngôn ngữ của property và Google có thể đổi cách diễn đạt mà
            không báo trước. Giữ cụm ngắn nhất còn mang nghĩa để cách diễn đạt đổi vài chữ vẫn khớp.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.RedirectWordEn">
            <summary>Cụm tương ứng khi property đổi sang tiếng Anh ("Page with redirect").</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.DefaultApiLogTake">
            <summary>Số dòng nhật ký trả về khi chỗ gọi không nói rõ.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.MaxApiLogTake">
            <summary>Trần số dòng nhật ký một lượt — bảng nhật ký để soi vài chục dòng gần nhất, không phải để tải cả sổ.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.SortableFields">
             <summary>
             Những cột được phép sắp xếp.
            
             <para>
             <b>Phải là danh sách trắng, không phải kiểm tra qua loa.</b> <c>ToSmartTableResultAsync</c>
             sắp xếp bằng <c>OrderByName</c> — phản chiếu theo tên property, <b>phân biệt hoa thường</b>,
             và ném <c>ArgumentException</c> khi không tìm thấy. Một khoá sort lạ (hay chỉ sai một chữ
             hoa) từ giao diện sẽ thành lỗi 500. Nguy hiểm hơn: <c>GroupName</c>, <c>Clicks</c>,
             <c>Impressions</c> <b>có</b> tồn tại trên DTO nhưng không nằm trong phép chiếu SQL, nên
             phản chiếu tìm thấy chúng rồi EF mới vỡ lúc chạy. Khoá ngoài danh sách được đưa về sắp
             mặc định.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <inheritdoc />
            <remarks>
            <para>
            <b>Cố ý không đi qua AutoMapper <c>.ToItem()</c></b> như quy ước chung của tầng service
            (skill <c>service-search-patterns</c> §2). Một dòng ở đây là phép LEFT JOIN hai bảng chứ
            không phải một entity, nên không có <c>Entity → Item</c> nào để ánh xạ. Quan trọng hơn:
            <c>ToSmartTableResultAsync</c> sắp xếp bằng <c>OrderByName</c> trên chính kiểu đang truy
            vấn, nên khoá sắp xếp mặc định <c>ChangedNotRecrawled</c> — vốn là một biểu thức, không
            phải cột — chỉ tồn tại nếu phép chiếu ra <c>SearchUrlStatusItem</c> xảy ra <b>trước</b> lúc
            sắp xếp, tức là ngay trong <c>IQueryable</c>. Ánh xạ sau khi lấy dữ liệu về thì cột đó
            không có gì để sắp.
            </para>
            <para>
            Bộ lọc cũng đặt trên phép chiếu chứ không trên hai bảng gốc, để công thức
            <c>ChangedNotRecrawled</c> chỉ được viết đúng <b>một</b> lần: viết lại nó ở tầng lọc là mở
            đường cho con số trong bảng lệch với con số trên thẻ tổng.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.PhanTrangAsync(System.Linq.IQueryable{Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem},Lada.Framework.DTO.SmartTable.SmartTableParam,System.String,System.Boolean)">
            <summary>
            Đếm, sắp xếp và cắt trang — có <b>khoá phụ cố định</b> là <c>Url</c>.
            </summary>
            <remarks>
            <para>
            <b>Vì sao không dùng thẳng</b> <c>ToSmartTableResultAsync</c>: nó sắp xếp bằng đúng một khoá
            rồi <c>OFFSET/FETCH</c> từng trang. Khoá mặc định ở đây là một cờ <c>bool</c>, nên trên 148
            dòng thì khoảng 138 dòng có khoá <b>bằng nhau</b> — SQL Server không hứa thứ tự giữa những
            dòng bằng khoá, và mỗi trang là một lượt sắp xếp riêng. Hậu quả: một URL có thể hiện ở cả
            trang 3 lẫn trang 4, hoặc không hiện ở trang nào, trong khi tổng số vẫn báo đủ. Người vận
            hành lật trang tìm một URL có thể không bao giờ thấy nó.
            </para>
            <para>
            <c>Url</c> là khoá phụ đúng nghĩa: nó có ràng buộc duy nhất trên bảng nên mọi dòng đều tách
            được, và nó cũng là thứ người đọc dùng để định vị. Cùng một luật mà
            <c>SearchNotIndexedProvider</c> đã áp cho widget.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.SapXep(System.Linq.IQueryable{Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem},System.String,System.Boolean)">
            <summary>
            Sắp xếp theo tên cột đã qua danh sách trắng.
            </summary>
            <remarks>
            Viết tay từng nhánh thay vì phản chiếu theo tên: mọi cột sắp được đều phải là cột <b>có
            thật trong phép chiếu SQL</b>. Phản chiếu thì <c>GroupName</c>, <c>Clicks</c>,
            <c>Impressions</c> — những property chỉ tồn tại trên DTO — vẫn tìm thấy được, rồi vỡ lúc
            chạy chứ không phải lúc dịch.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.GetSummaryAsync(Lada.Framework.Data.Enums.SearchEngine)">
            <inheritdoc />
            <remarks>
            <para>
            <b>Đếm trong bộ nhớ trên chính phép chiếu của bảng</b>, thay vì viết một loạt câu
            <c>COUNT</c> riêng. Lý do là tính nhất quán: con số trên thẻ tổng và con số người dùng đếm
            được khi bấm lọc trong bảng phải luôn bằng nhau, mà cách chắc chắn nhất để chúng bằng nhau
            là chúng dùng đúng một công thức. Hàng tồn kho cỡ 150 dòng (đo 15/09/2026) nên một lượt đi
            DB rẻ hơn chín lượt <c>COUNT</c>; nếu về sau vượt vài chục nghìn dòng thì chuyển phần này
            sang <c>GROUP BY</c> phía SQL.
            </para>
            <para>
            <b>Đếm theo <c>Verdict</c>, không đếm theo <c>CoverageState</c>.</b> <c>CoverageState</c> là
            câu Google viết theo ngôn ngữ của property ("Đã được gửi và lập chỉ mục"); đổi ngôn ngữ là
            mọi con số đếm theo nó vỡ im lặng. <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchConsoleSummaryModel.ByCoverageState"/>
            vẫn có mặt nhưng chỉ để trả lời "vì sao" và để người dùng bấm lọc theo đúng câu chữ họ nhìn
            thấy trong Search Console.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.GetSitemapStatusAsync(Lada.Framework.Data.Enums.SearchEngine)">
            <inheritdoc />
            <remarks>
            <para>
            <b>Chưa đo lần nào là trạng thái hợp lệ, không phải lỗi</b> — bảng <c>SearchSitemapStatus</c>
            đang rỗng trên dev vì job đọc sitemap chưa chạy lần nào ngoài test. Khi đó vẫn trả
            <c>SitemapUrl</c> đọc từ cấu hình kèm <c>HasData = false</c>: màn hình nói được "đang theo
            dõi tệp nào, chưa đo" thay vì bày ra 0 lỗi / 0 cảnh báo như thể đã đo và mọi thứ đều tốt.
            </para>
            <para>
            Bản ghi được lọc theo đúng tệp đang cấu hình. Đổi <c>Search.Google.SitemapUrl</c> sang tệp
            khác thì số đo của tệp cũ không còn nói gì về tệp mới, nên thà trả "chưa đo" còn hơn trả
            một con số đúng của một câu hỏi khác.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.GetApiLogsAsync(Lada.Framework.Data.Enums.SearchEngine,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.GetItemAsync(System.Guid,Lada.Framework.Data.Enums.SearchEngine)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.BuildQuery(Lada.Framework.Data.Enums.SearchEngine)">
             <summary>
             Phép chiếu dùng chung của cả màn hình: LEFT JOIN hàng tồn kho với trạng thái index của một
             công cụ tìm kiếm, ra thẳng <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem"/>.
            
             <para>
             <b>Phải là LEFT JOIN.</b> URL chưa từng được kiểm vẫn phải xuất hiện — "không biết gì về
             trang này" là tình trạng đáng lo hơn "biết là chưa index", và INNER JOIN sẽ giấu đúng nhóm
             đó đi.
             </para>
            
             <para>
             <b>URL đã rơi khỏi sitemap vẫn hiện.</b> Bộ lọc chỉ bỏ dòng xoá mềm, không bỏ dòng
             <c>InSitemap = false</c>: một trang biến mất khỏi sitemap có thể là cố ý, cũng có thể là lỗi
             sinh sitemap (sự cố 15/09/2026 mất 13 URL danh mục) — giấu nó đi là bỏ mất đúng loại sự cố
             mà bảng này sinh ra để phát hiện.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.StampRedirectFlags(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem})">
            <summary>
            Điền hai cờ đối chiếu ghép — chúng cần đọc hai cờ gốc nên không tính được trong phép chiếu.
            </summary>
            <remarks>
            <see cref="P:Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem.RedirectWithoutRule"/> giữ <c>null</c> khi chưa hỏi Google về
            URL đó: "chưa biết Google nghĩ gì" không được phép trông giống "đã kiểm và không có vấn đề".
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.ApplyStatusFilter(System.Linq.IQueryable{Ladaer.BackEnd.Infrastructures.DTO.Models.SearchEngines.SearchUrlStatusItem},System.String)">
             <summary>
             Lọc theo nhóm tình trạng mà người dùng bấm trên đầu bảng.
            
             <para>
             Mọi vế đều dựa trên <c>Verdict</c> — mã ổn định — chứ không dựa trên <c>CoverageState</c>.
             Riêng "error" gom cả <c>Verdict = FAIL</c> lẫn các <c>PageFetchState</c> chứa <c>ERROR</c>
             (<c>SERVER_ERROR</c>, <c>INTERNAL_ERROR</c>...): với người vận hành thì "trang lỗi" là một
             nhóm việc phải sửa, còn việc lỗi nằm ở kết luận tổng hay ở lượt tải trang là chi tiết kỹ
             thuật họ không cần phân biệt để bắt đầu.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.ResolveSortField(System.String)">
            <summary>
            Đưa khoá sắp xếp của giao diện về đúng tên property trong danh sách trắng;
            <c>null</c> nghĩa là "dùng sắp xếp mặc định".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchConsoleDashboardService.ResolveEngine(System.Int32)">
             <summary>
             Ép mã công cụ tìm kiếm về một giá trị có thật.
            
             <para>
             Mã lạ rơi về Google thay vì ném lỗi: giao diện chỉ có Google để chọn, nên một giá trị lạ là
             lỗi gõ chứ không phải ý định — và trả về bảng rỗng của một công cụ không tồn tại thì khó
             hiểu hơn nhiều so với trả về đúng thứ người dùng đang xem.
             </para>
             </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.UrlInspectionResult">
            <summary>
            Kết quả một lượt kiểm URL, đã rút từ phản hồi của công cụ tìm kiếm về đúng những trường
            bảng <c>SearchIndexStatus</c> cần.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.UrlInspectionResult.InSitemapPerEngine">
            <summary>Công cụ tìm kiếm có thấy URL này trong tệp sitemap đang theo dõi hay không.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.UrlInspectionResult.RawJson">
            <summary>Phản hồi thô, đã cắt ngắn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SitemapStatusResult">
            <summary>
            Trạng thái một tệp sitemap theo lời công cụ tìm kiếm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SitemapStatusResult.LastSubmitted">
            <summary>Mốc nộp gần nhất theo ghi nhận của công cụ tìm kiếm — bất kể ai nộp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SitemapStatusResult.LastDownloaded">
            <summary>Lần công cụ tìm kiếm thật sự tải tệp về đọc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SitemapStatusResult.UrlCountSubmitted">
            <summary>Số URL công cụ tìm kiếm đếm được trong tệp.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchApiResult`1">
            <summary>
            Kết quả một lời gọi ra công cụ tìm kiếm: dữ liệu, mã HTTP và thời gian — ba thứ cần để vừa
            dùng kết quả vừa ghi nhật ký mà không phải gọi hai lần.
            </summary>
            <typeparam name="T">Kiểu dữ liệu trả về khi thành công.</typeparam>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchApiResult`1.WasBlocked">
            <summary>
            Lời gọi bị chặn bởi công tắc nên <b>chưa hề đi ra ngoài</b>. Khác hẳn thất bại: không tốn
            hạn mức, không phải lỗi, và là trạng thái bình thường cho tới khi người vận hành bật công tắc.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchQuotaExceededException">
             <summary>
             Công cụ tìm kiếm trả 429 — hạn mức đã hết.
            
             <para>
             <b>Vì sao là một ngoại lệ riêng chứ không phải một mã lỗi trong kết quả.</b> Mọi lỗi khác chỉ
             làm hỏng đúng một URL và job nên đi tiếp; 429 làm hỏng mọi URL còn lại, nên job phải dừng hẳn
             vòng lặp. Kiểu riêng buộc chỗ gọi phải xử lý khác đi, thay vì trông chờ ai đó nhớ so mã 429.
             </para>
             </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventorySyncResult">
            <summary>
            Kết quả một lượt dựng lại hàng tồn kho URL.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventorySyncResult.UrlsInSitemap">
            <summary>Số URL đọc được từ tệp sitemap (sau khi bỏ trùng).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventorySyncResult.Added">
            <summary>Số dòng URL mới thêm.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventorySyncResult.Updated">
            <summary>Số dòng được cập nhật (mốc sitemap, nhóm, liên kết nội dung).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventorySyncResult.Removed">
            <summary>Số URL vừa rơi khỏi sitemap ở lượt này.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventorySyncResult.Restored">
            <summary>Số URL đã từng rơi khỏi sitemap và nay quay lại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventorySyncResult.DuplicatesInSitemap">
            <summary>Số URL trùng nhau trong chính tệp sitemap — lớn hơn 0 là một lỗi cần sửa.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventorySyncResult.Unmatched">
            <summary>Số URL không khớp được với bản ghi nội dung nào.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchInventoryService">
            <summary>
            Dựng lại hàng tồn kho URL từ chính tệp <c>sitemap.xml</c> mà công cụ tìm kiếm đọc.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchInventoryService.SyncAsync(System.String,System.Threading.CancellationToken)">
            <summary>Tải sitemap, đối chiếu với bảng <c>SearchUrl</c> rồi ghi lại chênh lệch.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventoryService">
             <summary>
             Cài đặt <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchInventoryService"/>.
            
             <para>
             <b>Nguồn là tệp sitemap công khai, không phải database.</b> Việc này không gọi tới công cụ tìm
             kiếm nào nên chạy được cả khi mọi công tắc còn tắt — và đó là chủ ý: hàng tồn kho phải dựng
             xong, đọc được, đối chiếu được bằng mắt <b>trước</b> khi có lời gọi đầu tiên đi ra ngoài.
             </para>
            
             <para>
             <b>Vì sao khớp ngược về <c>UrlRecord</c> bằng slug.</b> Phần lớn URL của website là slug một đoạn
             (<c>/gui-hang-lien-tinh</c>) nên không suy ra được loại nội dung từ hình dạng đường dẫn. Khớp
             slug cho cả ba thứ cùng lúc: nhóm để thống kê, khoá thực thể để mở màn sửa, và khoá
             <c>UrlRecord</c> để nối sang mốc <c>ContentChangedAt</c> của giai đoạn trước.
             </para>
            
             <para>
             <b>URL biến mất không bị xoá</b> mà được đánh <c>RemovedAt</c>. Một trang rơi khỏi sitemap có
             thể là cố ý, cũng có thể là hỏng — sự cố 15/09/2026 làm 13 URL danh mục biến mất vì DB thiếu một
             cột. Xoá dòng đi là mất luôn dấu vết của đúng loại sự cố mà bảng này sinh ra để phát hiện.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventoryService.HttpClientName">
            <summary>Tên named client dùng để tải sitemap — tách khỏi client gọi Google.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventoryService.ParseSitemap(System.String,System.Int32@)">
            <summary>
            Đọc tệp sitemap thành danh sách URL. URL trùng chỉ lấy bản đầu — bảng
            <c>SearchUrl</c> có chỉ số duy nhất nên trùng sẽ làm hỏng cả lượt ghi, mà đó lại đúng là
            tình trạng sitemap production đang có (3 URL trùng, tính tới 15/09/2026).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventoryService.MaxUrlLength">
            <summary>Độ dài tối đa của cột <c>SearchUrl.Url</c> và <c>SearchUrl.Path</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventoryService.ExtractOrigin(System.String)">
            <summary>Gốc của một URL: scheme + host + cổng, hoặc chuỗi rỗng nếu không phân giải được.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventoryService.IsSameOrigin(System.String,System.String)">
            <summary>
            URL có cùng gốc với tệp sitemap không. Gốc rỗng (không phân giải được địa chỉ sitemap) thì
            coi như không xét URL nào — thà bỏ sót một URL đã rơi còn hơn đánh dấu nhầm cả bảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventoryService.ParsePriority(System.String)">
            <summary>
            Đọc <c>priority</c> bằng <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>. Bắt buộc: máy chạy
            culture Việt đọc "0.8" theo culture máy sẽ ra 8 — đúng loại bẫy đã cắn ở giai đoạn trước,
            chỉ khác chiều (ở đó là chỗ ghi).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventoryService.BuildMatcherAsync(System.Threading.CancellationToken)">
            <summary>
            Dựng bảng tra từ slug về bản ghi nội dung. Nạp một lần cho cả lượt: mỗi URL tra riêng sẽ là
            hơn 150 lượt truy vấn cho một việc chạy đêm.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchInventoryService.SlugMatcher">
            <summary>
            Khớp một đường dẫn về bản ghi nội dung đứng sau nó.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchPerformanceService">
             <summary>
             Đọc số liệu hiệu suất tìm kiếm cho màn hình. <b>Không gọi ra Google lần nào</b> — mọi con số ở
             đây đã nằm sẵn trong <c>SearchMetricDaily</c>.
            
             <para>
             Tách khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchConsoleDashboardService"/> (đọc trạng thái index) vì hai thứ trả
             lời hai câu hỏi khác nhau — "Google đã thấy trang của mình chưa" và "người ta có bấm vào không"
             — và vì từ danh sách DI phải thấy ngay lớp nào có thể phát sinh lời gọi ra ngoài.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchPerformanceService.GetSummaryAsync(Lada.Framework.Data.Enums.SearchEngine,System.Int32,System.Threading.CancellationToken)">
            <summary>Các con số tổng hợp đầu tab, kèm câu trả lời cho "vì sao đang là 0".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchPerformanceService.GetTopPagesAsync(Lada.Framework.Data.Enums.SearchEngine,System.Int32,System.Int32,System.Threading.CancellationToken)">
            <summary>Xếp hạng trang theo lượt bấm trong khoảng ngày.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchPerformanceService.GetTopQueriesAsync(Lada.Framework.Data.Enums.SearchEngine,System.Int32,System.Int32,System.Threading.CancellationToken)">
            <summary>Xếp hạng truy vấn theo lượt bấm trong khoảng ngày.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchPerformanceService.GetQueriesForPageAsync(Lada.Framework.Data.Enums.SearchEngine,System.String,System.Int32,System.Int32,System.Threading.CancellationToken)">
            <summary>Các truy vấn đưa người dùng tới đúng một trang.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchPerformanceService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchPerformanceService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchPerformanceService.DoTreChotSoNgay">
            <summary>
            Độ trễ chốt số của Google, tính bằng ngày. Đo 2026-09-16: ngày <c>final</c> gần nhất là
            hôm nay − 3. Dùng để phân biệt "chưa kéo về" với "Google chưa chốt" — hai nguyên nhân cùng
            cho ra một bảng trống nhưng đòi hai phản ứng khác nhau.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchPerformanceService.MaxTake">
            <summary>Trần số dòng trả về một lượt, chống <c>?take=999999</c> kéo cả bảng.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchPerformanceService.MaxDays">
            <summary>Trần số ngày hỏi được một lượt — 16 tháng, đúng bằng phần Google giữ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchPerformanceService.GopTheoChieuAsync(Lada.Framework.Data.Enums.SearchEngine,Lada.Framework.Data.Enums.SearchMetricLevel,System.Int32,System.Int32,System.Boolean,System.Threading.CancellationToken)">
             <summary>
             Gộp một mức theo chiều của nó rồi xếp hạng.
            
             <para>
             <b>Gộp theo <c>UrlNormalized</c> chứ không theo <c>Url</c>.</b> Đo 2026-09-16: 31 dòng mang
             neo <c>#…</c> thuộc chỉ 9 trang gốc — xếp hạng theo chuỗi gốc sẽ chia một trang thành năm
             dòng con và đẩy nó khỏi bảng xếp hạng dù tổng lượt bấm của nó cao.
             </para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchPerformanceService.TinhKhoangAsync(Lada.Framework.Data.Enums.SearchEngine,System.Int32,System.Threading.CancellationToken)">
            <summary>
            Khoảng ngày để đọc: lùi <paramref name="days"/> ngày <b>từ ngày có số mới nhất</b>, không
            phải từ hôm nay — xem lý do ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchPerformanceService.GetSummaryAsync(Lada.Framework.Data.Enums.SearchEngine,System.Int32,System.Threading.CancellationToken)"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchPerformanceService.Dung(System.String,System.String,System.String,System.Int64,System.Int64,System.Decimal,System.Nullable{System.Boolean},System.Nullable{System.Boolean})">
            <summary>
            Dựng một dòng, tính lại CTR và vị trí <b>từ tổng</b>. Đây là chỗ duy nhất làm phép đó — để
            không có hai công thức trong hệ thống.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings">
             <summary>
             Cấu hình đồng bộ công cụ tìm kiếm, đã đọc và đã ép kiểu từ <c>AppConfig</c>.
            
             <para>
             <b>Đây là luật "khi nào được phép gọi ra công cụ tìm kiếm", cố ý gom về đúng một chỗ</b> — cùng
             lý do với <c>ContentFingerprint.Stamp</c> ở giai đoạn trước: mọi đường gọi (ba job, nút bấm tay
             trên dashboard sau này) phải cư xử giống hệt nhau, và khi cần đổi luật thì chỉ có một chỗ để sửa.
             </para>
            
             <para>
             <b>Thiếu khoá thì mặc định là TẮT.</b> Một khoá bị xoá nhầm, một DB chưa chạy migration, một lỗi
             đọc cache — mọi trường hợp "không biết" đều phải dẫn tới "không gọi". Chiều ngược lại (không đọc
             được thì cứ gọi) là cách hỏng nguy hiểm: nó đốt hạn mức và có thể báo cho Google thứ không thật.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.Enabled">
            <summary>Công tắc ĐỌC: kiểm tra URL, đọc trạng thái sitemap.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.SubmitEnabled">
            <summary>Công tắc GHI: nộp sitemap. Tách khỏi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.Enabled"/> vì hậu quả khác hẳn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.SiteUrl">
            <summary>
            Định danh property: <c>sc-domain:ladaexpress.vn</c> (Domain) hoặc
            <c>https://ladaexpress.vn/</c> (URL-prefix). Sai dạng thì Google trả 403 không kèm lý do.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.SitemapUrl">
            <summary>Tệp sitemap dùng để dựng hàng tồn kho và để nộp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.InspectDailyBudget">
            <summary>Trần số lượt kiểm URL mỗi ngày dành cho job.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.ApiLogRetentionDays">
            <summary>Số ngày giữ nhật ký lời gọi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.IndexingEnabled">
             <summary>
             Công tắc thứ ba: <b>báo chủ động một URL cho Google</b> qua Indexing API.
            
             <para>
             Tách khỏi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.SubmitEnabled"/> vì đây là loại lời gọi ghi <b>nhắm vào từng trang</b>,
             có hạn mức riêng (200 lượt/ngày) và có luật dùng riêng của Google: chỉ hợp lệ cho trang mang
             dữ liệu có cấu trúc <c>JobPosting</c>. Nộp sitemap sai thì cùng lắm Google đọc lại một tệp;
             báo sai một URL là một tín hiệu sai nhắm đúng vào một trang.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.IndexingDailyBudget">
            <summary>Trần số URL được báo chủ động mỗi ngày.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.AnalyticsMinImpressions">
             <summary>
             Ngưỡng lượt hiển thị tối thiểu để giữ một dòng ở mức "trang × truy vấn".
            
             <para>
             <b>Mặc định 1 — tức là không lọc gì.</b> Kế hoạch §3.6 từng đề xuất 5, nhưng Việc 0 ngày
             2026-09-16 đo ra ngưỡng ấy vứt mất <b>30,3 % số lượt bấm</b> (10 dòng có lượt bấm thật mà
             lượt hiển thị dưới 5), trong khi nỗi lo "bảng phình" không thành sự thật: mức mịn nhất chỉ
             sinh trung bình 127 dòng/ngày. Vẫn để thành khoá để nâng được khi website lớn lên, mà không
             phải deploy.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.AnalyticsWindowDays">
             <summary>
             Độ rộng cửa sổ trượt (số ngày) của job kéo số liệu hằng ngày: mỗi lượt kéo lại
             <c>[T-N, T-1]</c>.
            
             <para>
             Các lượt chạy <b>cố ý chồng lên nhau</b>: Google còn sửa số của vài ngày gần nhất sau khi
             chốt, nên kéo một lần rồi thôi là giữ lại một con số tạm thời. Khoá upsert làm cho việc kéo
             lại an toàn.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.AnalyticsBackfillMonths">
             <summary>
             Số tháng lượt kéo bù lịch sử đi ngược về.
            
             <para>
             <b>17 chứ không phải 16, dù Google nói là "16 tháng".</b> Đo thật 2026-09-16: ngày sớm nhất
             còn số là 2025-05-04 — tức <b>16,4 tháng lịch</b>. Đặt 16 thì lượt kéo bù dừng ở 2025-05-16
             và bỏ lại 12 ngày cũ nhất, đúng phần dễ mất nhất vì Google xoá chúng trước tiên. Đã cắn thật
             một lần ở phiên GĐ F trước khi sửa. Đặt cao hơn mức cần thì job tự dừng sau hai lô liền nhau
             không có dòng nào, nên phần thừa nhiều nhất là hai lời gọi.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.BotVisitRetentionDays">
             <summary>
             Số ngày giữ dữ liệu lượt bot trong bảng <c>BotVisitDaily</c>; job dọn xoá cứng dòng cũ hơn.
            
             <para>
             <b>Ngược hẳn với số liệu hiệu suất tìm kiếm.</b> Bảng kia càng cũ càng quý — Google xoá
             bản gốc sau 16 tháng nên không lấy lại được. Lượt bot thì hết giá trị nhanh: câu hỏi luôn
             là "tháng này bot nào đang ghé", không phải "năm ngoái ghé bao nhiêu". Mặc định 90 ngày,
             đủ để so một quý với quý trước.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.BotVisitEnabled">
             <summary>
             Website có đang đếm lượt bot không (<c>Search.BotVisit.Enabled</c>).
            
             <para>
             <b>Mặc định BẬT</b> — khác mọi công tắc khác của miền này, và có chủ đích: những công tắc
             kia gác các lời gọi <b>ra Google</b>, còn việc đếm lượt bot không gọi ra ngoài lần nào.
             Cái giá của việc để tắt thì rất thật: deploy xong không ai nhớ bật, rồi tới lúc cần số thì
             không có đường cơ sở nào để so.
             </para>
             <para>
             Lưu ý: khoá này do <b>website</b> đọc để quyết định có ghi hay không. API đọc nó chỉ để
             màn hình giải thích được vì sao bảng đang rỗng.
             </para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.CanRead">
            <summary>
            Được phép gọi lời gọi ĐỌC hay không. Ngoài công tắc còn đòi có
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.SiteUrl"/> — không có định danh property thì lời gọi chắc chắn trả 403,
            gọi đi chỉ để nhận lỗi là vô ích.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.CanWrite">
            <summary>
            Được phép gọi lời gọi GHI hay không. Đòi <b>cả hai</b> công tắc: bật riêng công tắc ghi mà
            quên công tắc đọc là một trạng thái vô nghĩa, và cho phép nó sẽ tạo ra đường gửi dữ liệu đi
            mà không đường nào đọc lại được kết quả.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.CanNotify">
             <summary>
             Được phép <b>báo chủ động một URL</b> hay không.
            
             <para>
             Đòi cả <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.Enabled"/> lẫn <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.IndexingEnabled"/>, cùng lý do với
             <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.CanWrite"/>: bật đường ghi mà tắt đường đọc là một trạng thái không ai kiểm được
             kết quả. Cố ý <b>không</b> đòi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.SubmitEnabled"/> — nộp sitemap và báo từng URL là
             hai việc khác nhau, buộc chúng đi kèm sẽ làm người vận hành không bật được việc này mà
             không bật việc kia.
             </para>
             <para>
             Cũng <b>không</b> đòi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.SiteUrl"/>: Indexing API nhận thẳng URL của trang, không
             cần định danh property. Hàng rào tương ứng của nó là "URL phải thuộc chính website này",
             và hàng rào ấy đặt ở lúc xếp hàng đợi chứ không ở đây.
             </para>
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.EnabledOffReason">
            <summary>
            Lý do khi công tắc đọc đang tắt — dùng chung cho cả hai câu giải thích bên dưới, để đổi chữ
            một nơi không làm hai màn hình nói hai giọng về cùng một việc.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.NotifyBlockReason">
            <summary>
            Câu giải thích vì sao chưa được phép báo chủ động — hiện trên nhật ký chạy thử, nên phải
            nói đúng khoá nào đang chặn thay vì một câu chung chung.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.BlockReason">
            <summary>Câu giải thích vì sao chưa được phép gọi — để ghi log và hiện lên dashboard.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchSettingsReader">
            <summary>
            Đọc <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings"/> từ <c>AppConfig</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchSettingsReader.ReadAsync">
            <summary>Đọc cấu hình hiện hành. Giá trị đi qua cache <c>AppConfig</c> nên đổi công tắc có độ trễ tối đa 1 giờ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettingsReader">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.ISearchSettingsReader"/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettingsReader.Keys">
            <summary>Tên các khoá <c>AppConfig</c>. Đặt hằng để không có chuỗi rời rạc nào lệch chính tả.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettingsReader.ReadBoolAsync(System.String)">
            <summary>
            Đọc một khoá kiểu bool. Khoá thiếu, rỗng hay ghi sai chính tả đều cho <c>false</c> —
            "không đọc được" phải dẫn tới "không gọi".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettingsReader.ReadBoolMacDinhBatAsync(System.String)">
            <summary>
            Đọc một khoá kiểu bool <b>mặc định BẬT</b>: chỉ giá trị đọc được và bằng <c>false</c> mới
            cho tắt. Dùng cho công tắc không gác lời gọi ra ngoài — xem
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettings.BotVisitEnabled"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SearchEngines.SearchSettingsReader.ReadIntAsync(System.String,System.Int32)">
            <summary>
            Đọc một khoá kiểu số. Khoá thiếu hay không phải số thì lấy mặc định; số âm bị kéo về 0 để
            không có hạn mức âm biến thành vòng lặp vô tận ở chỗ so sánh.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.ICallPathService.GetByIdAsync(System.Int32)">
            <summary>
            Lấy thông tin CallPath theo Id.
            </summary>
            <param name="id">Id của CallPath.</param>
            <returns>Thông tin CallPath.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.ICallPathService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CallPathModel)">
            <summary>
            Tạo mới CallPath.
            </summary>
            <param name="callPath">Thông tin CallPath cần tạo.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.ICallPathService.DeleteAsync(System.Int32)">
            <summary>
            Xóa CallPath.
            </summary>
            <param name="id">Id của CallPath cần xóa.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.ICallPathService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm CallPath theo điều kiện lọc và phân trang.
            </summary>
            <param name="param">Tham số phân trang và điều kiện lọc.</param>
            <returns>Kết quả phân trang chứa danh sách CallPath.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.ICallPathService.CopyToVersionAsync(System.Int32,System.Int32,System.Int32,System.String)">
            <summary>
            Lấy tất cả CallPath theo version/build. Nếu không truyền, lấy danh sách từ phiên bản mặc định.
            </summary>
            <param name="version">Số phiên bản (optional)</param>
            <param name="build">Số build (optional)</param>
            <summary>
            Copy tất cả CallPath từ một version sang một version khác.
            </summary>
            <param name="sourceVersionId">Id của CallPathVersion nguồn.</param>
            <param name="targetVersionId">Id của CallPathVersion đích.</param>
            <param name="updatedBy">Id người thực hiện.</param>
            <param name="updatedByUserName">Tên người thực hiện.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Settings.CallPathService">
            <summary>
            Triển khai dịch vụ quản lý CallPath.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.CallPathService.GetByIdAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.CallPathService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CallPathModel)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.CallPathService.UpdateAsync(Lada.Framework.Data.Domains.Settings.CallPath)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.CallPathService.CreateAsync(Lada.Framework.Data.Domains.Settings.CallPath)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.CallPathService.DeleteAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.CallPathService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.CallPathService.CopyToVersionAsync(System.Int32,System.Int32,System.Int32,System.String)">
            <summary>
            Copy tất cả CallPath từ một version sang một version khác.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.ICallPathVersionService.GetByIdAsync(System.Int32)">
            <summary>
            Lấy thông tin CallPathVersion theo Id.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.ICallPathVersionService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CallPathVersionModel)">
            <summary>
            Tạo mới hoặc cập nhật CallPathVersion.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.ICallPathVersionService.DeleteAsync(System.Int32)">
            <summary>
            Xóa CallPathVersion.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.ICallPathVersionService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm CallPathVersion theo điều kiện lọc và phân trang.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.ICallPathVersionService.GetAllAsync">
            <summary>
            Lấy tất cả CallPathVersion (dùng cho dropdown).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Settings.CallPathVersionService">
            <summary>
            Triển khai dịch vụ quản lý CallPathVersion.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.CallPathVersionService.GetByIdAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.CallPathVersionService.CreateOrUpdateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.Settings.CallPathVersionModel)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.CallPathVersionService.DeleteAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.CallPathVersionService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.CallPathVersionService.GetAllAsync">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Settings.IHangfireJobService">
            <summary>
            Đọc trạng thái hàng đợi Hangfire (tác vụ nền) để hiển thị trên SPA quản trị,
            thay cho dashboard /hangfire vốn không dùng được với JWT của SPA.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.IHangfireJobService.GetOverview">
            <summary>
            Số liệu tổng quan theo trạng thái + server + queue.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.IHangfireJobService.GetRecurringJobs">
            <summary>
            Danh sách tác vụ định kỳ: mọi job trong lịch Hangfire gộp với danh mục RecurringJobCatalog
            (job trong danh mục nhưng chưa đăng ký / đã tạm dừng vẫn hiện để bấm Đăng ký).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.IHangfireJobService.TriggerRecurringJob(System.String)">
            <summary>
            Kích hoạt chạy ngay một tác vụ định kỳ, không đợi tới lịch.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.IHangfireJobService.PauseRecurringJob(System.String)">
            <summary>
            Tạm dừng: gỡ job khỏi lịch Hangfire và ghi cờ để khởi động lại API không tự đăng ký lại.
            Chỉ áp dụng cho job trong danh mục (có cách đăng ký lại).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.IHangfireJobService.RegisterRecurringJob(System.String)">
            <summary>
            Đăng ký (lại) một job trong danh mục với lịch mặc định, gỡ cờ tạm dừng nếu có.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.IHangfireJobService.RemoveRecurringJob(System.String)">
            <summary>
            Xoá hẳn một job KHÔNG nằm trong danh mục khỏi lịch Hangfire (job mồ côi do code cũ để lại).
            Job trong danh mục thì dùng Tạm dừng — xoá xong khởi động lại API nó sẽ sống dậy.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.IHangfireJobService.GetJobs(System.String,System.Int32,System.Int32)">
            <summary>
            Liệt kê job theo trạng thái, phân trang bằng from/count.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.IHangfireJobService.GetJobDetail(System.String)">
            <summary>
            Chi tiết một job kèm lịch sử trạng thái; null nếu không tìm thấy.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.IHangfireJobService.RequeueJob(System.String)">
            <summary>
            Đưa job (thường là job thất bại) trở lại queue để chạy lại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.IHangfireJobService.DeleteJob(System.String)">
            <summary>
            Xoá một job (chuyển sang trạng thái Deleted, không chạy nữa).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Settings.HangfireJobService.ListableStates">
            <summary>
            Các trạng thái có API liệt kê. "Enqueued" gom mọi queue.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Settings.HangfireJobService.VietnamTimeZone">
            <summary>
            Hangfire lưu mọi mốc thời gian theo UTC; trả về giờ Việt Nam cho SPA hiển thị thẳng.
            Cùng múi giờ mà GeneralRegister dùng khi đăng ký RecurringJob.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.HangfireJobService.DescribeJob(Hangfire.Common.Job,System.Exception)">
            <summary>
            Tên hiển thị "Lớp.PhươngThức"; khi Hangfire không nạp được kiểu (đã đổi tên/xoá class) thì báo lý do.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Settings.IMobileAppGateService">
            <summary>
            Đọc/ghi cấu hình màn hình chặn truy cập bằng điện thoại của app khách hàng (Lada.App).
            Dữ liệu nằm rải ở nhiều khoá <c>MobileApp.*</c> trong bảng AppConfig (DB dùng chung với Lada.AppBackEnd).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.IMobileAppGateService.GetAsync">
            <summary>Lấy cấu hình hiện tại; khoá chưa có thì trả giá trị mặc định.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.IMobileAppGateService.SaveAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.MobileAppGateModel,System.Int32,System.String)">
            <summary>Lưu cấu hình. Trường bỏ trống vẫn được ghi (để xoá giá trị cũ).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Settings.MobileAppGateService">
             <summary>
             Cài đặt <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Settings.IMobileAppGateService"/>.
            
             Ghi thẳng qua repository thay vì <c>IAppConfigManagementService.CreateOrUpdate</c> vì hàm đó
             từ chối Value rỗng — ở đây các trường như ảnh QR hay lời nhắn được phép để trống, và phải
             ghi được chuỗi rỗng thì quản trị mới xoá được giá trị đã đặt trước đó.
             </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Settings.MobileAppGateService.KeyEnabled">
            <summary>Khoá AppConfig — trùng với hằng số bên Lada.AppBackEnd, đổi thì phải đổi cả hai nơi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.MobileAppGateService.GetAsync">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.MobileAppGateService.SaveAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.AppConfig.MobileAppGateModel,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Settings.MobileAppGateService.GhiKhoaAsync(System.String,System.String,System.Int32,System.String)">
            <summary>Ghi một khoá AppConfig và đồng bộ lại cache của khoá đó.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityInput">
            <summary>
            Bảng đầu vào của phép tính trạng thái sẵn sàng — mọi thứ cần biết về <b>một</b> người, đã
            đọc sẵn khỏi database.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityInput.IsResigned">
            <summary>Tài khoản đã nghỉ việc (<c>User.IsDeleted</c>) hoặc không tồn tại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityInput.SuspendedUntil">
            <summary>
            Quản lý tạm ngưng chia khách đến khi nào (<c>ChatAgentPresence.SuspendedUntil</c>).
            <c>null</c> = không bị ngưng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityInput.SelfStatus">
            <summary>
            Trạng thái người này tự khai (<c>ChatAgentPresence.SelfStatus</c>). Không có dòng
            presence thì là <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Available"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityInput.SelfStatusUntil">
            <summary>
            Trạng thái tự khai có hạn đến khi nào (<c>ChatAgentPresence.UntilTime</c>).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailability">
            <summary>
            Luật "sale này có sẵn sàng nhận khách mới lúc này không" — <b>hàm thuần</b>, viết đúng một
            lần, không chạm database.
            <para>
            Cùng khuôn với <c>ChatRealtimeAudience.Resolve</c> của giai đoạn A: bảng đầu vào → kết
            luận, nên kiểm được bằng bảng ca thẳng thay vì phải dựng cả kho dữ liệu giả. Đây cũng là
            điều kiện lọc số 2 của máy phân phối §3.3, nên giai đoạn D sẽ đọc thẳng hàm này.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailability.Resolve(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityInput,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours)">
            <summary>
            Trạng thái <b>hiệu lực</b> của một người tại một thời điểm.
            </summary>
            <remarks>
            <para>
            <b>Thứ tự ưu tiên</b>, cao thắng thấp — mỗi bậc có lý do riêng, không phải xếp theo
            cảm tính:
            </para>
            <list type="number">
            <item><see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Resigned"/> — người không còn làm việc thì không có
            trạng thái nào khác đáng bàn.</item>
            <item><see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Suspended"/> — quyết định của quản lý, sale không tự
            gỡ được, nên nó phải thắng mọi thứ sale tự khai.</item>
            <item><see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.OnLeave"/> — <b>đứng TRÊN</b> "ngoài giờ làm việc" có
            chủ ý: một lời khai nghỉ nhiều ngày mang nhiều thông tin hơn hẳn "bây giờ là 8 giờ tối".
            Xếp ngược lại thì người nghỉ cả tuần hiện là "ngoài giờ làm" mỗi tối, và bảng thời lượng
            của giai đoạn F mất luôn lý do thật.</item>
            <item><see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.OffShift"/> — <b>đứng TRÊN</b> Bận / Ra ngoài, vì đây
            là nguồn chính (xem <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours"/>) còn lời tự khai ngắn hạn là nguồn
            yếu nhất theo số đo C0.</item>
            <item><see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Busy"/> / <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Away"/> — lời tự
            khai còn hạn.</item>
            <item><see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Available"/> — mặc định.</item>
            </list>
            <para>
            <b>Quyết định fail-open, và vì sao.</b> Prompt giai đoạn C bắt phải chọn có ý thức giữa
            fail-open và fail-closed rồi viết lý do vào code. Ở đây chọn <b>fail-open</b>: mọi thứ
            không đọc được, không có, hoặc vô lý đều rơi về
            <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Available"/>. Ba lý do:
            </para>
            <list type="bullet">
            <item><b>"Không có dòng" là trạng thái BÌNH THƯỜNG, không phải trạng thái lỗi.</b> Số
            đo C0 cho thấy chưa sale nào có lý do dùng menu đổi trạng thái, nên tuyệt đại đa số
            người sẽ không bao giờ có dòng <c>ChatAgentPresence</c>. Fail-closed ở đây nghĩa là cả
            đội vĩnh viễn không nhận được khách — chính xác cái bẫy PP-12 đã ghi về chấm công.</item>
            <item><b>Hai hướng hỏng không cân nhau.</b> Fail-closed khi một truy vấn hỏng làm cả
            đội ngừng nhận khách và khách ngồi chờ — một sự cố nhìn thấy được từ phía khách hàng.
            Fail-open thì tệ nhất là chia khách cho người đang bận, và người đó bấm "Nhả" là xong.</item>
            <item><b>Đây KHÔNG phải hàng rào quyền xem.</b> Hàng rào (§3.7) fail-closed, và điều đó
            không đổi. Hàm này chỉ quyết định <i>chia việc</i>; đọc nhầm nó thành một quyết định
            bảo mật rồi siết theo là siết nhầm chỗ.</item>
            </list>
            <para>
            Ngoại lệ duy nhất của fail-open là <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityInput.IsResigned"/>:
            người gọi <b>phải</b> đặt cờ này khi không tra được tài khoản, vì một mã nhân viên không
            tồn tại thì fail-open nghĩa là giao khách cho người không có thật.
            </para>
            </remarks>
            <param name="input">Bảng đầu vào đã đọc sẵn khỏi database</param>
            <param name="at">Thời điểm cần biết. Truyền vào chứ không hỏi đồng hồ — repo không có abstraction đồng hồ.</param>
            <param name="workingHours">Cửa sổ giờ làm việc đã dựng từ cấu hình</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailability.NhanKhachMoiDuoc(Lada.Framework.Data.Enums.ChatAgentStatus)">
            <summary>
            Chỉ trạng thái <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Available"/> mới nhận khách mới (§3.5). Mọi
            trạng thái khác <b>không</b> miễn cho sale nghĩa vụ trả lời khách đang cầm — bận nghĩa
            là "không nhận thêm", không phải "được im lặng".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailability.TuKhaiDuoc(Lada.Framework.Data.Enums.ChatAgentStatus)">
            <summary>
            Giá trị này có được phép lưu vào <c>ChatAgentPresence.SelfStatus</c> không — tức người
            dùng (hoặc quản lý) có khai được nó không.
            <para>
            <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Suspended"/> không nằm ở đây vì nó là
            <c>SuspendedUntil</c>; <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.OffShift"/> và
            <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Resigned"/> không nằm ở đây vì chúng suy ra lúc chạy.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailability.GhiNhatKyDuoc(Lada.Framework.Data.Enums.ChatAgentStatus)">
            <summary>
            Giá trị này có được phép ghi vào <c>ChatAgentPresenceLog.Status</c> không — tức nó là
            trạng thái <b>khai báo</b> (1–5) chứ không phải trạng thái suy ra (6–7).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentAvailabilityResolver">
            <summary>
            Trả lời câu hỏi <b>"sale này có nhận khách mới lúc này không"</b> — đầu vào thứ hai của máy
            phân phối (§3.3 điều kiện lọc số 2, §3.5).
            <para>
            Gộp ba nguồn còn dùng được sau số đo C0: tài khoản còn làm việc không, quản lý có tạm ngưng
            không, và người đó tự khai gì — cộng với giờ làm việc <b>riêng của từng người</b> (KC-18,
            2026-09-27; trước đó là một cấu hình chung áp cho cả đội). <b>Không</b> đọc
            <c>LeaveRequest</c> (chủ dự án chốt 2026-08-29: trạng thái "Nghỉ" ở đây là trạng thái hỗ
            trợ tự khai, không liên quan nghỉ phép nhân sự — sổ nợ PP-11) và <b>không</b> đọc
            <c>Attendance</c> (chỉ 20/40 sale chấm công, dùng nó là một nửa đội vĩnh viễn "ngoài ca" mà
            không ai hiểu vì sao — sổ nợ PP-12).
            </para>
            <para>
            Toàn bộ <b>luật</b> nằm ở hàm thuần <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailability.Resolve(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityInput,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours)"/>; lớp này chỉ
            đi lấy dữ liệu cho nó. Nhờ tách như thế, mọi ca test về thứ tự ưu tiên chạy trên bảng ca
            thẳng, không cần kho dữ liệu giả.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentAvailabilityResolver.GetEffectiveStatusAsync(System.Int32,System.DateTimeOffset)">
            <summary>
            Trạng thái hiệu lực của một người tại một thời điểm.
            </summary>
            <param name="staffId">Mã nhân viên (<c>User.Id</c>)</param>
            <param name="at">
            Thời điểm cần biết. <b>Truyền vào</b> chứ không hỏi đồng hồ bên trong: repo không có
            abstraction thời gian, nên đây là cách duy nhất để test được luật hết hạn.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentAvailabilityResolver.GetEffectiveStatusesAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},System.DateTimeOffset)">
            <summary>
            Trạng thái hiệu lực của một loạt người, <b>ba lần đọc cho cả lô</b> chứ không phải ba
            lần đọc mỗi người: cấu hình chung (chỉ còn lấy múi giờ), tài khoản còn làm việc, và dòng
            <c>ChatAgentPresence</c>.
            <para>
            Giai đoạn D sẽ hỏi "ai trong kênh này đang sẵn sàng" cho mỗi tin inbound, mà một kênh
            có thể có hàng chục sale — gọi bản một-người trong vòng lặp là nhân số truy vấn lên
            đúng bằng số sale, trên đường chạy nóng nhất của cả hệ thống.
            </para>
            <para>
            <b>Giờ làm riêng (KC-18) không tốn truy vấn thứ tư</b>: bảy cột giờ nằm ngay trên dòng
            presence đã nạp, nên giờ của từng người dựng lại từ chính các dòng ấy
            (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffWorkingHoursProvider.FromPresences(System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Collections.Generic.IReadOnlyDictionary{System.Int32,Lada.Framework.Data.Domains.SocialChat.ChatAgentPresence},System.TimeSpan)"/>). Đây là lý do thiết kế đặt
            giờ riêng thành cột thay vì bảng con — plan khoá học chat §6 "Phiên 4" mục 1.
            </para>
            </summary>
            <returns>
            Từ điển đủ <b>mọi</b> mã được hỏi (mã không tra được cũng có mặt, mang
            <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Resigned"/>) — người gọi không phải xử lý khoá thiếu.
            </returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentAvailabilityResolver.GetPresenceAsync(System.Int32)">
            <summary>
            Trạng thái <b>tự khai</b> đang lưu của một người, kèm cờ tạm ngưng — dùng cho màn hình
            đổi trạng thái (nó phải hiện đúng thứ người dùng đã chọn, không phải kết luận sau khi
            gộp với giờ làm việc). Trả <c>null</c> khi người này chưa có dòng nào.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentAvailabilityResolver.GetWorkingHoursAsync(System.Int32)">
            <summary>
            Giờ làm việc <b>của riêng người này</b> đang có hiệu lực — để màn hình giải thích được vì
            sao "Ngoài giờ làm việc", và để hộp "Đặt giờ làm việc" hiện đúng giờ đã lưu.
            </summary>
            <remarks>
            Trước KC-18 hàm này không nhận tham số và trả cấu hình chung — một câu trả lời cho mọi
            người. Nay cấu hình chung không còn áp cho ai (§8.7 câu 5), nên hàm hỏi theo người và đi
            <b>cùng một đường dựng</b> với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentAvailabilityResolver.GetEffectiveStatusesAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},System.DateTimeOffset)"/>: chữ "Ngoài giờ"
            trên chip và lời giải thích bên cạnh không thể đọc hai định nghĩa khác nhau. Không bao
            giờ trả <c>null</c>; người chưa đặt mang
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursState.NotSet"/> với cửa sổ "luôn trong ca".
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentAvailabilityResolver.GetWorkingHoursManyAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>
            Giờ làm riêng của một loạt người trong <b>một</b> truy vấn — bản nhiều-người của
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentAvailabilityResolver.GetWorkingHoursAsync(System.Int32)"/>, cùng đường dựng. Dùng cho cột "Giờ làm việc" của bảng
            trạng thái sale (KC-20, §8.7 câu 6): quản lý phải thấy ca bất thường để đặt hộ lại.
            </summary>
            <returns>Từ điển đủ mọi mã hợp lệ được hỏi; người chưa đặt mang <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursState.NotSet"/>.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityResolver">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentAvailabilityResolver"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityResolver.GetEffectiveStatusAsync(System.Int32,System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityResolver.GetEffectiveStatusesAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityResolver.IsStillEmployed(System.DateTimeOffset)">
            <summary>
            Định nghĩa <b>duy nhất</b> của "còn đang đi làm" — phủ định của trạng thái
            <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Resigned"/>: tài khoản nhân viên, không bị khoá tại mốc
            <paramref name="now"/>. Mã không lọt qua (kể cả mã không tồn tại) là đã nghỉ việc.
            </summary>
            <remarks>
            Công khai vì đồng hồ hàng chờ (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelCoverageService"/>, KC-18) cũng phải
            loại người đã nghỉ việc khỏi tập "vào ca", và chép điều kiện <c>LockoutEnd</c> sang đó là
            dựng định nghĩa thứ hai — ngày ai đó sửa luật khoá tài khoản ở một chỗ, chỗ kia vẫn cho
            một người đã nghỉ "giữ đồng hồ chạy". Biểu thức chứ không phải hàm để EF dịch được sang SQL.
            </remarks>
            <param name="now">Mốc so <c>LockoutEnd</c> — <b>hiện tại</b>, không phải mốc quá khứ đang hỏi</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityResolver.GetPresenceAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityResolver.GetWorkingHoursAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityResolver.GetWorkingHoursManyAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentPresenceService">
            <summary>
            Đọc và đổi trạng thái sẵn sàng của sale, và đường uỷ quyền tạm đi kèm (giai đoạn C).
            </summary>
            <remarks>
            <para>
            Tách khỏi <c>SocialChatService</c> (constructor đã 12 tham số) và khỏi
            <c>ChatChannelStaffService</c> vì đây là một miền riêng: trạng thái của <b>người</b>, không
            phải của hội thoại hay của kênh. Giai đoạn D sẽ đọc
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentAvailabilityResolver"/> chứ không đọc lớp này — lớp này là đường GHI.
            </para>
            <para>
            <b>Mọi lần đổi người phụ trách đều đi qua <c>IChatAssignmentJournal.ApplyChangeAsync</c></b>
            (§1 mục 4). Uỷ quyền tạm không phải ngoại lệ, và cũng không được tự ghi thẳng vào
            repository hội thoại.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentPresenceService.GetPresenceItemAsync(System.Int32,System.DateTimeOffset)">
            <summary>
            Trạng thái của một người, dựng đủ cho màn hình (hiệu lực + tự khai + cấu hình + giờ làm
            riêng và giờ gợi ý)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentPresenceService.GetStaffPresenceItemAsync(System.Int32,System.Int32,System.DateTimeOffset)">
            <summary>
            Trạng thái của một <b>người khác</b>, đã chấm phạm vi. Trả <c>null</c> khi người gọi
            không quản lý được người này.
            </summary>
            <remarks>
            Phải là một cửa riêng, không dùng chung <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentPresenceService.GetPresenceItemAsync(System.Int32,System.DateTimeOffset)"/>: đường đọc
            không có hàng rào biến cặp endpoint này thành máy tra tên và ghi chú theo mã tuỳ ý cho
            bất kỳ ai qua được <c>[Authorize]</c> — đúng hình dạng finding F-4 của giai đoạn A
            (<c>POST staff</c> + <c>GET {id}/staff</c> thành máy tra họ tên theo mã).
            Ngoài phạm vi trả <c>null</c> chứ không ném: một thông điệp duy nhất, không phân biệt
            "không tồn tại" với "ngoài phạm vi".
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentPresenceService.SetMyStatusAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceModel,System.Int32,System.String)">
            <summary>
            Đặt trạng thái tự khai cho <b>chính mình</b>.
            </summary>
            <remarks>
            Đặt <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.OnLeave"/> dài từ <c>Chat.Presence.DelegateOnLeaveDays</c>
            ngày trở lên sẽ kéo theo <b>uỷ quyền tạm</b> mọi hội thoại đang cầm. Đó là một thao tác
            đổi người phụ trách hàng loạt chạy đồng bộ trong chính lời gọi này — chậm nhưng hiếm,
            và tách sang job nền thì người dùng bấm xong không biết chuyện gì đã xảy ra.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentPresenceService.SetStaffStatusAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceModel,System.Int32,System.String)">
            <summary>
            Đặt trạng thái tự khai <b>hộ người khác</b> (quyền <c>ChatAgentPresence.ManageOthers</c>).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentPresenceService.SetMyWorkingHoursAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel,System.Int32,System.String)">
            <summary>
            Đặt, sửa hoặc xoá giờ làm việc <b>riêng</b> của <b>chính mình</b> (KC-18). Giờ bắt đầu
            và giờ kết thúc cùng trống = xoá, về "chưa đặt" (luôn trong ca).
            </summary>
            <remarks>
            Chỉ ghi bảy cột giờ trên dòng <c>ChatAgentPresence</c>: <b>không</b> đụng trạng thái tự
            khai và hạn của nó, <b>không</b> ghi <c>ChatAgentPresenceLog</c> — nhật ký chỉ dành cho
            trạng thái khai báo, còn "Ngoài giờ" là trạng thái suy ra lúc đọc.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentPresenceService.SetStaffWorkingHoursAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel,System.Int32,System.String)">
            <summary>
            Đặt, sửa hoặc xoá giờ làm việc riêng <b>hộ người khác</b> — cùng quyền
            (<c>ChatAgentPresence.ManageOthers</c>) và cùng phạm vi với đặt trạng thái hộ (§8.7 câu 4).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentPresenceService.SuspendAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceSuspendModel,System.Int32,System.String)">
            <summary>Tạm ngưng chia khách cho một người, hoặc gỡ lệnh tạm ngưng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentPresenceService.DelegateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceDelegateModel,System.Int32,System.String)">
            <summary>
            Uỷ quyền tạm bằng tay: chuyển hội thoại của một người <b>đang không sẵn sàng</b> sang
            người khác cùng kênh.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentPresenceService.SearchDurationsAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>Bảng thời lượng theo trạng thái, một dòng mỗi nhân viên</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentPresenceService.SweepExpiredStatusesAsync(System.DateTimeOffset)">
            <summary>
            Dọn những trạng thái đã hết hạn mà chưa ai bấm gì: hạ về Sẵn sàng, đóng dòng nhật ký
            đang mở, và <b>trả lại hội thoại đã uỷ quyền tạm</b> cho người vừa hết hạn nghỉ
            (giai đoạn E — đóng PP-26 và PP-27).
            </summary>
            <remarks>
            <para>
            Vì sao cần: <c>ChatAgentAvailability.Resolve</c> đã coi trạng thái hết hạn là Sẵn sàng
            <b>ngay lúc đọc</b>, nên không có gì sai về mặt phân phối. Nhưng đường <i>trả lại hội
            thoại</i> nằm ở lời gọi GHI, mà lời gọi ấy chỉ chạy khi có người bấm — người nghỉ xong
            không bấm gì thì hội thoại ở lại vĩnh viễn với người giữ hộ (PP-26). Và dòng nhật ký
            đang mở không bao giờ đóng, làm bảng đọc thẳng bằng SQL trông sai dù bảng thời lượng vẫn
            đúng nhờ cột <c>ExpiresAt</c> (PP-27).
            </para>
            <para>
            Gọi kèm trong lượt quét hạn phản hồi — chỗ rẻ nhất, vì lượt ấy đã chạy mỗi 2 phút. Chạy
            <b>độc lập</b> với công tắc <c>Chat.Sla.Enabled</c>: đây là dọn dẹp trạng thái, không
            phải tự động thu hồi của ai, nên nó không nằm trong cái mà công tắc kia bảo vệ.
            </para>
            </remarks>
            <param name="now">Mốc quét — tham số để test được mà không phụ thuộc đồng hồ máy</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceExpirySweepResult">
            <summary>Kết quả một lượt dọn trạng thái hết hạn — dùng cho log và cho test.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceExpirySweepResult.ExpiredLogCount">
            <summary>Số dòng nhật ký đang mở đã quá hạn, tìm thấy ở lượt này</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceExpirySweepResult.ResetCount">
            <summary>Số nhân viên vừa được hạ về trạng thái Sẵn sàng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceExpirySweepResult.ReturnedConversationCount">
            <summary>Số hội thoại vừa trả lại cho người hết hạn nghỉ</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAgentPresenceService" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.RoleFounder">
            <summary>Bỏ qua mọi ràng buộc phạm vi</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.RoleDistributionManage">
            <summary>Quản trị phân phối toàn hệ thống — chạm được nhân viên của mọi kênh</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.DefaultReportDays">
            <summary>Cửa sổ mặc định của bảng thời lượng khi client không gửi khoảng nào — hôm nay</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.MaxReportStaff">
            <summary>
            Trần số nhân viên một lượt xem báo cáo. Bảng thời lượng nạp nhật ký của từng người, nên
            nó phải là một trang chứ không phải cả bảng lương.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.ExpirySweepLimit">
            <summary>
            Trần số dòng nhật ký quá hạn dọn trong một lượt. Lượt dọn chạy kèm job hạn phản hồi
            (mỗi 2 phút) nên nó phải kết thúc gọn; phần dư sang lượt sau, và vì sắp theo mã nhân
            viên nên thứ tự ổn định chứ không bỏ sót ai. <b>Cắt bao nhiêu thì log ra bấy nhiêu.</b>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.SystemActorName">
            <summary>Tên người thao tác ghi vào nhật ký khi chính hệ thống tự dọn</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.GetPresenceItemAsync(System.Int32,System.DateTimeOffset)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.GetStaffPresenceItemAsync(System.Int32,System.Int32,System.DateTimeOffset)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.SearchDurationsAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.SetMyStatusAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceModel,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.SetStaffStatusAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceModel,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.SuspendAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceSuspendModel,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.SetMyWorkingHoursAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.SetStaffWorkingHoursAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.DatGioLamAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatWorkingHoursModel,System.Int32,System.Int32,System.String)">
            <summary>
            Kiểm hợp lệ rồi ghi bảy cột giờ làm riêng — dùng chung cho hai đường "của tôi" và "đặt hộ".
            </summary>
            <remarks>
            <para>
            Luật hợp lệ là <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.ValidateStaffInput(System.String,System.String,System.String,System.String,System.String)"/> — cùng luật mà đường
            dựng từ cột (<c>ChatWorkingHours.ForStaff</c>) dùng, nên dòng nào ghi được ở đây thì máy
            chia đọc được đúng như thế, không có dòng "API nhận mà máy chia coi là hỏng".
            </para>
            <para>
            <b>Không</b> đụng <c>SelfStatus</c>/<c>UntilTime</c> và <b>không</b> ghi
            <c>ChatAgentPresenceLog</c>: nhật ký chỉ ghi trạng thái <i>khai báo</i>, còn "Ngoài giờ"
            là trạng thái <i>suy ra</i> lúc đọc (chốt chặn <c>GhiNhatKyDuoc</c>). Giờ riêng cũng
            không có lịch sử — giới hạn đã chấp nhận ở thiết kế §6 "Phiên 4".
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.MaxWorkingDayCodes">
            <summary>Số mã ngày tối đa một lần đặt giờ làm được gửi lên — bảy ngày trong tuần</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.ThongDiepBoGioRieng">
            <summary>Thông báo sau khi bỏ giờ làm riêng — dùng cho cả hai đường, cả khi chưa từng đặt.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.NoiMaNgay(System.Int32[])">
            <summary>
            Ghép mảng mã ngày từ giao diện thành chuỗi <c>"2,3,4"</c> mà hàm kiểm hợp lệ và cột
            <c>WorkingDays</c> dùng. <c>null</c>/rỗng giữ nguyên rỗng — hàm kiểm hợp lệ tự báo
            "chọn ít nhất một ngày" khi đang đặt giờ, và bỏ qua khi đang xoá.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.DelegateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceDelegateModel,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.UyQuyenTamDuoc(Lada.Framework.Data.Enums.ChatAgentStatus)">
            <summary>
            Trạng thái nào của người đang giữ thì cho phép <b>uỷ quyền tạm bằng tay</b>.
            </summary>
            <remarks>
            <para>
            CHỈ ba trạng thái mang nghĩa "vắng mặt đã được khai báo hoặc đã bị quản lý ra lệnh":
            <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.OnLeave"/>, <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Suspended"/>,
            <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Resigned"/>.
            </para>
            <para>
            <b>Cố ý KHÔNG nhận <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.OffShift"/></b>, dù nó cũng là "không sẵn
            sàng". Ngoài 08:00–17:30 và cả ngày Chủ Nhật thì <i>mọi người</i> đều OffShift — lấy nó
            làm điều kiện là dựng một hàng rào rỗng nghĩa: 18 giờ tối, người có
            <c>ChatAgentPresence.ManageOthers</c> nhưng KHÔNG có <c>ChatConversation.Transfer</c>
            vẫn chuyển được hội thoại của đồng nghiệp cùng kênh đi bất cứ đâu. Cùng lý lẽ với
            <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Busy"/>/<see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Away"/>: chúng có trần
            120 phút, không phải lý do để bàn giao việc.
            </para>
            <para>
            Đường TỰ ĐỘNG (đặt Nghỉ dài) không đi qua hàm này, và không cần: ở đó chính người đang
            giữ là người bấm, nên không có ai giành việc của ai.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.UyQuyenTamAsync(System.Int32,System.Int32,System.Int32,System.String,System.String,System.DateTimeOffset,System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Int32)">
            <summary>
            Giao hội thoại đang mở của <paramref name="fromStaffId"/> cho người khác cùng kênh.
            </summary>
            <param name="toStaffId">
            Người nhận. <c>0</c> = tự chọn người ít việc nhất đang sẵn sàng, theo từng kênh.
            </param>
            <param name="gioiHanKenh">
            Chỉ đụng tới hội thoại thuộc những kênh này. <c>null</c> = không giới hạn.
            <para>
            <b>Đây là hàng rào, không phải một bộ lọc tiện tay.</b> Thẩm quyền đưa người gọi tới
            đây là thẩm quyền <b>theo kênh</b>: <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.NhanVienQuanLyDuocAsync(System.Int32)"/> cho họ chạm
            tới một nhân viên vì hai người cùng ở một kênh mà họ làm <c>Leader</c>/<c>Owner</c>.
            Không giới hạn lại ở đây thì trưởng nhóm kênh K đụng được nhân viên B qua kênh K, rồi
            chuyển luôn hội thoại của B ở kênh L, M, N — những kênh họ không có vai trò nào. Đó
            đúng hình dạng finding <b>F-1</b> đã vá một lần ở giai đoạn A ("quyền cấu hình MỘT kênh
            gỡ được người phụ trách của MỌI kênh"), và đúng lý do
            <c>ChatChannelStaffService.NhaHoiThoaiKhiThoiPhuTrachAsync</c> phải lọc theo
            <b>cặp (kênh, người)</b>.
            </para>
            <para>
            Đường TỰ PHỤC VỤ truyền <c>null</c>, và phải thế: tôi nghỉ thì hội thoại của tôi ở
            <i>mọi</i> kênh đều cần bàn giao. Chính người đang giữ là người bấm nên không có ai
            giành việc của ai.
            </para>
            </param>
            <param name="loaiTruNguoiNhan">
            Không chọn người này làm người nhận ở nhánh tự chọn. Dùng để chặn người thao tác tự
            nhận việc về mình — <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.DelegateAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatPresenceDelegateModel,System.Int32,System.String)"/> đã chặn đường CHỈ ĐỊNH, nhưng nhánh TỰ
            CHỌN cũng phải chặn, nếu không thì chỉ cần đặt mọi đồng nghiệp sang "Bận" là bản thân
            thành ứng viên duy nhất và cùng một kết quả xảy ra qua một cửa khác.
            </param>
            <returns>(số hội thoại đã giao, số hội thoại không giao được)</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.TraLaiUyQuyenAsync(System.Int32,System.Int32,System.String,System.DateTimeOffset)">
            <summary>
            Nhận lại những hội thoại đã uỷ quyền tạm đi khi người nghỉ quay lại (CH-7).
            </summary>
            <remarks>
            Không có cột nào đánh dấu "hội thoại này đang được giữ hộ" — và cố ý không thêm, vì
            <c>ChatConversationAssignment</c> đã kể đủ câu chuyện: một lượt <b>đang mở</b> với lý do
            nhận <c>UyQuyenTam</c>, mà lượt <b>ngay trước</b> nó của cùng hội thoại là của người vừa
            quay lại và đóng bằng lý do <c>NguoiPhuTrachNghi</c>. Thêm một cột cờ là dựng nguồn sự
            thật thứ hai cho một việc mà nhật ký đã trả lời được.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.SweepExpiredStatusesAsync(System.DateTimeOffset)">
            <summary>
            Chọn người nhận trong một kênh: người chỉ định (nếu hợp lệ), hoặc người ít việc nhất
            đang sẵn sàng.
            </summary>
            <param name="loaiTru">
            Không bao giờ chọn người này ở nhánh TỰ CHỌN. <c>0</c> = không loại trừ ai.
            <para>
            Có mặt vì chặn đường CHỈ ĐỊNH thôi thì chưa đủ. Người có
            <c>ChatAgentPresence.ManageOthers</c> đặt được trạng thái cho mọi nhân viên trong kênh
            mình làm trưởng nhóm — nên họ chỉ cần đặt tất cả đồng nghiệp sang "Bận", đặt mình
            "Sẵn sàng", rồi đặt nạn nhân sang "Nghỉ 2 ngày": nhánh tự chọn lúc ấy chỉ còn đúng một
            ứng viên là chính họ, và toàn bộ hội thoại của nạn nhân về tay họ mà không cần
            <c>ChatConversation.Transfer</c>. Cùng một kết quả với đường chỉ định, qua một cửa khác.
            </para>
            <para>
            Đường TỰ PHỤC VỤ truyền <c>0</c>: ở đó người bấm chính là người đang giữ, nên máy chọn
            trúng ai cũng là luật xác định chứ không phải một lựa chọn của họ.
            </para>
            </param>
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.DoiNguoiPhuTrachAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.Int32,System.Int32,System.Int32,System.String,System.String,System.DateTimeOffset,Lada.Framework.Data.Enums.ChatAssignReason,Lada.Framework.Data.Enums.ChatReleaseReason)">
            <summary>
            Đổi người phụ trách một hội thoại qua sổ phân công, rồi phát realtime đúng thứ tự.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.NapHoacTaoAsync(System.Int32,System.Int32,System.String,System.DateTimeOffset)">
            <summary>
            Nạp dòng presence, hoặc dựng mới nếu chưa có. "Chưa có dòng" là trạng thái bình thường
            của gần như mọi sale, không phải lỗi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.GhiNhatKyAsync(Lada.Framework.Data.Domains.SocialChat.ChatAgentPresence,Lada.Framework.Data.Enums.ChatPresenceSource,System.Int32,System.String,System.DateTimeOffset)">
            <summary>
            Đóng dòng nhật ký đang mở và mở dòng mới, nếu trạng thái <b>khai báo</b> thật sự đổi.
            </summary>
            <remarks>
            Trạng thái khai báo là <c>Suspended</c> khi đang bị tạm ngưng, còn lại là
            <c>SelfStatus</c> — một giá trị tại một thời điểm, nên đúng một dòng đang mở. Không tách
            khoảng khi trạng thái không đổi (ví dụ chỉ sửa ghi chú): tách ra là bảng thời lượng đầy
            những khoảng một phút không nói lên điều gì.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.TrongPhamViAsync(System.Int32,System.Int32)">
            <summary>
            Người thao tác có được đặt trạng thái / tạm ngưng / uỷ quyền cho nhân viên này không.
            </summary>
            <remarks>
            <para>
            Hàng rào ở đây là <b>phạm vi KÊNH</b>, không phải <c>DataAccessScope</c>:
            </para>
            <list type="bullet">
            <item>Quản trị phân phối toàn hệ thống (<c>Founder</c> hoặc
            <c>ChatDistribution.Manage</c>) chạm được mọi nhân viên chat.</item>
            <item>Người khác chỉ chạm được nhân viên của <b>những kênh chính mình đang là
            <c>Leader</c>/<c>Owner</c></b> — cùng đúng tập mà <c>CanAdministerChannelAsync</c> cho
            họ cấu hình danh sách phụ trách.</item>
            <item>Chính mình thì luôn được.</item>
            </list>
            <para>
            <b>Vì sao không dùng <c>DataAccessScope</c> như <c>IsStaffInScopeAsync</c>:</b> số đo
            §2.4 cho thấy 77/85 dòng <c>UserPreference</c> đang ở <c>SelfOnly</c>, kể cả của người
            quản lý. Gác đường này bằng <c>DataAccessScope</c> nghĩa là nhóm 7 "Quản lý chi nhánh"
            — nhóm được cấp <c>ChatAgentPresence.ManageOthers</c> ở PP-17 — <b>không đặt được trạng
            thái cho một ai</b>, và giao diện lại dịch điều đó thành "không tìm thấy nhân viên".
            Đó đúng hình dạng lỗi FB-1/L12: trang vô dụng với chính vai nó phục vụ, và không ai
            thấy vì mọi lần thử tay đều bằng Founder.
            </para>
            <para>
            Nới hơn <c>IsStaffInScopeAsync</c> nhưng <b>không</b> mở thêm đường nào: hàm kia gác một
            phép <i>tra danh bạ</i> (cặp <c>POST staff</c> + <c>GET {id}/staff</c> từng thành máy tra
            họ tên theo mã — finding F-4), còn hàm này gác thao tác quản lý trên những người mà
            người gọi <b>đã</b> nhìn thấy sẵn trong danh sách phụ trách kênh của chính họ. Và tự
            nâng mình lên <c>Leader</c> để lách thì không được: đặt vai <c>Leader</c>/<c>Owner</c>
            đòi <c>ChatDistribution.Manage</c> hoặc <c>Founder</c> từ bản vá F-1.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.NhanVienQuanLyDuocAsync(System.Int32)">
            <summary>
            Tập nhân viên mà người này quản lý được trạng thái. Trả <c>null</c> nghĩa là
            <b>không giới hạn</b> (quản trị phân phối toàn hệ thống) — phân biệt rõ với một danh
            sách rỗng, vốn nghĩa là "không quản lý được ai".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.KenhQuanLyDuocAsync(System.Int32)">
            <summary>
            Những kênh mà người này thật sự có thẩm quyền quản lý. Trả <c>null</c> nghĩa là
            <b>không giới hạn</b> (quản trị phân phối toàn hệ thống) — phân biệt rõ với danh sách
            rỗng, vốn nghĩa là "không quản lý kênh nào".
            </summary>
            <remarks>
            Tách riêng khỏi <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.NhanVienQuanLyDuocAsync(System.Int32)"/> vì <b>hai hàng rào cần cùng một
            nguồn</b>: "được chạm tới AI" và "được đụng hội thoại của họ Ở KÊNH NÀO". Trước khi tách,
            chỉ có hàng rào thứ nhất tồn tại — nên trưởng nhóm kênh K chạm được nhân viên B qua kênh
            K rồi chuyển luôn hội thoại của B ở kênh L, M, N. Hai câu hỏi khác nhau đọc từ một chỗ
            thì chúng không lệch nhau được.
            <para>
            Đặt vai <c>Leader</c>/<c>Owner</c> đòi <c>ChatDistribution.Manage</c> hoặc
            <c>Founder</c> từ bản vá F-1, nên đường "tự nâng mình lên trưởng nhóm để mở rộng phạm
            vi" không tồn tại.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.DocBoLoc(Lada.Framework.DTO.SmartTable.SmartTableParam,System.DateTimeOffset,System.TimeSpan)">
            <summary>
            Đọc bộ lọc của bảng thời lượng: khoảng thời gian, kênh, từ khoá.
            </summary>
            <remarks>
            <c>FromDate</c>/<c>ToDate</c> gửi lên là <b>ngày</b> theo giờ Việt Nam, nên phải dựng
            lại mốc bằng <paramref name="offset"/> của cửa sổ giờ làm chứ không dùng offset của máy
            chủ. Không làm thế thì báo cáo "hôm nay" trên một máy chủ chạy UTC bắt đầu từ 7 giờ
            sáng — đúng lớp lỗi lệch múi giờ đã cắn ở đợt bảo dưỡng xe (axios ép
            <c>toISOString()</c>).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.LayNhanVienChatAsync(System.Int32)">
            <summary>
            Tập nhân viên đưa vào bảng thời lượng: người đang phụ trách kênh chat.
            </summary>
            <param name="chiKenh">Chỉ một kênh; <c>0</c> = mọi kênh</param>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.ThuTuNgay">
            <summary>Thứ tự ngày trong tuần theo cách người Việt đọc lịch: Thứ Hai trước, Chủ Nhật cuối.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.MoTaGioLam(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours)">
            <summary>
            Câu mô tả giờ làm <b>riêng</b> cho chip trạng thái, ví dụ
            "08:00–17:30, Thứ Hai–Thứ Bảy, nghỉ trưa 12:00–13:00".
            </summary>
            <remarks>
            Ca kéo tới hết ngày in "đến hết ngày" chứ không in giờ kết thúc: trong bộ nhớ nó là
            <c>24:00</c>, và định dạng <c>hh\:mm</c> sẽ in thành "00:00" — "08:00–00:00" đọc như ca
            không có phút nào. In "23:59" cũng sai theo kiểu khác: người đọc hiểu phút cuối không
            tính, trong khi nó có tính.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.MoTaNgayLam(System.Collections.Generic.IReadOnlyCollection{System.DayOfWeek})">
            <summary>
            Gom ngày làm thành cụm cho gọn chip: đủ bảy ngày là "cả tuần"; chuỗi liên tiếp từ ba
            ngày trở lên viết "Thứ Hai–Thứ Sáu"; ngắn hơn thì liệt kê.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.ToWorkingHoursItem(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours)">
            <summary>
            Một cửa sổ giờ làm ở dạng giao diện đọc và <b>gửi lại được nguyên văn</b>: hết ngày in
            <c>23:59</c> (giá trị người dùng chọn), ngày làm là mã 2..8 tăng dần.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentPresenceService.MaNgay(System.DayOfWeek)">
            <summary><c>DayOfWeek</c> → mã ngày của cấu hình: 2 = Thứ Hai … 7 = Thứ Bảy, 8 = Chủ Nhật.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange">
            <summary>
            Một lần đổi người giữ hội thoại, mô tả đủ để ghi được nhật ký.
            </summary>
            <remarks>
            Gộp thành một lớp thay vì tám tham số rời: đường ghi này được gọi từ bốn chỗ khác nhau
            (phân công tay, nhả, chuyển tay, và máy phân phối ở giai đoạn D), và tám tham số cùng kiểu
            <c>int?</c>/<c>bool</c> đứng cạnh nhau là chỗ để hoán vị nhầm mà trình biên dịch không kêu.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange.ConversationId">
            <summary>Hội thoại đổi người</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange.NewStaffId">
            <summary>Người sắp nhận. <c>null</c> = gỡ phân công, hội thoại về hàng chờ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange.AssignReason">
            <summary>Vì sao người mới nhận. Bỏ qua khi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange.NewStaffId"/> để trống.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange.ReleaseReason">
            <summary>
            Vì sao người cũ thôi giữ — <b>thứ quyết định người cũ còn đọc được hội thoại không</b>
            (§6.2). Bỏ qua khi trước đó không ai giữ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange.IsAuto">
            <summary>Máy quyết hay người quyết</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange.ActorUserId">
            <summary>Người bấm nút. <c>null</c> = máy quyết.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange.ActorUserName">
            <summary>Tên người bấm nút, ghi vào cột audit</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange.Note">
            <summary>Ghi chú của người thao tác</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAssignmentJournal">
            <summary>
            Sổ phân công hội thoại — <b>đường ghi duy nhất</b> vào
            <see cref="T:Lada.Framework.Data.Domains.SocialChat.ChatConversationAssignment"/>.
            </summary>
            <remarks>
            <para>
            Tách khỏi <c>SocialChatService</c> vì bảng này quyết định phạm vi dữ liệu chứ không chỉ ghi
            nhật ký: mức <c>Self</c> của hàng rào đọc <c>KeepReadAccess</c> ở đây (§6.2, PP-10). Mọi
            đường đổi người — phân công tay hôm nay, máy phân phối ở giai đoạn D, thu hồi quá hạn ở
            giai đoạn E — đều phải đi qua đúng lớp này. Chép luật ghi ra chỗ thứ hai là để hai chỗ đó
            lệch nhau, và một chỗ lệch nghĩa là một lượt giữ không ai đọc được hoặc hai lượt cùng mở.
            </para>
            <para>
            <b>Không</b> chấm phạm vi. Người gọi đã nạp hội thoại qua
            <c>SocialChatService.LoadConversationInScopeAsync</c>; lớp này tin điều đó và chỉ lo ghi
            đúng. Đặt thêm một lớp chấm quyền ở đây là dựng hàng rào thứ hai để nó lệch với hàng rào thật.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAssignmentJournal.RecordChangeAsync(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange)">
            <summary>
            Ghi một lần đổi người: đóng lượt đang mở của người cũ (nếu có) và mở một lượt mới cho
            người mới (nếu có).
            </summary>
            <remarks>
            Đóng <b>mọi</b> lượt đang mở chứ không chỉ lượt của người cũ đã biết: nếu vì bất kỳ lý
            do nào dữ liệu có hai lượt cùng mở, lần đổi người kế tiếp phải khép chúng lại chứ không
            bỏ mặc — một lượt mở treo lơ lửng là một người giữ quyền đọc mãi mãi.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAssignmentJournal.ApplyChangeAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange)">
            <summary>
            Ghi cột <c>AssignedStaffId</c> trên hội thoại <b>và</b> dòng lịch sử tương ứng, trong
            <b>một</b> giao dịch.
            </summary>
            <remarks>
            <para>
            Hai lượt ghi này phải cùng sống hoặc cùng chết: nhật ký hỏng giữa chừng là người cũ giữ
            quyền đọc <b>vĩnh viễn</b> và không đường nào đối soát được (finding FB-5 của giai đoạn
            B). Giao dịch vốn nằm ở <c>SocialChatService.GhiDoiNguoiAsync</c> — nhưng giai đoạn C
            mở <b>đường ghi thứ ba</b> vào cột ấy (uỷ quyền tạm khi nghỉ dài, và nhả hội thoại khi
            gỡ người khỏi kênh — sổ nợ PP-18), mà cả hai chạy từ service khác. Chép lại khối giao
            dịch sang chỗ thứ hai là để hai chỗ đó lệch nhau, nên nó chuyển hẳn về đây.
            </para>
            <para>
            <b>Bản đẩy realtime cố ý KHÔNG nằm trong hàm này</b>, và người gọi phải tự gọi nó
            <i>sau</i> khi hàm này trả về: gửi đi rồi rollback là báo cho mọi màn hình một sự thật
            chưa từng xảy ra. Thứ tự bắt buộc vẫn là thu hồi phạm vi trước, đẩy cập nhật sau.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAssignmentJournal.TryAssignUnclaimedAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange,System.DateTimeOffset)">
            <summary>
            <b>So sánh rồi đặt</b>: chỉ gán hội thoại khi nó <i>còn</i> chưa có ai giữ. Trả
            <c>true</c> nếu lượt này giành được, <c>false</c> nếu người khác đã giữ trước.
            </summary>
            <remarks>
            <para>
            Máy phân phối chạy trên webhook, và hai tin của cùng một khách đến cách nhau vài chục
            mili-giây là chuyện bình thường. Đọc rồi ghi thì hai luồng cùng đọc thấy <c>null</c> và
            cùng ghi — khách được giao cho hai người, mỗi người thấy một nửa sự thật. Điều kiện
            <c>AssignedStaffId IS NULL</c> vì thế phải nằm trong <b>chính câu lệnh ghi</b>, để
            database phân xử chứ không phải code.
            </para>
            <para>
            Cố ý <b>không</b> dùng khuôn <c>RowVersion + retry</c> của <c>WalletTransferService</c>:
            ở đó nhiều cột đổi cùng lúc và lượt thua phải thử lại trên dữ liệu mới; ở đây đúng một
            cột chuyển từ <c>null</c> sang có giá trị, và lượt thua <b>không có gì để thử lại</b> —
            hội thoại đã có người, việc đã xong. Thử lại chỉ sinh ra một lần đổi người mà không ai
            yêu cầu.
            </para>
            <para>
            Hàm này ghi <b>cả</b> cột trên hội thoại lẫn dòng lịch sử trong một giao dịch, y như
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAssignmentJournal.ApplyChangeAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange)"/>; và cũng y như thế, bản đẩy realtime nằm ngoài.
            </para>
            </remarks>
            <param name="conversation">
            Thực thể hội thoại. Khi giành được, hàm cập nhật luôn các cột trên thực thể này để bản
            đẩy realtime và mọi lời gọi phía sau nhìn thấy đúng người vừa nhận.
            </param>
            <param name="change">Lượt đổi người, phải có <c>NewStaffId</c></param>
            <param name="now">Mốc gán. Truyền vào thay vì đọc đồng hồ để bản phát lại đặt được mốc lịch sử.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAssignmentJournal.TryReleaseOverdueAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange,System.Int32,System.DateTimeOffset)">
            <summary>
            <b>Thu hồi quyền xem</b> của một người trên một hội thoại, kể cả khi họ đã thôi giữ từ lâu.
            </summary>
            <remarks>
            <para>
            Cờ <c>KeepReadAccess</c> chỉ được ghi lúc đóng một lượt đang mở (§6.2), nên có một khe
            hở mà chính người sắp bị cắt điều khiển được: họ tự nhả trước với một lý do hành chính,
            lượt của họ đóng lại với cờ giữ quyền, hội thoại về hàng chờ — và từ đó không còn lượt
            nào để quản lý đóng. Chú thích của <c>ChatReleaseReasonRules</c> đã gọi tên đúng mối lo
            này ("người bấm nút chuyển hội thoại thường chính là người có động cơ giữ lại quyền
            xem") nhưng mới bịt đường sửa cờ trên giao diện, chưa bịt đường tự chọn lý do.
            </para>
            <para>
            Không sửa dòng lịch sử cũ — lịch sử là append-only. Thay vào đó ghi THÊM một dòng đã
            đóng sẵn mang cờ cắt; luật gộp theo cặp (người, hội thoại) của
            <c>ChatVisibilityResolver</c> đòi MỌI lượt còn quyền đọc, nên đúng một dòng như vậy là
            đủ cắt.
            </para>
            </remarks>
            <param name="reason">Bắt buộc là lý do CẮT quyền xem; lý do khác bị từ chối</param>
            <summary>
            Nhả hội thoại quá hạn khỏi người đang giữ, <b>có so-sánh-rồi-đặt</b>: chỉ nhả khi hội thoại
            vẫn đang ở tay <paramref name="expectedStaffId"/> và khách vẫn đang chờ. Trả <c>false</c>
            khi thua — hội thoại đã đổi tay, hoặc vừa được trả lời.
            </summary>
            <remarks>
            Cùng khuôn với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAssignmentJournal.TryAssignUnclaimedAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange,System.DateTimeOffset)"/>, chỉ ngược chiều: một câu <c>UPDATE</c>
            có điều kiện để <b>database</b> phân xử lượt tranh chấp, dòng nhật ký chỉ ghi khi câu ấy
            thắng, và cả hai nằm trong một giao dịch. Bản đầu của giai đoạn E dùng
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAssignmentJournal.ApplyChangeAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange)"/> — nó ghi lại <b>cả dòng</b> từ ảnh chụp đầu lượt quét và xoá
            mất câu trả lời mà sale vừa kịp gửi.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAssignmentJournal.GetHistoryAsync(System.Int32)">
            <summary>
            Lịch sử phân công của một hội thoại, mới nhất lên đầu — dùng cho màn "ai từng cầm hội
            thoại này".
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentJournal">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAssignmentJournal" />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentJournal.TryAssignUnclaimedAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange,System.DateTimeOffset)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentJournal.ApplyChangeAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentJournal.RecordChangeAsync(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentJournal.TryReleaseOverdueAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange,System.Int32,System.DateTimeOffset)">
            <inheritdoc />
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentJournal.GetHistoryAsync(System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentJournal.ResolveActorName(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange)">
            <summary>Tên ghi vào cột audit; máy quyết thì nói thẳng là máy</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentJournal.Truncate(System.String)">
            <summary>Ghi chú đến từ client — cắt đúng bề rộng cột để một chuỗi dài không làm hỏng cả lượt ghi</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAttachmentResult">
            <summary>Kết quả lưu một ảnh đính kèm của khung chat.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAttachmentResult.Success">
            <summary>Lưu được hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAttachmentResult.Error">
            <summary>Lý do đọc được cho nhân viên khi không lưu được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAttachmentResult.SystemPath">
            <summary>Đường dẫn tệp trên đĩa máy chủ — do MÁY CHỦ sinh, không bao giờ nhận từ client</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAttachmentResult.Url">
            <summary>Đường dẫn công khai để khung chat hiển thị lại ảnh</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAttachmentService">
            <summary>
            Lưu ảnh nhân viên đính kèm vào tin nhắn chat.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAttachmentService.SaveImageAsync(Microsoft.AspNetCore.Http.IFormFile,System.String)">
            <summary>Kiểm tra và lưu một ảnh, trả về đường dẫn đĩa + đường dẫn công khai.</summary>
            <param name="file">Tệp ảnh nhận từ multipart</param>
            <param name="subFolder">
            Thư mục con dưới <c>Images/Chat</c>. <b>Luôn là hằng số của máy chủ</b> (ví dụ
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAttachmentService.QuickReplySubFolder"/>), không bao giờ lấy từ request.
            <c>null</c> (mặc định) = đường cũ <c>Images/Chat/{năm}/{tháng}/{ngày}</c> của ảnh gửi kèm tin nhắn;
            có giá trị thì ghi vào <c>Images/Chat/{subFolder}/{năm}/{tháng}</c>.
            </param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAttachmentService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatAttachmentService"/>
            <remarks>
            <para>
            <b>Vì sao không dùng thẳng <c>IUnifiedMediaService.ProcessImageAsync</c> như các phân hệ
            khác:</b> hàm đó tối ưu mọi ảnh sang WebP rồi xoá bản gốc, mà Zalo chỉ nhận <b>jpg/png</b>
            — tệp vừa lưu sẽ không gửi đi được. Ở đây tệp gốc được giữ nguyên định dạng. Không mất gì
            về dung lượng vì giới hạn 1 MB của Zalo đã chặn sẵn ảnh lớn.
            </para>
            <para>
            <b>Tên tệp do máy chủ sinh.</b> Thư mục media được một site riêng phục vụ, ngoài pipeline
            .NET, nên <b>không có bất kỳ lớp chấm quyền nào</b> — ai biết đường dẫn là xem được. Giữ
            tên tệp người dùng đặt là để lộ tên gốc và làm đường dẫn đoán được. Cùng lý do với
            <c>TruckMaintenanceMediaService.ProcessPdfAsync</c>.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAttachmentService.MaxImageBytes">
            <summary>
            Trần kích thước ảnh. Bằng đúng giới hạn Zalo công bố cho API tải ảnh lên — chặn tại
            đây thì nhân viên biết ngay, thay vì gửi xong mới nhận một mã lỗi của Zalo.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAttachmentService.QuickReplySubFolder">
            <summary>
            Thư mục con của ảnh mẫu tin nhắn nhanh (docs/plan-tin-nhan-nhanh-chat.md §2.2).
            <para>
            Nằm riêng khỏi ảnh gửi kèm tin nhắn vì hai loại có vòng đời khác nhau: ảnh mẫu được <b>nhiều</b>
            tin trỏ tới và không bao giờ bị xoá khi xoá mẫu (nguyên tắc 1.4), nên việc dọn tệp mồ côi sau
            này (sổ nợ TN-5) phải quét được đúng thư mục của nó mà không đụng ảnh hội thoại.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAttachmentService.FolderName">
            <summary>Thư mục con dưới gốc media</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAttachmentService.SubFolderPattern">
            <summary>
            Tên thư mục con hợp lệ. Hẹp tới mức không chứa được dấu phân cách đường dẫn hay <c>..</c>:
            tham số này hôm nay chỉ nhận hằng số, nhưng hàm ghi tệp xuống đĩa không được phép tin điều đó.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAttachmentService.DetectImageExtensionAsync(Microsoft.AspNetCore.Http.IFormFile)">
            <summary>
            Phần mở rộng suy từ chữ ký nội dung, hoặc <c>null</c> nếu không phải JPG/PNG.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageBatch">
            <summary>Kết quả một lần nạp phủ sóng — dùng chung cho một lượt quét hoặc một trang.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageBatch.Empty">
            <summary>Không kênh nào, không ai — kết quả của một lần hỏi rỗng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageBatch.Channels">
            <summary>
            Phủ sóng theo <c>ChatChannelId</c> — có mặt <b>mọi</b> kênh được hỏi (mã <c>&gt; 0</c>). Kênh
            không có ứng viên nào mang tập khoảng rỗng: không ai vào ca, đồng hồ không chạy.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageBatch.WorkingHours">
            <summary>
            Giờ làm riêng của mọi người đã nạp (ứng viên + người gọi xin thêm), theo <c>StaffId</c> —
            đi ra từ <b>cùng một</b> truy vấn <c>ChatAgentPresence</c>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelCoverageService">
            <summary>
            Nạp dữ liệu cho đồng hồ hàng chờ (KC-18, §8.7 câu 3 + 3b) — <b>hàng loạt</b>, rồi giao cho hàm
            thuần <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.Build(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageCandidate},System.DateTimeOffset,System.DateTimeOffset)"/>.
            </summary>
            <remarks>
            <para>
            Hai nơi hỏi cùng một câu "khách ở hàng chờ đã chờ bao nhiêu phút có người trực": lượt quét báo
            trưởng nhóm (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService"/>) và cột "chờ bao lâu" trên giao diện
            (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContextProvider"/>). Một lớp nạp chung là để hai con số ấy không bao giờ
            khác nhau — cùng bài học của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules.WaitingSince(System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset},Lada.Framework.Data.Enums.ChatConversationStatus)"/>.
            </para>
            <para>
            <b>Số truy vấn không phụ thuộc số hội thoại hay số kênh:</b> một câu ứng viên cho mọi kênh, một
            câu giờ riêng (qua <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffWorkingHoursProvider"/>), một câu nhật ký Nghỉ / Tạm
            ngưng, một câu trạng thái nghỉ việc. Lượt quét chạy mỗi 2 phút với tới 200 hội thoại — hỏi theo
            từng hội thoại là N+1 trên đúng job nóng nhất.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelCoverageService.LoadAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},System.DateTimeOffset,System.DateTimeOffset,System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>
            Phủ sóng của các kênh trong <c>[from, to]</c>.
            </summary>
            <param name="chatChannelIds">Kênh cần phủ sóng — người gọi đã lọc <c>AutoDistribute</c></param>
            <param name="from">Mốc chờ <b>sớm nhất</b> trong các hội thoại cần đếm; dài quá <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.MaxSpan"/> thì bị cắt và ghi log</param>
            <param name="to">"Bây giờ"</param>
            <param name="alsoLoadWorkingHoursOf">
            Những người mà người gọi cần giờ riêng nhưng không phải ứng viên của kênh nào được hỏi —
            cột "chờ bao lâu" xin thêm người đang cầm hội thoại để đi chung <b>một</b> truy vấn giờ làm.
            </param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelCoverageService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelCoverageService"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelCoverageService.LoadAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},System.DateTimeOffset,System.DateTimeOffset,System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelService">
            <summary>
            Quản lý các kênh chat đã kết nối: luồng cấp quyền, giữ token, bật/tắt, xoá.
            <para>
            Đây là nơi DUY NHẤT trong hệ thống ghi và đọc token của kênh, và token
            luôn đi qua <see cref="T:Lada.Framework.Infrastructures.Services.ISecretProtector"/> — không có đường nào lưu thô.
            </para>
            <para>
            Luồng cấp quyền khác nhau theo nền tảng (Zalo dùng OAuth v4, Facebook dùng dán user token
            rồi tra <c>/me/accounts</c>) nên các phương thức ở đây gọi thẳng tên nền tảng. Đó là chủ ý:
            lõi độc lập nền tảng là <c>SocialChatService</c>, không phải lớp này.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelService.GetAllAsync">
            <summary>Danh sách kênh, mới nhất trước. Không trả token dưới bất kỳ dạng nào.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelService.GetByIdAsync(System.Int32)">
            <summary>Chi tiết một kênh. Không trả token dưới bất kỳ dạng nào.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelService.GetZaloAuthorizationLink">
            <summary>
            Dựng đường dẫn để admin của Zalo OA bấm vào và cấp quyền cho ứng dụng,
            kèm tham số <c>state</c> đã ký để nhận ra callback do LADA khởi tạo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelService.HandleZaloCallbackAsync(System.String,System.String,System.String)">
            <summary>
            Xử lý callback Zalo gọi về sau khi admin OA đồng ý cấp quyền:
            kiểm <c>state</c>, đổi <c>code</c> lấy token, tạo hoặc cập nhật kênh.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelService.GetFacebookAuthorizationLink(System.Int32)">
            <summary>
            Dựng đường dẫn Facebook Login for Business để quản trị viên bấm vào và tự cấp quyền,
            kèm tham số <c>state</c> đã ký và <b>buộc vào chính người bấm</b>.
            <para>
            Chuỗi <c>state</c> trả về cũng là thứ giao diện giữ lại để hỏi danh sách Page ở bước
            sau — token không bao giờ đi qua trình duyệt.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelService.HandleFacebookCallbackAsync(System.String,System.String)">
            <summary>
            Xử lý lần chuyển hướng Facebook gọi về sau khi quản trị viên cấp quyền: kiểm
            <c>state</c>, đổi <c>code</c> lấy token, đổi tiếp sang bản dài hạn rồi giữ tạm trong
            bộ nhớ máy chủ để bước chọn Page dùng lại.
            <para>
            KHÔNG tạo kênh ở đây: quản trị viên còn phải chọn Page nào trong số Page họ quản lý.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelService.ListFacebookPagesAsync(System.String,System.String,System.Int32)">
            <summary>
            Danh sách Facebook Page mà quản trị viên đang quản lý.
            Kết quả KHÔNG chứa token của Page nào — xem <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.FacebookPageItem"/>.
            <para>
            Hai nguồn token, truyền đúng một trong hai: <paramref name="state"/> của một phiên
            Facebook Login vừa xong (đường chuẩn), hoặc <paramref name="userAccessToken"/> dán tay
            từ Graph API Explorer (đường dự phòng khi chưa cấu hình xong ứng dụng Facebook).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelService.ConnectFacebookPageAsync(System.String,System.String,System.String,System.Int32,System.String)">
            <summary>
            Kết nối một Facebook Page thành kênh chat: lấy Page access token của đúng Page được
            chọn, mã hoá rồi lưu.
            <para>
            Nguồn token giống <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelService.ListFacebookPagesAsync(System.String,System.String,System.Int32)"/>. Phiên cấp quyền sống 10 phút và
            dùng được nhiều lần trong khoảng đó — kết nối liền mấy Page không phải đăng nhập lại.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelService.ResubscribeFacebookPageAsync(System.Int32)">
            <summary>
            Đăng ký lại webhook (<c>subscribed_apps</c>) cho một kênh Facebook đã lưu, bằng chính
            Page access token đang giữ (SC-20). Dành cho kênh kết nối trước bản vá này, hoặc khi
            bước đăng ký lúc kết nối thất bại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelService.SetActiveAsync(System.Int32,System.Boolean,System.Int32,System.String)">
            <summary>Bật hoặc tắt một kênh. Kênh tắt thì webhook bỏ qua tin của nó và không gửi ra được.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelService.DeleteAsync(System.Int32,System.Int32,System.String)">
            <summary>Xoá mềm một kênh.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelService.RefreshExpiringTokensAsync(System.TimeSpan,System.Threading.CancellationToken)">
            <summary>
            Làm mới token của mọi kênh sắp hết hạn. Job Hangfire gọi định kỳ.
            Trả về số kênh đã làm mới thành công.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.StateSecretConfigKey">
            <summary>Khoá cấu hình dùng để ký tham số <c>state</c> của luồng OAuth</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.StateTimeToLive">
            <summary>
            Thời hạn của tham số <c>state</c>. Authorization code của Zalo sống 10 phút, nhưng
            admin còn phải chọn OA và bấm đồng ý trước đó nên cửa sổ phải rộng hơn thế.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.PendingTokenCachePrefix">
            <summary>
            Tiền tố khoá của token Facebook đang chờ chọn Page. Cố ý KHÔNG khai vào
            <c>CacheKeys</c> và cố ý KHÔNG đi qua <c>ICacheService</c>: controller
            <c>/api/Cache/GetEntries</c> in thẳng giá trị thô của mọi mục đi qua đường đó ra HTTP.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.IssuedStateCachePrefix">
            <summary>
            Tiền tố khoá của sổ <c>state</c> đã phát hành cho luồng Facebook, ánh xạ sang mã người
            dùng đã bấm nút.
            <para>
            Chữ ký HMAC một mình KHÔNG đủ: nó chứng minh state do LADA sinh ra, nhưng không nói
            state đã được tiêu chưa. Mà state thì nằm trên URL — trong nhật ký truy cập, trong lịch
            sử trình duyệt. Ai nhặt được một chuỗi còn hạn có thể tự chạy lại lượt cấp quyền bằng
            tài khoản Facebook của họ và ghi đè token đang chờ của quản trị viên. Sổ này khoá điều
            đó lại: state chỉ tiêu được đúng một lần (RFC 6749 §10.12).
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.IssuedStateTimeToLive">
            <summary>
            Hạn của một <c>state</c> đã phát hành nhưng chưa dùng. Ngắn hơn hẳn
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.StateTimeToLive"/> (con số của luồng Zalo) nhưng vẫn đủ rộng cho một lượt
            đăng nhập Facebook có xác thực hai bước và màn chọn Trang, chọn Doanh nghiệp.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.PendingTokenTimeToLive">
            <summary>
            Token chờ chọn Page sống 10 phút — đủ để nhìn danh sách rồi bấm kết nối vài Page liền
            nhau, ngắn hơn hẳn 60 ngày tuổi thọ thật của nó.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.GetAllAsync">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.GetByIdAsync(System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.FillOrganizationAsync(System.Collections.Generic.IReadOnlyCollection{Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatChannelItem})">
            <summary>
            Điền tên bưu cục và số nhân viên phụ trách cho một trang danh sách kênh — hai lượt tra
            cho cả trang, không tra từng dòng (cùng cách <c>SearchConversationsAsync</c> điền tên
            người phân công).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.GetZaloAuthorizationLink">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.HandleZaloCallbackAsync(System.String,System.String,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.GetFacebookAuthorizationLink(System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.HandleFacebookCallbackAsync(System.String,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.ListFacebookPagesAsync(System.String,System.String,System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.ConnectFacebookPageAsync(System.String,System.String,System.String,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.ResubscribeFacebookPageAsync(System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.ResolveUserTokenAsync(System.String,System.String,System.Int32)">
            <summary>
            Lấy user access token dài hạn từ một trong hai nguồn.
            <para>
            Đường chuẩn là <paramref name="state"/> của phiên Facebook Login vừa xong: token đã
            được đổi sang bản dài hạn ngay lúc callback và nằm trong bộ nhớ máy chủ, nên ở đây chỉ
            việc lấy ra — đổi lần nữa là thừa một lượt gọi Graph API.
            </para>
            <para>
            Đường dự phòng là token dán tay. Bước đổi dài hạn khi đó là bắt buộc chứ không phải tối
            ưu: Page access token thừa hưởng tuổi thọ của user token sinh ra nó. Lấy Page token từ
            một user token ngắn hạn thì vài giờ sau kênh chết im lặng, và không có job nào làm mới
            được vì Facebook không có refresh token.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.PendingFacebookToken">
            <summary>
            User access token dài hạn đang chờ quản trị viên chọn Page, buộc vào người đã cấp quyền.
            Chỉ nằm trong RAM và chỉ sống <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.PendingTokenTimeToLive"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.PendingFacebookToken.#ctor(System.String,System.Int32)">
            <summary>
            User access token dài hạn đang chờ quản trị viên chọn Page, buộc vào người đã cấp quyền.
            Chỉ nằm trong RAM và chỉ sống <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.PendingTokenTimeToLive"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.ResolvePagesAsync(System.String,System.String,System.Int32)">
            <summary>
            Lấy user token dài hạn rồi hỏi danh sách Page.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.SetActiveAsync(System.Int32,System.Boolean,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.DeleteAsync(System.Int32,System.Int32,System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.RefreshExpiringTokensAsync(System.TimeSpan,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.RefreshOneAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,System.Threading.CancellationToken)">
            <summary>
            Làm mới token của một kênh.
            <para>
            Refresh token của Zalo chỉ dùng được MỘT LẦN: gọi xong là bản cũ chết, và access token cũ
            cũng hết hiệu lực ngay. Vì vậy cặp mới phải được ghi xuống trong một transaction — mất nó
            là kênh chết im lặng, không có lỗi nào báo cho tới khi nhân viên gửi tin và bị từ chối.
            </para>
            <para>
            Lời gọi HTTP nằm NGOÀI transaction có chủ ý: giữ transaction mở suốt một lượt gọi mạng
            là khoá bảng lâu vô ích. Cặp token là hai cột của cùng một dòng nên một lệnh cập nhật
            đã đủ nguyên tử; transaction ở đây là để lời hứa đó tường minh và kiểm được bằng test.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.TryProtect(System.String,System.String@)">
            <summary>
            Mã hoá một token và CHỨNG MINH nó đã được mã hoá. <see cref="T:Lada.Framework.Infrastructures.Services.ISecretProtector"/> cố ý
            lưu thô khi thiếu <c>Security:SecretKey</c> (chấp nhận được với mật khẩu email trên dev),
            nhưng Page access token không có hạn dùng và refresh token Zalo sống ba tháng — để chúng
            nằm thô trong database là để bất kỳ ai đọc được bảng hay bản backup nhắn tin thay LADA.
            Thiếu khoá thì hỏng ồn ào ngay lúc kết nối, còn hơn hở im lặng cho tới lúc bị phát hiện.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.FindChannelAsync(Lada.Framework.Data.Enums.SocialPlatform,System.String)">
            <summary>
            Tìm kênh theo nền tảng + định danh nền tảng, bản mới nhất trước.
            Không lọc theo <c>IsActive</c>: cấp quyền lại cho một kênh đang tắt vẫn phải cập nhật
            đúng bản ghi đó chứ không sinh bản ghi thứ hai.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.BuildState">
            <summary>
            Chuỗi state = "{giây epoch}.{nonce}.{chữ ký HMAC}". Chỉ callback do LADA khởi tạo mới ký đúng,
            và chữ ký phủ luôn dấu thời gian nên không kéo dài hạn của một state cũ được.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.TryValidateState(System.String,System.String@)">
            <summary>
            Kiểm chữ ký và hạn dùng của một chuỗi <c>state</c>, trả ra phần nonce để bên gọi đọc
            tiếp nếu cần. Cả hai luồng cấp quyền dùng chung hàm này — thuật toán ký của repo đã bị
            chép thành hai bản (ở đây và <c>AdsConnectionService</c>), đừng thêm bản thứ ba.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.BuildUserBoundState(System.Int32)">
            <summary>
            Bản <c>state</c> có buộc thêm mã người dùng: nonce mang dạng <c>"{userId}-{GUID}"</c>.
            <para>
            Dấu nối là gạch ngang chứ không phải dấu chấm — dấu chấm là ký tự tách của chính chuỗi
            <c>state</c>, thêm một dấu nữa là hàm kiểm thấy 4 phần rồi từ chối sạch.
            </para>
            <para>
            Luồng Zalo không cần thứ này vì callback của nó tạo kênh xong ngay trong một lần gọi;
            luồng Facebook thì còn một bước chọn Page ở phiên đăng nhập khác, nên phải biết token
            đang chờ là của ai.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.TryReadUserBoundState(System.String,System.Int32@)">
            <summary>
            Kiểm <c>state</c> rồi đọc ra mã người dùng đã khởi tạo luồng cấp quyền.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelService.Sign(System.String)">
            <summary>
            Ký payload của tham số <c>state</c>.
            <para>
            Chuỗi kết nối DB là đường lui — vẫn là bí mật chỉ máy chủ biết. Nhưng KHÔNG có đường lui
            nào là hằng số trong mã nguồn: khoá HMAC nằm trong repo thì ai đọc được repo cũng ký được
            state hợp lệ, tức là lớp chống CSRF duy nhất của endpoint công khai này biến mất. Thiếu
            cả hai nguồn thì ném lỗi, để hỏng ồn ào lúc cấu hình sai còn hơn hở im lặng.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookPageLookupResult">
            <summary>
            Kết quả bước hỏi danh sách Page trước khi kết nối kênh Facebook.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookPageLookupResult.Success">
            <summary>Hỏi được danh sách hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookPageLookupResult.Pages">
            <summary>Danh sách Page, không kèm token</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookPageLookupResult.Message">
            <summary>Lý do đọc được cho quản trị viên khi hỏi không được</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatTokenRefreshReport">
            <summary>Kết quả một lượt job làm mới token.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatTokenRefreshReport.Considered">
            <summary>Số kênh tới ngưỡng phải làm mới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatTokenRefreshReport.Refreshed">
            <summary>Số kênh đã làm mới thành công</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatTokenRefreshReport.Failed">
            <summary>Số kênh làm mới thất bại — cần cấp quyền lại bằng tay</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService">
            <summary>
            Danh sách nhân viên phụ trách từng kênh chat, và cấu hình phân phối của kênh.
            <para>
            Đây là <b>nguồn của quan hệ kênh ↔ sale</b> mà cả hàng rào quyền xem
            (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatVisibilityResolver"/>) lẫn máy phân phối (giai đoạn D) đều đọc. Một bảng,
            một service, một luật — kênh nhiều sale và kênh một chủ dùng chung (§2.3, §6.4).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.GetByChannelAsync(System.Int32)">
            <summary>Danh sách nhân viên phụ trách một kênh, kể cả người đã thôi phụ trách</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.CanConfigureChannelAsync(System.Int32,System.Int32)">
            <summary>
            Người này có được cấu hình danh sách phụ trách của kênh đã cho không.
            <para>
            Quyền hạt <c>ChatChannel.StaffAssign</c> chỉ nói "được cấu hình sale phụ trách kênh",
            không nói <b>kênh nào</b>. Đường đọc danh sách phải hỏi thêm câu này, còn hai đường ghi
            tự hỏi lại bên trong — một quyền không kèm phạm vi là lỗ IDOR, đúng bài học của
            <c>docs/security-audit-2026-07-11.md</c>.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.SaveAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatChannelStaffModel,System.Int32,System.String)">
            <summary>Thêm hoặc sửa một dòng phụ trách</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.RemoveAsync(System.Int32,System.Int32,System.String)">
            <summary>
            Gỡ một người khỏi danh sách phụ trách — xoá mềm và đóng mốc <c>LeftAt</c>.
            <para>
            Không xoá cứng: dòng này là bằng chứng "ai từng phụ trách kênh nào", và ở giai đoạn sau
            nó còn là căn cứ đối chiếu của nhật ký phân phối.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.UpdateAssignmentSettingsAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.ChatChannelAssignmentModel,System.Int32,System.String)">
            <summary>Đổi bưu cục sở hữu và chế độ phân phối của một kênh</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.IsAssignableToChannelAsync(System.Int32,System.Int32)">
            <summary>
            Một nhân viên có được phép nhận phân công hội thoại của kênh này không.
            <para>
            Kênh còn ở chế độ <see cref="F:Lada.Framework.Data.Enums.ChatAssignmentMode.Shared"/> thì luôn <c>true</c>: ở đó
            phân công vẫn chỉ là nhãn và danh sách phụ trách thường còn trống, siết vào là phá
            luồng đang chạy thật (nguyên tắc số 1). Kênh đã bật hàng rào thì bắt buộc có tên trong
            danh sách phụ trách, vì phân công quyết định ai đọc được hội thoại.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.GetActiveStaffIdsAsync(System.Int32)">
            <summary>Mã những nhân viên đang phụ trách một kênh (đang hoạt động, chưa thôi phụ trách)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.GetDistributionCandidatesAsync(System.Int32)">
            <summary>
            Những nhân viên đang phụ trách một kênh <b>kèm trọng số</b> — điều kiện lọc số 1 của
            máy phân phối §3.3.
            </summary>
            <remarks>
            <para>
            Cùng phép lọc với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.GetActiveStaffIdsAsync(System.Int32)"/> (<c>IsActive</c> và chưa
            <c>LeftAt</c>) và <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.GetActiveStaffIdsAsync(System.Int32)"/> gọi thẳng vào đây, để định nghĩa
            "đang phụ trách kênh" chỉ tồn tại ở <b>một</b> chỗ. Hai truy vấn viết riêng cùng một
            phép lọc là hai truy vấn sẽ lệch nhau ở lần sửa thứ ba.
            </para>
            <para>
            <b>Không lọc theo <see cref="T:Lada.Framework.Data.Enums.ChatChannelRole"/>.</b> §3.3 chỉ đòi "có dòng
            <c>ChatChannelStaff</c> của kênh đó" — trưởng nhóm và chủ kênh cũng nhận khách, và trên
            dev họ đúng là những người có mặt. Muốn một trưởng nhóm không nhận khách thì hạ
            <c>IsActive</c> hoặc đặt <c>WeightOverride</c> nhỏ, chứ không phải bằng một luật ngầm
            trong máy phân phối.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.GetChannelLeaderIdsAsync(System.Int32)">
            <summary>
            Trưởng nhóm và chủ của một kênh — những người nhận cảnh báo về kênh ấy.
            </summary>
            <remarks>
            <para>
            Gộp cả <see cref="F:Lada.Framework.Data.Enums.ChatChannelRole.Leader"/> lẫn <see cref="F:Lada.Framework.Data.Enums.ChatChannelRole.Owner"/>,
            đúng như hai hàng rào phạm vi kênh đang có (<c>CanAdministerChannelAsync</c> ở lớp này
            và <c>KenhQuanLyDuocAsync</c> ở dịch vụ trạng thái sẵn sàng). Có mặt vì giai đoạn D
            suýt thêm bản sao thứ ba và thứ tư của cùng một truy vấn: định nghĩa "ai quản trị được
            kênh này" mà nằm ở bốn chỗ thì đến lần sửa thứ hai chúng đã lệch nhau.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.GetRestrictedStaffIdsAsync(System.Int32)">
            <summary>
            Tập nhân viên mà một kênh <b>giới hạn</b> phân công vào — dùng để thu hẹp ô gợi ý nhân viên.
            <para>
            Trả <c>null</c> khi kênh không giới hạn ai (kênh <see cref="F:Lada.Framework.Data.Enums.ChatAssignmentMode.Shared"/>,
            hoặc không truyền kênh nào): người gọi giữ nguyên danh sách của mình. Trả danh sách —
            kể cả danh sách rỗng — nghĩa là kênh có hàng rào và chỉ những người này được chọn.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.GetChannelPeerIdsOfConversationAsync(System.Int32)">
            <summary>
            Những người cùng phụ trách kênh của <b>một hội thoại cụ thể</b> — tập mà một người mức
            <c>DataAccessScope.SelfOnly</c> được phép chọn khi phân công hoặc chuyển khách
            (sổ nợ PP-38, kế hoạch §6.6, chốt 2026-08-30).
            </summary>
            <remarks>
            <para>
            <b>Cố ý KHÔNG hỏi <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.IsAssignableToChannelAsync(System.Int32,System.Int32)"/> và cũng không hỏi
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.GetRestrictedStaffIdsAsync(System.Int32)"/>.</b> Hàm thứ nhất trả <c>true</c> vô điều kiện
            cho kênh <c>Shared</c>, hàm thứ hai trả <c>null</c> ("không giới hạn ai") cho đúng kênh
            ấy — dùng cái nào ở đây cũng biến ô chọn của một sale thành danh bạ nhân sự cả công ty
            trên mọi kênh chưa bật hàng rào, tức trên TOÀN BỘ hệ thống trong lúc còn dry-run. Ở đây
            "cùng kênh" luôn có nghĩa là <b>có dòng phụ trách đang hoạt động</b>, bất kể chế độ.
            </para>
            <para>
            Ruột gọi lại đúng <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService.GetActiveStaffIdsAsync(System.Int32)"/> mà <c>staff/suggest</c> dùng —
            một luật, một truy vấn, hai hình dạng. Hội thoại tra không ra → danh sách rỗng, không
            ai chọn được. Fail-closed.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelStaffService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatChannelStaffService" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelStaffService.RoleFounder">
            <summary>Bỏ qua mọi ràng buộc phạm vi</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelStaffService.RoleDistributionManage">
            <summary>
            Quản trị phân phối chat của <b>toàn hệ thống</b> — quyền duy nhất mở được vai trò
            "Trưởng nhóm"/"Chủ kênh" và đổi được chế độ phân phối của một kênh.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelStaffService.IsDistributionCandidate">
            <summary>
            Định nghĩa <b>duy nhất</b> của "dòng phụ trách này là một ứng viên phân phối" — điều kiện
            lọc của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelStaffService.GetDistributionCandidatesAsync(System.Int32)"/>.
            </summary>
            <remarks>
            Công khai vì đồng hồ hàng chờ (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelCoverageService"/>, KC-18 thiết kế
            mục 5) đòi "đúng tập ứng viên của kênh" nhưng <b>không gọi được</b> hàm trên: lớp này phụ
            thuộc bản đẩy realtime, bản đẩy realtime phụ thuộc bối cảnh cột "chờ bao lâu", và bối cảnh
            ấy lại cần tập ứng viên — một vòng phụ thuộc mà DI chỉ báo lúc chạy. Nên bên kia truy vấn
            bảng trực tiếp (một câu cho mọi kênh), và dùng chung biểu thức này thay vì chép điều kiện.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelStaffService.OutOfChannelScopeMessage">
            <summary>
            Một thông điệp duy nhất cho mọi ca "bạn không quản trị được kênh này" — không phân biệt
            kênh không tồn tại với kênh ngoài phạm vi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelStaffService.IsGlobalChatAdminAsync(System.Int32)">
            <summary>
            Quản trị phân phối chat của toàn hệ thống: <c>Founder</c> hoặc
            <c>ChatDistribution.Manage</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelStaffService.CanAdministerChannelAsync(System.Int32,System.Int32,System.Nullable{System.Boolean})">
            <summary>
            Người này có quản trị được danh sách phụ trách của kênh đã cho không.
            <para>
            Quyền hạt <c>ChatChannel.StaffAssign</c> nói "được cấu hình sale phụ trách kênh", nó
            KHÔNG nói "kênh nào". Thiếu bước thu hẹp theo kênh thì bất kỳ ai có quyền ấy cũng ghi
            được vào mọi kênh của mọi bưu cục — chính là finding F-1 của cổng chất lượng giai đoạn A.
            </para>
            <para>
            Hai đường được đi qua: quản trị phân phối toàn hệ thống, hoặc đang là trưởng nhóm / chủ
            của <b>chính kênh đó</b>. Kênh chưa ai phụ trách thì chỉ đường thứ nhất mở — người đầu
            tiên của một kênh phải do quản trị đặt, không tự nhận.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelStaffService.IsStaffInScopeAsync(System.Int32,System.Int32)">
            <summary>
            Mã nhân viên gửi lên có nằm trong phạm vi nhân sự của người gọi không — <b>cùng luật</b>
            với ô gợi ý <c>staff/suggest</c> và với đường phân công hội thoại.
            </summary>
            <remarks>
            <c>Founder</c> đi thẳng qua nhánh không ràng buộc, đúng luật chung của hệ thống. Người
            quản trị phân phối bình thường vẫn bị <c>DataAccessScope</c> của chính họ giới hạn —
            hệ quả bắt buộc: tài khoản làm việc này phải được đặt phạm vi <c>All</c> hoặc
            <c>ManagedTeam</c> cho đúng, và điều đó nằm trong checklist production của kế hoạch.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelStaffService.DescribeStaffingBreakAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,Lada.Framework.Data.Domains.SocialChat.ChatChannelStaff)">
            <summary>
            Gỡ (hoặc ngừng) dòng phụ trách này có làm kênh mất người không — trả về câu giải thích
            khi có, <c>null</c> khi gỡ được.
            <para>
            Chỉ chặn trên kênh đã bật hàng rào. Kênh <c>Shared</c> giữ nguyên hành vi hôm nay: ở đó
            danh sách phụ trách mới chỉ là nhãn, làm rỗng nó không giấu hội thoại của ai (nguyên tắc
            số 1).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelStaffService.NhaHoiThoaiKhiThoiPhuTrachAsync(System.Int32,System.Int32,System.Int32,System.String,System.DateTimeOffset)">
            <summary>
            Nhả về hàng chờ những hội thoại mà người vừa thôi phụ trách kênh còn đang giữ
            <b>trên chính kênh đó</b> (sổ nợ PP-18).
            </summary>
            <remarks>
            <para>
            Trước bản vá này, gỡ một sale khỏi kênh chỉ đóng dòng phụ trách;
            <c>ChatConversation.AssignedStaffId</c> giữ nguyên, nên nhánh <c>Self</c> của hàng rào
            vẫn cho họ ĐỌC <b>và GHI</b> những hội thoại ấy — kể cả gửi tin cho khách qua OA/Page
            của công ty. Cổng chất lượng giai đoạn B kết luận đây không phải lỗ <i>mở rộng</i> phạm
            vi (tập hội thoại đóng băng đúng lúc gỡ và chỉ co lại), nhưng khoảng trống quy trình thì
            có thật, và bằng chứng là <c>ChatReleaseReason.ThoiPhuTrachKenh = 9</c> khai từ giai
            đoạn B mà không đường nào phát ra.
            </para>
            <para>
            <b>Lọc theo CẶP (kênh, người), không chỉ theo người.</b> Một sale phụ trách nhiều kênh;
            lọc theo mỗi <c>StaffId</c> là gỡ họ khỏi một kênh lại nhả sạch hội thoại của kênh khác.
            </para>
            <para>
            <b>Người cũ vẫn ĐỌC được</b>: <c>KeepsReadAccess(ThoiPhuTrachKenh)</c> trả <c>true</c>
            theo §6.2 — thôi phụ trách kênh là chuyện hành chính, không phải lỗi của họ, và họ cần
            tra lại việc mình đã làm. Cái bị cắt là quyền GHI, vì phạm vi ghi không có nhánh "từng
            giữ" (<c>BuildWritableConversationFilter</c>).
            </para>
            <para>
            Chạy trong <b>một</b> giao dịch cho mỗi hội thoại qua
            <c>IChatAssignmentJournal.ApplyChangeAsync</c> — đường ghi duy nhất. Không tự
            <c>UpdateAsync</c> hội thoại rồi ghi nhật ký riêng: hỏng giữa chừng là người cũ giữ
            quyền vĩnh viễn mà không đường nào đối soát (FB-5).
            </para>
            </remarks>
            <returns>Số hội thoại đã nhả</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelStaffService.DemHoiThoaiDangGiuAsync(System.Int32,System.Collections.Generic.List{System.Int32})">
            <summary>
            Số hội thoại chưa đóng mà từng người trong danh sách còn đang giữ trên một kênh.
            </summary>
            <remarks>
            Dùng cho giao diện <c>/kenh-chat</c>: nút Gỡ phải nói trước "người này còn giữ N hội
            thoại, gỡ đi thì chúng về hàng chờ" — yêu cầu tối thiểu của PP-18. Một lời gọi cho cả
            danh sách, không phải một lời gọi mỗi dòng.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConnectionRegistry">
            <summary>
            Sổ kết nối SignalR đang mở của phân hệ chat: ai đang nối bằng những kết nối nào, và mỗi kết
            nối đang ở trong những nhóm nào.
            <para>
            SignalR <b>không</b> cho liệt kê thành viên của một nhóm, mà thu hồi phòng thì bắt buộc phải
            biết <c>ConnectionId</c>. Đó là lý do lớp này tồn tại: không có nó thì hàng rào quyền xem chỉ
            chặn được REST, còn một kết nối đã mở vẫn tiếp tục nhận nguyên văn tin của khách cho tới khi
            người dùng đóng tab (finding F-3 của cổng chất lượng giai đoạn A).
            </para>
            <para>
            <b>Giới hạn đã biết — sổ nợ PP-16.</b> Sổ này nằm trong bộ nhớ của <b>một</b> tiến trình. Khi
            API chạy nhiều bản sau Redis backplane, mỗi bản chỉ biết kết nối của chính mình, nên thu hồi
            chỉ chắc chắn cho những kết nối đang bám vào bản xử lý lời gọi. Bản đầy đủ cần đưa sổ này
            xuống Redis; ghi rõ ở đây để không ai đọc nhầm rằng thu hồi đã kín trong mọi cấu hình triển
            khai. Mọi đường REST vẫn chặn đúng trong mọi trường hợp — đây là lớp phòng thủ thứ hai.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConnectionRegistry.Track(System.Int32,System.String)">
            <summary>Ghi nhận một kết nối vừa mở của một người</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConnectionRegistry.Forget(System.String)">
            <summary>Xoá một kết nối vừa đóng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConnectionRegistry.TrackGroup(System.String,System.String)">
            <summary>Ghi nhận kết nối vừa vào một nhóm</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConnectionRegistry.ForgetGroup(System.String,System.String)">
            <summary>Ghi nhận kết nối vừa rời một nhóm</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConnectionRegistry.ConnectionsOf(System.Int32)">
            <summary>Những kết nối đang mở của một người, kèm nhóm mà từng kết nối đang ở trong</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConnectionRegistry.ConnectedUserIds">
            <summary>Mọi người đang có kết nối mở — dùng khi một thay đổi chạm phạm vi của tất cả</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatConnectionRegistry">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConnectionRegistry"/>
            <remarks>
            Đăng ký <b>singleton</b>: vòng đời của nó là vòng đời tiến trình, không phải vòng đời một
            lời gọi. Dùng <see cref="T:System.Collections.Concurrent.ConcurrentDictionary`2"/> vì <c>OnConnectedAsync</c> và
            <c>OnDisconnectedAsync</c> chạy song song trên nhiều luồng.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatConnectionRegistry._connections">
            <summary>Kết nối → người sở hữu và các nhóm nó đang ở trong</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConversationWriter">
            <summary>
            Những câu <c>UPDATE</c> ghi <b>thẳng</b> vào <c>ChatConversation</c>, không đi qua bộ theo
            dõi thay đổi của EF: giành hội thoại có điều kiện, và đóng dấu đã-báo hàng chờ.
            </summary>
            <remarks>
            <para>
            Tách thành interface riêng vì đúng một lý do, và nói thẳng ra để người sau không tưởng đây
            là một tầng trừu tượng vô cớ: <c>ExecuteUpdateAsync</c> là một tính năng của <b>trình dịch
            truy vấn EF Core</b>, không phải của <c>IQueryable</c>. Kho dữ liệu giả của bộ test dựng
            trên <c>EnumerableQuery</c> nên nó ném lỗi ở đó. Không có seam này thì mọi ca test chạm tới
            máy phân phối đều chết vì hạ tầng, và cách chữa duy nhất còn lại là đọc-rồi-ghi — tức là bỏ
            đúng cái ràng buộc đang cần kiểm.
            </para>
            <para>
            <b>Bản giả phải giữ nguyên ràng buộc của bản thật</b> — chỉ nhận khi <c>AssignedStaffId</c>
            còn <c>null</c> và hội thoại chưa xoá. Một bản giả bỏ qua đúng cái giới hạn mà bản thật có
            là một bản giả mời lỗi đi qua (bài học <c>FakeChatStaffDirectory</c> ở L9). Nhưng bản giả
            <b>không</b> chứng minh được tính nguyên tử — việc đó chỉ có database thật làm được, nên ca
            tranh chấp thật chạy trên SQL Server.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConversationWriter.ClaimAsync(System.Int32,System.Int32,System.DateTimeOffset)">
            <summary>
            Trả về số dòng đổi được: <c>1</c> nếu giành được hội thoại, <c>0</c> nếu người khác đã
            giữ trước hoặc hội thoại đã bị xoá.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConversationWriter.MarkQueueAlertedAsync(System.Int32,System.DateTimeOffset)">
            <summary>
            Đóng dấu "đã báo trưởng nhóm về hội thoại này", chạm <b>đúng hai cột</b>.
            </summary>
            <remarks>
            <para>
            Phải là một câu <c>UPDATE</c> chạm đúng cột cần chạm, không được là
            <c>UpdateAsync(conversation)</c>. Thực thể mà job quét đang cầm được nạp ở đầu lượt, và
            <c>UpdateAsync</c> ghi lại <b>cả dòng</b> theo ảnh chụp lúc ấy. Giữa lúc nạp và lúc ghi,
            một webhook có thể đã giao hội thoại cho ai đó — mà đường giao ấy cũng là một câu
            <c>UPDATE</c> không qua bộ theo dõi, nên thực thể trong tay lượt quét vẫn mang
            <c>AssignedStaffId = null</c>. Ghi cả dòng là <b>xoá mất lượt gán vừa thắng</b>: khách
            đã có người, rồi lại không có ai, trong khi nhật ký phân công vẫn ghi là đã giao.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConversationWriter.MarkSlaRemindedAsync(System.Int32,System.DateTimeOffset)">
            <summary>
            Đóng dấu "đã nhắc người đang giữ về hạn phản hồi", chạm <b>đúng hai cột</b>
            (giai đoạn E).
            </summary>
            <remarks>
            Cùng lý do với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConversationWriter.MarkQueueAlertedAsync(System.Int32,System.DateTimeOffset)"/>, và ở đây rủi ro còn cụ thể hơn: lượt
            quét hạn phản hồi nạp thực thể rồi mới gửi thông báo, mà trong quãng ấy chính sale có
            thể vừa trả lời khách — tức <c>LastMessageAt</c>, <c>LastStaffReplyAt</c> và
            <c>FirstResponseAt</c> vừa đổi. Ghi cả dòng theo ảnh chụp cũ là xoá mất câu trả lời ấy
            khỏi mọi phép đo của giai đoạn F.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConversationWriter.ReleaseOverdueAsync(System.Int32,System.Int32,System.DateTimeOffset)">
            <summary>
            Cộng một lượt quá hạn vào <c>SlaBreachCount</c> và xoá mốc đã-nhắc, chạm <b>đúng ba
            cột</b> (giai đoạn E).
            </summary>
            <remarks>
            <para>
            Cộng <b>tại database</b> (<c>c.SlaBreachCount + 1</c>) chứ không đọc-rồi-ghi: hai lượt
            quét chồng nhau, hoặc một lượt quét chạy cùng lúc với một lời gọi khác đang sửa hội
            thoại, thì đọc-rồi-ghi làm mất một lượt đếm. Đây là con số duy nhất của cả đợt mà giai
            đoạn F sẽ dùng để chấm tiêu chí <c>chat.sla-breach-rate</c>.
            </para>
            <para>
            Xoá mốc đã-nhắc cùng lúc là để lượt giữ của <b>người mới</b> bắt đầu sạch. Luật đã tự
            bảo vệ được nhờ so với mốc bắt đầu đếm, nhưng ghi rõ ra thì nhật ký đọc bằng SQL không
            còn mang một mốc của lượt đã kết thúc.
            </para>
            </remarks>
            <summary>
            Nhả hội thoại quá hạn khỏi <paramref name="expectedStaffId"/> và cộng một lượt quá hạn —
            <b>một câu <c>UPDATE</c> có điều kiện</b>. Trả về số dòng đổi được: <c>1</c> nếu thắng,
            <c>0</c> nếu hội thoại đã đổi tay hoặc đã được trả lời trong lúc lượt quét đang chạy.
            </summary>
            <remarks>
            <para>
            <b>Vì sao KHÔNG dùng <c>ApplyChangeAsync(conversation, …)</c> như bản đầu.</b> Đường ấy
            gọi <c>UpdateAsync(entity)</c> → <c>DbSet.Update()</c>, đánh dấu <b>mọi</b> cột là đã
            đổi, nên câu <c>UPDATE</c> ghi lại <b>cả dòng</b> theo ảnh chụp lúc đầu lượt quét. Giữa
            lúc nạp và lúc ghi, chính sale có thể vừa trả lời khách — và ghi cả dòng sẽ kéo
            <c>LastMessageAt</c>, <c>LastStaffReplyAt</c>, <c>FirstResponseAt</c>, <c>UnreadCount</c>,
            <c>Status</c>, <c>LastMessage</c> lùi về trước câu trả lời ấy, xoá luôn nó khỏi mọi phép
            đo của giai đoạn F.
            </para>
            <para>
            <b>Và vì sao phải có vế <c>AssignedStaffId = @expected</c>.</b> Bản đầu cố chặn tranh
            chấp bằng cách nạp lại thực thể rồi chấm lại — <b>một câu lệnh vô tác dụng</b>:
            <c>Repository.Query()</c> là truy vấn CÓ theo dõi và cả lượt quét dùng chung một
            <c>DbContext</c> (đăng ký <c>Scoped</c>), nên EF phân giải định danh và trả về <b>chính
            thực thể cũ</b>, không ghi đè giá trị bằng dữ liệu dưới database. Hàng rào ấy là code
            chết. Chỉ database mới phân xử được lượt tranh chấp này — đúng lý lẽ đã áp cho
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConversationWriter.ClaimAsync(System.Int32,System.Int32,System.DateTimeOffset)"/>, chỉ khác chiều.
            </para>
            <para>
            <b>Vế "khách còn đang chờ" cũng nằm trong câu lệnh</b> (<c>WaitingSinceAt IS NOT NULL</c>):
            đường nhận tin xoá cột ấy ở mọi tin đi ra, nên nếu sale vừa kịp trả lời thì câu lệnh này
            đổi 0 dòng và lượt thu hồi tự huỷ.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.EfChatConversationWriter">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConversationWriter"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.EfChatConversationWriter.ClaimAsync(System.Int32,System.Int32,System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.EfChatConversationWriter.MarkQueueAlertedAsync(System.Int32,System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.EfChatConversationWriter.MarkSlaRemindedAsync(System.Int32,System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.EfChatConversationWriter.ReleaseOverdueAsync(System.Int32,System.Int32,System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatTimeRange">
            <summary>
            Một khoảng thời gian nửa mở <c>[From, To)</c> — mốc đầu thuộc khoảng, mốc cuối không.
            </summary>
            <remarks>
            Nửa mở vì cùng quy ước với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.IsWorkingTime(System.DateTimeOffset)"/> (<c>[Start, End)</c>)
            và với cách nhật ký trạng thái cắt hiệu lực: "Nghỉ tới 09:00" nghĩa là 09:00 đã hết nghỉ.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatTimeRange.#ctor(System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Một khoảng thời gian nửa mở <c>[From, To)</c> — mốc đầu thuộc khoảng, mốc cuối không.
            </summary>
            <remarks>
            Nửa mở vì cùng quy ước với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.IsWorkingTime(System.DateTimeOffset)"/> (<c>[Start, End)</c>)
            và với cách nhật ký trạng thái cắt hiệu lực: "Nghỉ tới 09:00" nghĩa là 09:00 đã hết nghỉ.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatTimeRange.Minutes">
            <summary>Độ dài khoảng tính bằng phút; khoảng rỗng hoặc ngược chiều bằng 0.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageCandidate">
            <summary>
            Một ứng viên của kênh, đủ dữ liệu để biết họ "vào ca" lúc nào — đầu vào của
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.Build(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageCandidate},System.DateTimeOffset,System.DateTimeOffset)"/>.
            </summary>
            <param name="StaffId">Mã nhân viên — chỉ để đọc log và bảng ca, luật không dùng tới</param>
            <param name="WorkingHours">
            Giờ làm <b>riêng</b> của người này; người chưa đặt (hoặc giờ hỏng) mang cửa sổ "luôn trong
            ca" (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.CreateAlwaysOpen(System.TimeSpan)"/>) — đúng giá trị mà
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffWorkingHoursProvider"/> trả.
            </param>
            <param name="PresenceLog">
            Các dòng <c>ChatAgentPresenceLog</c> của người này giao với khoảng đang tính. Truyền cả dòng
            Sẵn sàng / Bận / Ra ngoài cũng được — luật tự lọc lấy Nghỉ và Tạm ngưng.
            </param>
            <param name="IsResigned">Đã nghỉ việc — không bao giờ vào ca</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageCandidate.#ctor(System.Int32,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSpan},System.Boolean)">
            <summary>
            Một ứng viên của kênh, đủ dữ liệu để biết họ "vào ca" lúc nào — đầu vào của
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.Build(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageCandidate},System.DateTimeOffset,System.DateTimeOffset)"/>.
            </summary>
            <param name="StaffId">Mã nhân viên — chỉ để đọc log và bảng ca, luật không dùng tới</param>
            <param name="WorkingHours">
            Giờ làm <b>riêng</b> của người này; người chưa đặt (hoặc giờ hỏng) mang cửa sổ "luôn trong
            ca" (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.CreateAlwaysOpen(System.TimeSpan)"/>) — đúng giá trị mà
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffWorkingHoursProvider"/> trả.
            </param>
            <param name="PresenceLog">
            Các dòng <c>ChatAgentPresenceLog</c> của người này giao với khoảng đang tính. Truyền cả dòng
            Sẵn sàng / Bận / Ra ngoài cũng được — luật tự lọc lấy Nghỉ và Tạm ngưng.
            </param>
            <param name="IsResigned">Đã nghỉ việc — không bao giờ vào ca</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageCandidate.StaffId">
            <summary>Mã nhân viên — chỉ để đọc log và bảng ca, luật không dùng tới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageCandidate.WorkingHours">
            <summary>
            Giờ làm <b>riêng</b> của người này; người chưa đặt (hoặc giờ hỏng) mang cửa sổ "luôn trong
            ca" (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.CreateAlwaysOpen(System.TimeSpan)"/>) — đúng giá trị mà
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffWorkingHoursProvider"/> trả.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageCandidate.PresenceLog">
            <summary>
            Các dòng <c>ChatAgentPresenceLog</c> của người này giao với khoảng đang tính. Truyền cả dòng
            Sẵn sàng / Bận / Ra ngoài cũng được — luật tự lọc lấy Nghỉ và Tạm ngưng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageCandidate.IsResigned">
            <summary>Đã nghỉ việc — không bao giờ vào ca</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage">
            <summary>
            "Có ít nhất một ứng viên của kênh đang vào ca" — tập khoảng đã hợp, cho đồng hồ hàng chờ
            (KC-18, §8.7 câu 3 + 3b). <b>Hàm thuần</b>: không chạm database, không đọc đồng hồ.
            </summary>
            <remarks>
            <para>
            <b>Một ứng viên vào ca tại mốc t</b> (plan §6 Phiên 4, thiết kế mục 5) khi đồng thời: không ở
            Nghỉ / Tạm ngưng (nhật ký trạng thái, cắt hiệu lực bằng
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatAvailabilityProvider.MocKetThucHieuLuc(System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset},System.DateTimeOffset)"/>), không ngoài giờ riêng (chưa đặt =
            luôn trong giờ), không đã nghỉ việc. Bận và Ra ngoài <b>vẫn là vào ca</b>: chủ dự án chọn
            "theo trạng thái" — người đang bận vẫn là người có mặt, trưởng nhóm được báo để điều phối.
            </para>
            <para>
            <b>Vì sao hợp khoảng chứ không đếm theo phút.</b> Một hội thoại bị bỏ quên vài tuần là vài chục
            nghìn phút; lặp từng phút cho từng ứng viên của từng kênh trong một job chạy mỗi 2 phút là
            đúng thứ <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.WorkingMinutesBetween(System.DateTimeOffset,System.DateTimeOffset)"/> đã tránh. Ở đây sinh khoảng ca
            <b>theo ngày</b> (nhiều nhất hai khoảng một ngày), trừ khoảng vắng, rồi hợp — số khoảng tỉ lệ
            với số ngày, không với số phút.
            </para>
            <para>
            <b>Giới hạn biết trước</b> (plan §6 Phiên 4): giờ riêng và tập ứng viên lấy theo <b>hiện tại</b>
            cho cả quá khứ; "đã nghỉ việc" theo <c>LockoutEnd</c> hiện tại. Cùng giới hạn cấu hình chung
            đã có.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.MaxSpan">
            <summary>
            Độ dài tối đa của một lần tính. Khách chờ lâu hơn thế chỉ được đếm phần
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.MaxSpan"/> cuối cùng.
            </summary>
            <remarks>
            62 ngày = hai tháng dài nhất: đủ rộng để một hội thoại chờ qua kỳ nghỉ Tết vẫn đếm đúng,
            đủ hẹp để một bản ghi lệch <i>một năm</i> (đã có trên dev, số đo Đ5 §2.4 plan chat) không
            biến một lượt quét thành hàng nghìn khoảng mỗi ứng viên. Ngưỡng báo trưởng nhóm tính bằng
            phút nên phần bị cắt không đổi quyết định báo hay không — chỉ đổi con số hiển thị.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.Lookahead">
            <summary>
            Kéo phép dựng quá <c>to</c> một chút để câu hỏi "lúc này" (<c>t = to</c>) có câu trả lời:
            khoảng nửa mở <c>[a, to)</c> không chứa <c>to</c>, nên cắt đúng ở <c>to</c> là mọi mốc
            "bây giờ" đều đọc thành "không ai vào ca".
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage._minutesBefore">
            <summary>Tổng phút phủ của mọi khoảng đứng TRƯỚC khoảng thứ i — để đếm không phải lặp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.RequestedFrom">
            <summary>Mốc đầu người gọi hỏi — khác <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.From"/> khi đã bị cắt.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.From">
            <summary>Mốc đầu thật sự đã tính (sau khi cắt ở <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.MaxSpan"/>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.To">
            <summary>Mốc cuối — thường là "bây giờ" của lượt quét / của trang.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.Ranges">
            <summary>
            Các khoảng "có người vào ca", đã sắp và đã hợp (không chồng, không kề nhau). Khoảng cuối có
            thể vượt quá <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.To"/> một chút — xem <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.IsCoveredAt(System.DateTimeOffset)"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.WasTruncated">
            <summary>Khoảng hỏi dài hơn <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.MaxSpan"/> và đã bị cắt — người gọi phải ghi log.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.ClampFrom(System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Mốc đầu sau khi áp trần <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.MaxSpan"/>. Tách thành hàm để lớp nạp dữ liệu truy vấn
            nhật ký đúng khoảng mà <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.Build(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageCandidate},System.DateTimeOffset,System.DateTimeOffset)"/> sẽ tính — hai phép cắt lệch nhau là thiếu dòng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.LoadUntil(System.DateTimeOffset)">
            <summary>
            Mốc cuối mà lớp nạp dữ liệu phải lấy nhật ký tới — gồm cả phần nhìn quá <paramref name="to"/>
            để trả lời được "lúc này".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.Empty(System.DateTimeOffset,System.DateTimeOffset)">
            <summary>Không ai vào ca suốt khoảng — kênh không có ứng viên nào.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.Build(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageCandidate},System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Dựng tập khoảng "có ít nhất một ứng viên vào ca" trong <c>[from, to]</c>.
            </summary>
            <param name="candidates">Đúng tập ứng viên phân phối của kênh (<c>GetDistributionCandidatesAsync</c>)</param>
            <param name="from">Mốc chờ sớm nhất cần đếm; dài quá <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.MaxSpan"/> thì bị cắt</param>
            <param name="to">"Bây giờ"</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.CoveredMinutesBetween(System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Số phút "có người vào ca" trong <c>[a, b]</c>, cắt vào <c>[From, To]</c>. Trả 0 khi
            <paramref name="b"/> không muộn hơn <paramref name="a"/> — cùng quy ước với
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.WorkingMinutesBetween(System.DateTimeOffset,System.DateTimeOffset)"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.IsCoveredAt(System.DateTimeOffset)">
            <summary>
            Tại mốc <paramref name="at"/> có ít nhất một ứng viên vào ca không. Trả lời được cho
            <c>From &lt;= at &lt;= To</c>; ngoài đó là <c>false</c> (không có dữ liệu để nói có).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.CoveredUntil(System.DateTimeOffset)">
            <summary>Tổng phút phủ từ <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.From"/> tới <paramref name="at"/> — đơn điệu không giảm.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.LastRangeStartingAtOrBefore(System.DateTimeOffset)">
            <summary>Chỉ số khoảng cuối cùng có <c>From &lt;= at</c>, hoặc -1. Tìm nhị phân.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.AbsencesOf(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSpan},System.DateTimeOffset)">
            <summary>
            Khoảng Nghỉ / Tạm ngưng từ nhật ký. Hiệu lực cắt ở mốc <b>sớm hơn</b> giữa lúc đóng dòng và
            lúc hết hạn tự khai — dùng lại đúng <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatAvailabilityProvider.MocKetThucHieuLuc(System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset},System.DateTimeOffset)"/>,
            không viết bản thứ hai: "Nghỉ tới 11:00" mà hôm sau mới bấm về Sẵn sàng thì 11:00 đã hết nghỉ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.Merge(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatTimeRange})">
            <summary>Sắp theo mốc đầu rồi gộp mọi khoảng chồng hoặc kề nhau.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.Subtract(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatTimeRange},System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatTimeRange})">
            <summary>
            Phần của <paramref name="shifts"/> không nằm trong <paramref name="absences"/>. Cả hai đã sắp
            và không chồng nhau trong nội bộ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCustomerAlignment">
            <summary>Điều đã xảy ra sau khi một hội thoại được gắn khách hàng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCustomerAlignment.Transferred">
            <summary>Hội thoại vừa được chuyển sang sale của khách</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCustomerAlignment.ManagerAdopted">
            <summary>Khách chưa có ai phụ trách, vừa được gán cho người đang cầm hội thoại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCustomerAlignment.CoManagerAdded">
            <summary>Sale của khách không phụ trách kênh, người đang cầm được thêm làm đồng phụ trách</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCustomerAlignment.Message">
            <summary>Câu mô tả cho người bấm; rỗng khi không có gì đổi</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatCustomerAlignmentService">
            <summary>
            Giữ cho chat và CRM không nói hai chuyện khác nhau về "sale của khách" (§3.4).
            </summary>
            <remarks>
            <para>
            Nguyên tắc gói gọn: <c>Customer.ManagerId</c> là nguồn sự thật về <b>sale của khách</b>,
            <c>ChatConversation.AssignedStaffId</c> là nguồn sự thật về <b>người đang cầm hội thoại</b>.
            Khi hai cái lệch nhau, <b>chat nhường CRM</b>.
            </para>
            <para>
            <b>Vì sao là một service riêng chứ không nằm trong <c>SocialChatService</c>.</b> Luật này có
            hai đầu: một đầu ở miền chat (vừa gắn khách vào hội thoại) và một đầu ở miền CRM (vừa đổi
            người phụ trách khách). Đặt ở giữa thì cả hai đầu gọi được cùng một luật; đặt trong một
            trong hai miền thì miền kia hoặc phải chép lại luật, hoặc phải phụ thuộc ngược.
            </para>
            <para>
            <b>Cố ý KHÔNG inject <c>ICustomerService</c>.</b> Chiều ngược lại đã tồn tại —
            <c>CustomerService.AssignManager</c> gọi vào đây cho tình huống 3 — nên inject nó là dựng
            một vòng phụ thuộc. Vì thế dòng đồng phụ trách được chèn thẳng qua repository, kèm phép dò
            trùng đúng bằng chỉ số duy nhất của bảng.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatCustomerAlignmentService.AlignAfterLinkAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Lada.Framework.Data.Domains.Crm.Customer,System.Int32,System.String)">
            <summary>
            Tình huống 1 và 2 của §3.4 — vừa gắn hội thoại với một khách hàng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatCustomerAlignmentService.MoveConversationsToManagerAsync(System.Int32,System.Int32,System.Boolean,System.Int32,System.String)">
            <summary>
            Tình huống 3 của §3.4 — <c>Customer.ManagerId</c> vừa đổi, kéo hội thoại đang mở của
            khách đó theo.
            </summary>
            <param name="cutReadAccess">
            <c>true</c> khi lần đổi này đến từ <b>yêu cầu của khách</b> (duyệt
            <c>CustomerManagerChangeRequest</c>): người cũ mất luôn quyền xem, đúng quyết định §6.2.
            <c>false</c> cho lần gán hành chính bình thường — người cũ vẫn đọc được lịch sử.
            </param>
            <returns>Số hội thoại đã chuyển</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCustomerAlignmentService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatCustomerAlignmentService"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCustomerAlignmentService.AlignAfterLinkAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Lada.Framework.Data.Domains.Crm.Customer,System.Int32,System.String)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCustomerAlignmentService.MoveConversationsToManagerAsync(System.Int32,System.Int32,System.Boolean,System.Int32,System.String)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCustomerAlignmentService.ChuyenAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.Nullable{System.Int32},System.Int32,Lada.Framework.Data.Enums.ChatReleaseReason,System.String,System.Int32,System.String)">
            <summary>
            Đổi người phụ trách một hội thoại qua sổ phân công, rồi phát realtime đúng thứ tự.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCustomerAlignmentService.TuPhanPhoiDuocAsync(System.Int32)">
            <summary>Kênh này có đang ở chế độ tự phân phối không. Không tra được thì coi là KHÔNG.</summary>
            <remarks>
            Fail-closed, và đây là chiều an toàn duy nhất: không chạy luật §3.4 thì hội thoại nằm
            đúng chỗ nó đang nằm; chạy nó trên một kênh không biết chế độ là tự bật một hành vi mà
            không ai bật, đúng thứ nguyên tắc số 1 cấm.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCustomerAlignmentService.NguoiConDocDuocAsync(System.Int32,System.Int32)">
            <summary>
            Những người còn đọc được hội thoại này nhờ một lượt giữ cũ, trừ người sắp nhận.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCustomerAlignmentService.NhaVeHangChoAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.String,System.Int32,System.String)">
            <summary>
            Nhả hội thoại về hàng chờ với lý do cắt quyền xem, rồi phát realtime đúng thứ tự.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCustomerAlignmentService.ThemDongPhuTrachAsync(System.Int32,System.Int32,System.String)">
            <summary>
            Ghi người đang cầm hội thoại vào danh sách đồng phụ trách của khách. Trả <c>true</c>
            nếu vừa thêm mới.
            </summary>
            <remarks>
            Chèn thẳng qua repository thay vì gọi <c>ICustomerService.AddCoManager</c> vì lý do vòng
            phụ thuộc đã ghi ở XML-doc của interface. Phép dò trùng dưới đây khớp đúng chỉ số duy
            nhất <c>(CustomerId, UserId)</c> của bảng — bỏ nó đi là để database ném lỗi giữa một
            thao tác gắn khách hoàn toàn hợp lệ.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCustomerAlignmentService.BaoTruongNhomAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Lada.Framework.Data.Domains.Crm.Customer,System.Int32,System.Int32)">
            <summary>
            Báo trưởng nhóm của kênh khi chat và CRM nói hai chuyện khác nhau mà máy không tự khớp
            được.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDecisionQueryService">
            <summary>
            Đọc nhật ký quyết định phân phối cho màn <c>/dieu-phoi-chat</c> (giai đoạn D).
            </summary>
            <remarks>
            Chỉ ĐỌC. Bảng <see cref="T:Lada.Framework.Data.Domains.SocialChat.ChatAssignmentDecision"/> là append-only — không có đường sửa hay
            xoá một dòng, chỉ có job dọn theo tuổi.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDecisionQueryService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>Tìm trong nhật ký quyết định, đã thu hẹp theo phạm vi kênh của người đọc.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDecisionQueryService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDecisionQueryService"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDecisionQueryService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDecisionQueryService.BoSungTenAsync(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatAssignmentDecisionItem})">
            <summary>
            Điền tên người và tên kênh cho <b>cả trang</b> bằng ba truy vấn, không phải ba truy vấn
            cho mỗi dòng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionOutcome">
            <summary>Kết quả một lượt chạy máy phân phối trên một hội thoại.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionOutcome.Ran">
            <summary>Máy có chạy không. <c>false</c> = kênh không ở chế độ tự phân phối, hoặc hội thoại đã có người.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionOutcome.Assigned">
            <summary>Có ghi <c>AssignedStaffId</c> thật không. Luôn <c>false</c> ở chế độ thử chạy.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionOutcome.ChosenStaffId">
            <summary>Người được chọn (hoặc <b>sẽ</b> được chọn nếu bật, khi đang thử chạy)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionOutcome.SkipReason">
            <summary>Không chạy vì lý do gì — chỉ để log, không hiển thị cho người dùng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionEngine">
            <summary>
            Máy phân phối khách chat — luật §3.3 nối vào database (giai đoạn D).
            </summary>
            <remarks>
            <para>
            Chia đôi có chủ ý với <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules"/>: mọi <b>luật</b> nằm ở hàm thuần
            bên đó, lớp này chỉ lo <b>nạp bảng đầu vào</b>, ghi nhật ký và giành hội thoại. Nhờ thế
            bảng ca của luật kiểm được mà không cần một dòng dữ liệu nào, đúng yêu cầu §3.10.
            </para>
            <para>
            <b>Chỉ chạy trên kênh <see cref="F:Lada.Framework.Data.Enums.ChatAssignmentMode.AutoDistribute"/>.</b> Kênh
            <c>Shared</c> giữ nguyên hành vi hôm nay (§6.3), còn <c>FixedOwner</c> là kênh một chủ của
            đợt Zalo cá nhân — dựng nhánh cho nó bây giờ, khi chưa có kênh nào ở chế độ ấy, là dựng
            thêm một nhánh chết đúng bài học PP-11.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionEngine.TryDistributeAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.DateTimeOffset,Lada.Framework.Data.Enums.ChatDecisionSource)">
            <summary>
            Chạy máy cho một hội thoại. Không chạm gì nếu kênh không tự phân phối hoặc hội thoại đã
            có người giữ.
            </summary>
            <param name="conversation">Hội thoại vừa nhận tin inbound</param>
            <param name="now">Mốc quyết định — tham số chứ không đọc đồng hồ, để bản phát lại đặt được mốc lịch sử</param>
            <param name="source">Máy chạy thật hay bản phát lại lịch sử</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionEngine.EvaluateAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.Collections.Generic.IReadOnlyCollection{System.Int32},System.DateTimeOffset)">
            <summary>
            Dựng bảng ứng viên và chọn người, <b>không</b> ghi gì cả. Dùng cho bản phát lại, vốn tự
            quản lý trạng thái tải trong bộ nhớ thay vì đọc lại database sau từng lượt.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionEngine">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionEngine"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionEngine.JsonCauHinh">
            <summary>
            Cách viết <c>CandidatesJson</c>. <c>camelCase</c> đúng như §3.2 đặc tả
            (<c>{staffId, weight, openCount, todayCount, score, excludedReason}</c>) — đây là một
            tài liệu dữ liệu, không phải một phản hồi REST, nên nó không theo lệ PascalCase của API.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionEngine.TryDistributeAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.DateTimeOffset,Lada.Framework.Data.Enums.ChatDecisionSource)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionEngine.EvaluateAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.Collections.Generic.IReadOnlyCollection{System.Int32},System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionEngine.ApDungTrongSoChatLuongAsync(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelCandidate},System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>
            Nhân trọng số phân phối suy từ điểm chất lượng vào bảng ứng viên — <b>chỉ khi công tắc
            <c>Chat.Quality.AffectsDistribution</c> bật</b> (giai đoạn F).
            </summary>
            <remarks>
            <para>
            Đây là <b>chỗ duy nhất</b> giai đoạn F chạm vào đường phân phối; mọi thứ khác của giai
            đoạn ấy chỉ đọc. Công tắc tắt thì hàm này thoát ngay và bảng ứng viên giữ nguyên trọng
            số của giai đoạn D — máy chia đều y hệt trước, đúng mục 3 của nguyên tắc số 1:
            <i>"Điểm chất lượng không được ảnh hưởng phân phối trước khi có dữ liệu."</i>
            </para>
            <para>
            <b>Người có <c>WeightOverride</c> KHÔNG bị nhân.</b> §3.2 định nghĩa cột ấy là *"bỏ qua
            điểm, ép trọng số; dùng khi sale mới cần kèm"* — nhân điểm chồng lên một giá trị đã ép
            là làm hỏng đúng công cụ mà quản lý dùng để can thiệp bằng tay. Đây là lý do
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelCandidate.HasWeightOverride"/> tồn tại: <c>Weight</c> một mình
            không phân biệt được "không ai ép nên lấy 1,0" với "ép đúng 1,0".
            </para>
            <para>
            <b>Chưa có dòng điểm thì giữ nguyên trọng số</b>, không rơi về sàn 0,4. Một sale vừa
            được thêm vào kênh hôm nay chưa được job 03:20 chấm; cho họ trọng số sàn là phạt họ vì
            job chưa chạy. Cùng lý lẽ với sàn 0,4 của chính công thức: một người không được chia
            khách là một người không bao giờ có dữ liệu để cải thiện điểm.
            </para>
            <para>
            <b>Bản phát lại không đi qua đây</b> — <c>ChatDistributionReplayService</c> gọi thẳng
            <c>GetDistributionCandidatesAsync</c> chứ không qua máy. Cố ý: điểm trong
            <c>ChatQualitySummary</c> là ảnh chụp của <b>hôm nay</b>, còn bản phát lại dựng lại
            quyết định của ba ngày trước. Áp điểm hôm nay lên lịch sử là trộn hai thời điểm vào một
            bảng đối chiếu, cùng họ giới hạn với PP-28, PP-29 và với tập loại trừ rỗng của §15.5.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionEngine.BiCatQuyenXemAsync(System.Int32)">
            <summary>
            Những người đã bị <b>thu hồi quyền xem</b> hội thoại này — họ không bao giờ được chọn lại.
            </summary>
            <remarks>
            <para>
            Đặt ở đây, trong cửa chung <c>EvaluateAsync</c>, chứ không ở riêng đường thu hồi quá hạn:
            cả ba đường gọi máy chia (tin của khách đến, lượt quét hàng chờ, lượt thu hồi quá hạn)
            đều phải chịu hàng rào này. Vá riêng một đường là để nguyên hai đường kia — đúng hình
            dạng F-5 đã cắn ở giai đoạn C.
            </para>
            <para>
            <c>ChatAgentPresenceService.TraLaiUyQuyenAsync</c> đã có hàng rào đối xứng từ giai đoạn C.
            Đường của máy thì chưa, và <c>/security-review</c> của giai đoạn E tìm ra — vì E biến
            đường ấy thành tự động, chạy mỗi 2 phút.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionEngine.DemHoiThoaiDangGiuAsync(System.Collections.Generic.List{System.Int32})">
            <summary>Số hội thoại chưa đóng mỗi người đang giữ — <b>toàn hệ thống</b>, không theo kênh.</summary>
            <remarks>
            Trần <c>MaxOpenPerStaff</c> nói về sức chứa của một con người, và một sale phụ trách ba
            kênh vẫn chỉ có một cái đầu. Đếm theo kênh là cho phép người ấy giữ ba lần trần.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionEngine.DemTaiHomNayAsync(System.Collections.Generic.List{System.Int32},System.DateTimeOffset,System.Boolean)">
            <summary>
            Số lượt nhận từ 00:00 hôm nay và lần nhận gần nhất — hai số của luật 2, lấy trong
            <b>một</b> truy vấn.
            </summary>
            <remarks>
            <para>
            Đếm trên sổ phân công chứ không trên hội thoại đang giữ: "phần việc hôm nay của tôi" là
            số khách tôi đã <b>nhận</b>, không phải số khách tôi còn <b>đang cầm</b>. Đếm theo cái
            đang cầm thì người xử lý nhanh, đóng hội thoại sớm, sẽ liên tục bị chia thêm — tức là
            hệ thống phạt người làm tốt.
            </para>
            <para>
            Cửa sổ đếm là <b>ngày hiện tại theo múi giờ cấu hình</b>, không phải 7 ngày trượt: sale
            nghỉ nửa ngày quay lại sẽ không bị dồn bù, và "phần của tôi hôm nay" là đơn vị sale
            hiểu. Múi giờ lấy từ chính cấu hình giờ làm việc, nếu không thì nửa đêm của phép đếm
            lệch với nửa đêm của người dùng.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionEngine.DemTaiThuChayAsync(System.Collections.Generic.List{System.Int32},System.DateTimeOffset)">
            <summary>
            Tải hôm nay ở <b>chế độ thử chạy</b>, đếm trên nhật ký quyết định thay vì trên sổ phân công.
            </summary>
            <remarks>
            <para>
            <b>Vì sao phải đếm ở nguồn khác, và vì sao thiếu nó thì cả bước 5 của trình tự lên
            production trở nên vô nghĩa.</b> Chế độ thử chạy cố ý KHÔNG ghi lượt giữ nào, nên sổ
            phân công đứng im. Đếm tải ở đó thì <c>TodayCount</c> của mọi người luôn bằng <b>0</b>,
            luật 2 hoà tuyệt đối ở mọi lượt, và phép xử hoà rơi xuống "mã nhỏ nhất" — tức là
            <b>một người duy nhất</b> được ghi là người sẽ nhận cho mọi quyết định trong ngày.
            </para>
            <para>
            Bảng đối chiếu đọc từ nhật ký ấy sẽ báo 100 % / 0 % / 0 % và người vận hành kết luận
            thuật toán chia lệch — trong khi cái lệch là do chính phép đo. Vòng phản hồi phải khép:
            ở chế độ thử, "người này đã nhận bao nhiêu hôm nay" chính là "máy đã CHỌN người này bao
            nhiêu lần hôm nay".
            </para>
            <para>
            Chỉ đếm dòng <see cref="F:Lada.Framework.Data.Enums.ChatDecisionSource.Live"/>: bản phát lại có bộ đếm riêng trong
            bộ nhớ, và trộn hai nguồn vào một phép đếm là đúng thứ cột <c>Source</c> sinh ra để ngăn.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionEngine.VuaNhaHoiThoaiNayAsync(System.Int32,System.Int32,System.DateTimeOffset)">
            <summary>Ai vừa nhả chính hội thoại này trong quãng nghỉ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionEngine.SaleCuaKhachAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation)">
            <summary>
            Sale đang phụ trách hồ sơ khách của hội thoại — nguồn của luật 1.
            </summary>
            <remarks>
            <c>Customer.ManagerId</c> là <b>nguồn sự thật</b> về sale của khách; khi nó lệch với
            <c>AssignedStaffId</c> thì chat nhường CRM (§3.4). Ở đây chỉ đọc, không bao giờ ghi.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionEngine.DauNgay(System.DateTimeOffset,System.TimeSpan)">
            <summary>00:00 của ngày chứa <paramref name="moc"/>, tính theo múi giờ cấu hình.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionEngine.GhiNhatKyAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionResult,System.String,System.Boolean,Lada.Framework.Data.Enums.ChatDecisionSource,System.DateTimeOffset)">
            <summary>
            Ghi một dòng <see cref="T:Lada.Framework.Data.Domains.SocialChat.ChatAssignmentDecision"/>. Gọi ở <b>mọi</b> nhánh — kể cả nhánh
            không ai nhận và nhánh thua tranh chấp.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionEngine.LanTruocCungKhongAiNhanAsync(System.Int32)">
            <summary>
            Dòng quyết định gần nhất của hội thoại này có phải cũng là "không ai đủ điều kiện" không.
            </summary>
            <remarks>
            <para>
            <b>Vì sao phải có phép này.</b> Job quét chạy <b>mỗi 2 phút</b> trên mọi hội thoại còn
            nằm hàng chờ. Không có nó thì một hội thoại khách nhắn lúc 22 giờ sinh ra một dòng nhật
            ký <i>giống hệt nhau</i> mỗi 2 phút suốt đêm — khoảng <b>435 dòng</b> cho một hội thoại,
            và ở chế độ thử chạy thì con số ấy là 720 dòng mỗi ngày cho <i>mọi</i> hội thoại chưa ai
            nhận. Màn nhật ký sinh ra để trả lời "sao tôi không được chia khách"; một bảng ngập
            những dòng lặp không trả lời được câu nào.
            </para>
            <para>
            <b>Điều này KHÔNG làm mất thông tin nào.</b> Lượt VÀO hàng chờ vẫn có đúng một dòng, và
            mọi lần kết quả <i>đổi</i> — có người nhận, hoặc thua tranh chấp — đều được ghi. Cái bị
            bỏ là những lượt thử lại cho ra đúng kết quả cũ, tức là những lượt không mang tin gì mới.
            Đúng lý lẽ của cột <c>QueueAlertedAt</c> ở tầng thông báo, chỉ khác chỗ áp dụng.
            </para>
            <para>
            Đánh đổi đã biết: nếu LÝ DO không ai nhận đổi (cả đội ngoài giờ → cả đội bận) mà vẫn là
            "không ai nhận", lần đổi ấy không được ghi. Chấp nhận: câu hỏi màn này phục vụ là "có ai
            nhận không", không phải "vì sao không ai nhận, theo từng phút".
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionReplayService">
            <summary>
            Phát lại tin inbound lịch sử qua máy phân phối để dựng bảng đối chiếu "nếu bật thì ai nhận
            bao nhiêu" — bằng chứng của <b>cổng D2</b>.
            </summary>
            <remarks>
            <para>
            <b>Vì sao phát lại thay vì chờ ba ngày.</b> Plan có một mâu thuẫn đã được chốt trước khi
            viết dòng code này: "Xong khi" của giai đoạn D đòi dry-run ba ngày trên <i>dữ liệu thật</i>,
            trong khi trình tự lên production xếp dry-run là bước 5 — sau khi đã chạy migration và bật
            hàng rào <i>trên production</i>. Bật hàng rào production chỉ để lấy số là làm đúng thứ mà sổ
            nợ PP-16 bảo đừng làm (sổ kết nối SignalR còn là bộ nhớ một tiến trình). Lối ra đã chốt là
            phát lại lịch sử trên dev, và nó <b>khả thi</b> vì §3.3 đã chốt thuật toán là <b>xác định</b>:
            cùng đầu vào cho cùng kết quả, nên phát lại cho ra đúng bảng mà ba ngày chờ sẽ cho.
            </para>
            <para>
            <b>Không bao giờ ghi <c>AssignedStaffId</c>.</b> Mọi dòng nhật ký nó sinh ra mang
            <c>Source = Replay</c> và <c>IsDryRun = true</c>. Cột <c>Source</c> tồn tại chính vì lượt
            phát lại và lượt chạy thật ở chế độ thử cùng ghi <c>IsDryRun = 1</c> — trộn hai thứ là đọc
            một bảng phân bố pha hai hiệu ứng mà không biết.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionReplayService.ReplayAsync(System.DateTimeOffset,System.DateTimeOffset,System.Int32)">
            <summary>Chạy một lượt phát lại và trả về bảng đối chiếu.</summary>
            <param name="from">Đầu cửa sổ (bao gồm)</param>
            <param name="to">Cuối cửa sổ (không bao gồm)</param>
            <param name="chatChannelId">Chỉ một kênh; <c>0</c> = mọi kênh đang tự phân phối</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionReplayService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.TranSoNgay">
            <summary>
            Trần độ dài cửa sổ phát lại.
            </summary>
            <remarks>
            Một lượt phát lại ghi một dòng nhật ký cho mỗi quyết định; không có trần thì một lời gọi
            nhỡ tay quét cả năm lịch sử và sinh ra một bảng không ai đọc nổi. 31 ngày đủ rộng cho
            mọi cửa sổ đối chiếu có nghĩa (plan chỉ đòi 3 ngày).
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.MocQuetGiaLap">
            <summary>
            Số lượt quét giả lập mỗi ngày, đặt ở đầu buổi sáng và đầu buổi chiều.
            </summary>
            <remarks>
            Job thật chạy mỗi 2 phút, nhưng mô phỏng 720 lượt quét mỗi ngày chỉ để chứng minh cùng
            một điều là 720 lần đọc trạng thái sẵn sàng cho một con số không đổi. Hai mốc này bắt
            đúng thứ cần bắt: hội thoại rơi vào hàng chờ vì đến ngoài giờ làm sẽ được giao lại vào
            <b>đầu ca kế tiếp</b>. Sai số so với job thật là vài phút, và bảng đối chiếu đo <i>ai
            nhận bao nhiêu</i> chứ không đo <i>nhận lúc mấy giờ</i>.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.ReplayAsync(System.DateTimeOffset,System.DateTimeOffset,System.Int32)">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.TinInbound">
            <summary>Một tin của khách trong cửa sổ phát lại.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.TinInbound.#ctor(System.Int32,System.DateTimeOffset)">
            <summary>Một tin của khách trong cửa sổ phát lại.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.MocPhatLai">
            <summary>Một mốc trên tuyến thời gian phát lại.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.MocPhatLai.#ctor(System.DateTimeOffset,System.Int32,System.Boolean)">
            <summary>Một mốc trên tuyến thời gian phát lại.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.DungTuyenThoiGian(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.TinInbound},System.DateTimeOffset,System.DateTimeOffset,System.TimeSpan)">
            <summary>
            Trộn tin inbound với các mốc quét giả lập, theo đúng thứ tự thời gian.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.BoiPhatLai">
            <summary>
            Trạng thái tải trong lúc phát lại — đếm trong bộ nhớ, không đọc database.
            </summary>
            <remarks>
            <para>
            Phải đếm trong bộ nhớ vì database mang trạng thái <b>hôm nay</b>: hỏi nó "người này đã
            nhận bao nhiêu khách hôm 26/08" thì nó trả lời bằng số của hôm nay, và bảng đối chiếu
            thành ra vô nghĩa.
            </para>
            <para>
            <b>Giới hạn đã biết:</b> hội thoại trong bản mô phỏng <b>không bao giờ đóng</b>, nên số
            đang giữ chỉ tăng. Với cỡ mẫu của dev (62 hội thoại, 3 người) con số cao nhất vẫn dưới
            trần 30 nên nó không đổi kết quả; ở cửa sổ dài hơn thì trần sẽ chạm sớm hơn thực tế và
            bảng đối chiếu sẽ báo thừa lượt "không ai đủ điều kiện". Nói ra thay vì giấu.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.BoiPhatLai.#ctor(System.TimeSpan)">
            <summary>
            Trạng thái tải trong lúc phát lại — đếm trong bộ nhớ, không đọc database.
            </summary>
            <remarks>
            <para>
            Phải đếm trong bộ nhớ vì database mang trạng thái <b>hôm nay</b>: hỏi nó "người này đã
            nhận bao nhiêu khách hôm 26/08" thì nó trả lời bằng số của hôm nay, và bảng đối chiếu
            thành ra vô nghĩa.
            </para>
            <para>
            <b>Giới hạn đã biết:</b> hội thoại trong bản mô phỏng <b>không bao giờ đóng</b>, nên số
            đang giữ chỉ tăng. Với cỡ mẫu của dev (62 hội thoại, 3 người) con số cao nhất vẫn dưới
            trần 30 nên nó không đổi kết quả; ở cửa sổ dài hơn thì trần sẽ chạm sớm hơn thực tế và
            bảng đối chiếu sẽ báo thừa lượt "không ai đủ điều kiện". Nói ra thay vì giấu.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.BoiPhatLai.LanTruocKhongAiNhan(System.Int32)">
            <summary>Lượt quyết định gần nhất của hội thoại này có phải cũng là "không ai nhận" không.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.BoiPhatLai.CanQuyetDinh(System.Int32)">
            <summary>Hội thoại này còn cần một quyết định không (chưa ai nhận trong bản mô phỏng).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.BoiPhatLai.SangNgayMoiNeuCan(System.DateTimeOffset)">
            <summary>Cửa sổ đếm của luật 2 là NGÀY, nên qua nửa đêm là đặt lại về 0.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.LechLonNhatCungTrongSo(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatDistributionShareItem})">
            <summary>
            Lệch lớn nhất giữa hai người <b>cùng trọng số</b>, tính bằng phần trăm trên người nhận
            nhiều hơn — đúng con số mà ngưỡng 20 % của cổng D2 nói tới.
            </summary>
            <remarks>
            So theo <b>cặp cùng trọng số</b> chứ không so với một trung bình chung: hai người trọng
            số 1,0 và 0,5 lệch nhau 50 % là đúng thiết kế, không phải lỗi. Ngưỡng của cổng chỉ có
            nghĩa khi hai vế thật sự đáng bằng nhau.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.CanhBaoDoTinCay(System.Int32,System.Int32)">
            <summary>
            Câu cảnh báo về độ tin cậy. Rỗng nghĩa là bảng đọc được như một bảng phân bố.
            </summary>
            <remarks>
            Bắt buộc phải có vì dev đúng là chỗ mà cảnh báo này áp dụng: số đo D0-4 đếm được kênh 2
            chỉ có <b>2</b> người và <b>3</b> hội thoại. Trình bày một tỉ lệ ở đó như thể nó chắc
            chắn là nói dối bằng một con số đúng.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionReplayService.DonBanPhatLaiCuAsync(System.Collections.Generic.List{System.Int32})">
            <summary>
            Xoá <b>mọi</b> dòng phát lại cũ của những kênh sắp phát lại, để chạy lại không cộng đôi.
            </summary>
            <remarks>
            <para>
            Chỉ chạm dòng <see cref="F:Lada.Framework.Data.Enums.ChatDecisionSource.Replay"/>. Dòng của máy chạy thật là
            append-only và không đường nào ở đây xoá được chúng — đó là lý do cột <c>Source</c> tồn
            tại.
            </para>
            <para>
            <b>Cố ý KHÔNG kẹp theo cửa sổ ngày.</b> Bản đầu tiên có kẹp, và nó để lọt đúng thứ nó
            định dọn: <c>DecidedAt</c> của một dòng phát lại lấy từ mốc tin nhắn, mà dev có tin đề
            ngày <b>2025-08-26</b> — sớm hơn hội thoại sớm nhất đúng một năm. Dòng sinh ra từ tin ấy
            nằm ngoài mọi cửa sổ hợp lý nên phép dọn không bao giờ với tới, và nó cộng thêm một bản
            sao sau mỗi lần chạy lại.
            </para>
            <para>
            Dọn theo KÊNH thì đúng cả về nghĩa: một lượt phát lại <b>sở hữu</b> nhật ký phát lại của
            những kênh nó phát. Để bản phát lại của cửa sổ này nằm cạnh bản của cửa sổ khác là đúng
            thứ "trộn hai hiệu ứng vào một bảng" mà cột <c>Source</c> sinh ra để ngăn.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelCandidate">
            <summary>
            Một người đang phụ trách kênh, kèm trọng số — kết quả của
            <c>IChatChannelStaffService.GetDistributionCandidatesAsync</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelCandidate.StaffId">
            <summary>Nhân viên (<c>User.Id</c>)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelCandidate.Weight">
            <summary><c>ChatChannelStaff.WeightOverride</c>, hoặc 1,0 khi không ai ép</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelCandidate.HasWeightOverride">
            <summary>
            Trọng số này do người vận hành <b>ép</b> bằng <c>WeightOverride</c>, không phải giá trị
            mặc định.
            </summary>
            <remarks>
            Cần một cờ riêng vì <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatChannelCandidate.Weight"/> một mình không phân biệt được "không ai ép nên
            lấy 1,0" với "có người ép và họ ép đúng 1,0". Giai đoạn F đọc cờ này: §3.2 định nghĩa
            <c>WeightOverride</c> là *"bỏ qua điểm, ép trọng số; dùng khi sale mới cần kèm"*, nên
            điểm chất lượng <b>không</b> được nhân chồng lên một giá trị đã ép — ép là ép.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionCandidate">
            <summary>
            Một ứng viên của lượt phân phối, đã kèm sẵn lý do bị loại mà chỉ tầng chạm database mới
            biết (trạng thái sẵn sàng, tải đang giữ, vừa nhả hội thoại này).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionCandidate.StaffId">
            <summary>Nhân viên (<c>User.Id</c>)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionCandidate.Weight">
            <summary>
            Trọng số. Hôm nay là <c>ChatChannelStaff.WeightOverride ?? 1.0</c>; giai đoạn F sẽ nhân
            thêm trọng số điểm chất lượng <b>sau</b> công tắc <c>Chat.Quality.AffectsDistribution</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionCandidate.OpenCount">
            <summary>Số hội thoại đang giữ chưa đóng — dùng cho trần, không dùng cho phép chọn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionCandidate.TodayCount">
            <summary>Số hội thoại đã nhận từ 00:00 hôm nay — tử số của phép chọn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionCandidate.LastAssignedAt">
            <summary>Lần gần nhất người này nhận một hội thoại. <c>null</c> = chưa nhận bao giờ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionCandidate.Exclusion">
            <summary>
            Lý do bị loại mà tầng gọi đã xác định được. <see cref="F:Lada.Framework.Data.Enums.ChatCandidateExclusion.None"/>
            nghĩa là chưa có lý do nào — luật vẫn có thể tự loại thêm vì trọng số ≤ 0.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionInput">
            <summary>Bảng đầu vào của một lượt quyết định. Không có gì ở đây chạm database.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionInput.Candidates">
            <summary>Mọi người đã cân nhắc, kể cả người bị loại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionInput.StickyStaffId">
            <summary>
            Sale đang phụ trách hồ sơ khách của hội thoại này (<c>Customer.ManagerId</c>).
            <c>null</c> = hội thoại chưa gắn khách, hoặc khách chưa có người phụ trách.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionInput.IsAnonymous">
            <summary>Hội thoại ẩn danh — nền tảng không cấp định danh bền vững cho khách</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionInput.HasCustomer">
            <summary>Hội thoại đã gắn <c>CustomerId</c></summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCandidateSnapshot">
            <summary>
            Ảnh chụp một ứng viên đúng như luật đã nhìn thấy — chính là một phần tử của
            <c>ChatAssignmentDecision.CandidatesJson</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCandidateSnapshot.Score">
            <summary>Điểm chọn <c>todayCount / weight</c>. <c>null</c> khi trọng số ≤ 0.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionResult">
            <summary>Kết quả một lượt quyết định, đủ để ghi thẳng thành một dòng nhật ký.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionResult.Note">
            <summary>Câu giải thích nhánh mà bảng ứng viên không nói được (chủ yếu là luật 1)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionResult.Candidates">
            <summary>
            Bảng ứng viên <b>đúng như luật đã nhìn</b>. Trả ra từ đây thay vì để tầng gọi tự dựng
            lại, vì hai bản dựng độc lập là hai bản sẽ lệch nhau — và lúc đó nhật ký nói một đằng,
            máy làm một nẻo.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules">
            <summary>
            Luật phân phối §3.3 — <b>hàm thuần</b>: bảng đầu vào cho ra người được chọn, không chạm
            database, không đọc đồng hồ.
            <para>
            <b>Vì sao tách thuần.</b> Đây là đoạn code quyết định sale nào được chia bao nhiêu khách,
            tức là quyết định thu nhập của người ta. Nó phải kiểm được bằng một bảng ca đọc hết trong
            một màn hình, và phải tái dựng được từ nhật ký: cùng đầu vào thì cùng kết quả, không đồng
            hồ, không ngẫu nhiên, không con trỏ vòng quay phải lưu ở đâu đó.
            </para>
            <para>
            <b>Trọng tâm là luật 2, không phải luật 1.</b> Số đo Đ2 đếm được chỉ <b>3,17 %</b> hội thoại
            gắn <c>CustomerId</c>, và số đo D0-6 của giai đoạn D còn mạnh hơn: trên toàn bộ lịch sử dev,
            luật 1 chạy <b>0</b> lần, vì hai hội thoại có khách đều trỏ về một người không phụ trách
            kênh nào. Luật 1 vẫn là luật nghiệp vụ quan trọng hơn (quyết định §6.1, đừng bàn lại), nhưng
            thứ quyết định gần như toàn bộ lưu lượng thật là luật 2 — nên nó là thứ phải được kiểm kỹ
            hơn, ngược với cảm giác về thứ tự ưu tiên.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules.RuleStickyCustomer">
            <summary>Luật 1 — khách quen về đúng sale đang phụ trách hồ sơ khách (§6.1)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules.RuleLeastLoaded">
            <summary>Luật 2 — ít việc nhất so với trọng số</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules.RuleNoCandidate">
            <summary>Không ai đủ điều kiện — hội thoại vào hàng chờ</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules.RuleLostRace">
            <summary>Có người khác giữ hội thoại trước khi lượt này ghi kịp</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules.DefaultWeight">
            <summary>Trọng số dùng khi không ai đặt <c>WeightOverride</c></summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules.Decide(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionInput)">
            <summary>
            Chọn người nhận hội thoại theo §3.3.
            </summary>
            <remarks>
            <para>
            Thứ tự: lọc người đủ điều kiện → luật 1 (khách quen) → luật 2 (ít việc nhất so với
            trọng số) → không ai thì <c>no-candidate</c>.
            </para>
            <para>
            <b>Hoà thì xử thế nào và vì sao.</b> Hoà điểm thì ưu tiên người có
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionCandidate.LastAssignedAt"/> <b>cũ nhất</b>, và người
            <b>chưa nhận bao giờ</b> đứng trước tất cả — đó là ý nghĩa của việc coi <c>null</c> là
            cũ nhất. Vẫn hoà thì mã nhỏ nhất, để kết quả xác định hoàn toàn. Không có bước cuối
            cùng ấy thì hai lần chạy trên cùng dữ liệu có thể ra hai người khác nhau tuỳ thứ tự
            database trả về, và bảng đối chiếu của cổng D2 mất ý nghĩa.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules.Score(System.Decimal,System.Int32)">
            <summary>
            Điểm chọn của luật 2: số hội thoại nhận hôm nay chia cho trọng số. Trọng số ≤ 0 thì
            phép chia không có nghĩa và trả <c>null</c> — người đó đã bị loại bằng
            <see cref="F:Lada.Framework.Data.Enums.ChatCandidateExclusion.ZeroWeight"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules.LyDoLoai(System.Int32,System.Int32,System.Collections.Generic.IReadOnlyDictionary{System.Int32,Lada.Framework.Data.Enums.ChatAgentStatus},System.Int32,System.Int32,System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>
            Bốn điều kiện lọc của §3.3 gộp thành một lý do duy nhất — hàm thuần, dùng chung cho máy
            chạy thật và cho bản phát lại lịch sử.
            </summary>
            <remarks>
            <para>
            Thứ tự chấm là cố định và có ý nghĩa: điều kiện 1 (phụ trách kênh) trước điều kiện 2
            (sẵn sàng), rồi 3 (trần) và 4 (vừa nhả). Người vừa nghỉ việc hiện ra là "đã nghỉ việc"
            chứ không phải "quá trần hội thoại", vì lý do đầu mới là lý do người đọc cần biết.
            </para>
            <para>
            Dùng chung ở hai nơi là điều kiện để bảng đối chiếu của cổng D2 <b>nói về</b> đúng cái
            máy sẽ chạy. Hai bản chép tay là hai bản sẽ lệch, và lúc đó cổng D2 nghiệm thu một
            thuật toán không tồn tại.
            </para>
            </remarks>
            <param name="khongPhuTrachKenh">
            Mã người có mặt trong bảng ứng viên <b>chỉ vì</b> họ là sale của khách, chứ không phụ
            trách kênh. <c>0</c> khi không có ai như thế.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules.ApDungLuatKhachQuen(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionInput,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCandidateSnapshot},System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCandidateSnapshot})">
            <summary>
            Luật 1. Trả về người được chọn (nếu áp dụng được) kèm câu giải thích cho nhật ký.
            </summary>
            <remarks>
            Ba nhánh "không áp dụng" đều phải nói ra được lý do, vì trên dữ liệu thật chúng là
            nhánh <b>thường gặp</b> chứ không phải nhánh hiếm: hội thoại ẩn danh (sổ nợ PP-4),
            hội thoại chưa gắn khách (96,8 % theo Đ2), và khách quen không đủ điều kiện (đúng
            100 % số ca có khách trên dev, theo D0-6).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules.LanNhanGanNhat(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionInput,System.Int32)">
            <summary>
            Mốc so hoà. Chưa nhận bao giờ thì đứng đầu hàng — <c>DateTimeOffset.MinValue</c> chính
            là cách nói "cũ nhất có thể".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules.MoTaLyDo(Lada.Framework.Data.Enums.ChatCandidateExclusion)">
            <summary>Mô tả tiếng Việt của một lý do loại, dùng trong câu giải thích của nhật ký.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules.TuTrangThai(Lada.Framework.Data.Enums.ChatAgentStatus)">
            <summary>
            Quy trạng thái sẵn sàng hiệu lực (§3.5) về lý do bị loại của nhật ký phân phối.
            <para>
            Chỉ <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Available"/> mới nhận khách mới — đúng luật
            <c>ChatAgentAvailability.NhanKhachMoiDuoc</c>. Hàm này chỉ dịch <i>vì sao không</i>
            sang ngôn ngữ của nhật ký, không định nghĩa lại luật đó.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionConfigKeys">
            <summary>
            Tên khoá <c>AppConfig</c> của máy phân phối — seed bằng migration <c>M202608291610</c>, không
            hardcode giá trị ở nơi khác.
            <para>
            Theo đúng khuôn <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceConfigKeys"/> của giai đoạn C: hằng tên khoá ở một chỗ,
            một lớp duy nhất diễn giải chuỗi, <c>InvariantCulture</c>, giá trị hỏng rơi về mặc định đã biết
            đúng thay vì ném lỗi giữa một webhook của khách.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionConfigKeys.DryRun">
            <summary>
            Chế độ thử chạy: máy chạy đủ, ghi đủ nhật ký, <b>không ghi</b> <c>AssignedStaffId</c>.
            <c>true</c> / <c>false</c>. Mặc định <b>bật</b> — mục 2 của nguyên tắc số 1.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionConfigKeys.MaxOpenPerStaff">
            <summary>Trần số hội thoại chưa đóng mà một sale được giữ cùng lúc</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionConfigKeys.ReleaseCooldownMinutes">
            <summary>
            Vừa nhả một hội thoại thì bấy nhiêu phút sau máy không giao lại chính hội thoại đó cho
            người ấy. <c>0</c> = tắt hẳn quãng nghỉ.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionConfigKeys.QueueAlertMinutes">
            <summary>Chờ trong hàng chờ quá bấy nhiêu phút thì báo trưởng nhóm của kênh</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionSettings">
            <summary>
            Đọc và diễn giải các khoá cấu hình của máy phân phối.
            </summary>
            <remarks>
            Tách riêng khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatPresenceSettings"/> vì hai nhóm khoá có hai vòng đời khác nhau:
            giờ làm việc là thứ người vận hành đặt một lần rồi quên, còn <c>DryRun</c> và các trần phân phối
            là thứ họ sẽ chỉnh trong tuần đầu chạy thật. Gộp vào một interface thì mọi lời gọi đọc giờ làm
            cũng kéo theo phụ thuộc vào những khoá chưa tồn tại lúc nó được viết.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionSettings.IsDryRunAsync">
            <summary>
            Có đang ở chế độ thử chạy không. <b>Mặc định <c>true</c></b>: khoá đọc không ra thì coi như
            đang thử, chứ không coi như đã bật.
            </summary>
            <remarks>
            Chiều rơi của giá trị hỏng ở đây là một quyết định an toàn, không phải tuỳ tiện. Hai hướng
            hỏng không cân nhau: rơi về "đang thử" thì tệ nhất là khách nằm hàng chờ thêm một lúc và có
            người bấm tay; rơi về "đã bật" thì máy bắt đầu tự chia khách trên một hệ thống mà không ai
            định bật, và đó đúng là thứ nguyên tắc số 1 cấm.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionSettings.GetMaxOpenPerStaffAsync">
            <summary>Trần hội thoại đang giữ mỗi sale (mặc định 30 — đề xuất CH-5)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionSettings.GetReleaseCooldownMinutesAsync">
            <summary>Quãng nghỉ sau khi nhả, tính bằng phút (mặc định 30). <c>0</c> = tắt.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionSettings.GetQueueAlertMinutesAsync">
            <summary>Ngưỡng báo trưởng nhóm khi hội thoại nằm hàng chờ, tính bằng phút (mặc định 15)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionSettings">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionSettings"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionSettings.DefaultDryRun">
            <summary>
            Thử chạy hay không khi khoá đọc không ra. Xem <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionSettings.IsDryRunAsync"/>
            để biết vì sao chiều này.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionSettings.DefaultMaxOpenPerStaff">
            <summary>Trần hội thoại mỗi sale — CH-5 đề xuất 30</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionSettings.DefaultReleaseCooldownMinutes">
            <summary>
            Quãng nghỉ sau khi nhả. 30 phút là <b>điểm khởi đầu</b> chứ không phải hằng số: chưa có số
            đo nào về việc sale nhả rồi nhận lại, vì trước giai đoạn D chưa có máy nào giao lại. Ngắn
            hơn thì vô nghĩa (nhả xong hai phút sau nhận lại đúng hội thoại vừa nhả), dài hơn thì khách
            nằm chờ trong khi kênh chỉ có vài người.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionSettings.DefaultQueueAlertMinutes">
            <summary>
            Ngưỡng báo hàng chờ. Lấy đúng ngưỡng nhắc SLA đã chốt từ số đo Đ5 (N = 206, trong giờ làm):
            15 phút nằm giữa p75 (4,3′) và p90 (35,4′).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionSettings.IsDryRunAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionSettings.GetMaxOpenPerStaffAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionSettings.GetReleaseCooldownMinutesAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionSettings.GetQueueAlertMinutesAsync">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatHistorySyncService">
            <summary>
            Kéo các tin gần nhất của hội thoại từ nền tảng về để bù tin webhook không chở tới.
            <para>
            Ca gốc (2026-10-24): Page tự trả lời riêng từ bình luận "Ib" của khách (private reply) lúc 15:01,
            khách trả lời bằng số điện thoại lúc 15:18. LADA chỉ có con số; hộp thư Meta Business Suite có cả câu
            hỏi đứng trước. Facebook không cam kết bắn <c>message_echoes</c> cho private reply, nên chờ webhook
            là không đủ — phải chủ động hỏi API hội thoại.
            </para>
            <para>
            Hai đường vào: job <c>chat-history-sync</c> tự kéo cho hội thoại MỚI, và nút "Đồng bộ lại" trên
            khung chat cho hội thoại bất kỳ. Cả hai đi qua đúng một hàm chèn, chỉ khác cách chọn hội thoại.
            </para>
            <para>
            Lớp này không biết nền tảng nào — hỏi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger.SupportsHistorySync"/>. Tách
            khỏi <c>SocialChatService</c> vì lớp đó đã quá to, và việc này không dính gì tới gửi tin hay phân công.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatHistorySyncService.SyncPendingAsync(System.Threading.CancellationToken)">
            <summary>
            Lượt quét của job: kéo lịch sử cho hội thoại mới chưa kéo lần nào.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatHistorySyncService.SyncConversationAsync(System.Int32,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>
            Nút "Đồng bộ lại": kéo lịch sử cho một hội thoại <b>trong phạm vi ĐỌC</b> của người bấm.
            <para>
            Phạm vi đọc chứ không phải phạm vi ghi: việc này chỉ chép lại thứ đã có trên nền tảng vào
            đúng hội thoại người đó đang được xem, không gửi gì cho khách và không đổi người phụ trách —
            cùng lý lẽ với nút Lịch sử phân công vẫn còn ở hội thoại chỉ-đọc.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncRunResult">
            <summary>Tổng kết một lượt quét của job.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncRunResult.Processed">
            <summary>Số hội thoại đã hỏi nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncRunResult.Inserted">
            <summary>Tổng số tin còn thiếu đã chèn vào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncRunResult.Failed">
            <summary>Hội thoại nền tảng từ chối hẳn — đã đánh dấu, không thử lại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncRunResult.WillRetry">
            <summary>Hội thoại gặp lỗi tạm — để nguyên, lượt sau thử lại</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatHistorySyncService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncService.AuthorName">
            <summary>Tên ghi vào cột audit cho tin và hội thoại do lớp này ghi</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncService.AutoSyncWindow">
            <summary>
            Job chỉ tự kéo hội thoại tạo trong khoảng này. Hội thoại cũ hơn thì để nút bấm lo: lượt đầu
            sau deploy không được quét ngược cả kho, và một hội thoại hỏng mạng mãi không được thử lại vô hạn.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncService.SettleDelay">
            <summary>
            Đợi hội thoại "lắng" một phút rồi mới kéo. Webhook tạo hội thoại và lưu tin đầu trong cùng một
            request, nhưng Facebook hay gom vài tin sát nhau thành nhiều request — kéo ngay giây đầu là đua
            với chính các request đó.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncService.MatchWindow">
            <summary>
            Cửa sổ nhận hai bản ghi là một tin khi mã tin không khớp nhau — cùng độ rộng với cửa sổ đối
            chiếu tiếng vọng của lõi (<c>SocialChatService.OutboundEchoWindow</c>).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncService.BatchSize">
            <summary>Số hội thoại tối đa mỗi lượt quét — mỗi hội thoại là một lời gọi nền tảng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncService.SyncOutcome">
            <summary>Kết quả kéo một hội thoại</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncService.SyncOutcome.#ctor(System.Int32,System.String,System.Boolean)">
            <summary>Kết quả kéo một hội thoại</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncService.InsertMissingAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage},System.String,System.Threading.CancellationToken)">
            <summary>
            Chèn những tin nền tảng có mà LADA chưa có, theo thứ tự thời gian.
            </summary>
            <remarks>
            <para>
            Nhận diện trùng hai lượt. Lượt 1 theo <b>mã tin</b> — đường chính, vì webhook, Send API và API
            hội thoại của Facebook cùng dùng mã <c>m_…</c>. Lượt 2 theo <b>nội dung trong cửa sổ hai phút</b>,
            cho phòng khi mã hai nguồn lệch nhau: thiếu lượt này thì mỗi lần kéo nhân đôi cả khung chat.
            Mỗi bản ghi có sẵn chỉ được nhận MỘT lần, để khách gõ "ok" hai lần thì vẫn ra hai tin.
            </para>
            <para>
            Tin <see cref="F:Lada.Framework.Data.Enums.ChatContentType.Other"/> rỗng (tin mẫu có nút của công cụ tự động, tin chia sẻ bài
            viết) bị bỏ: không đọc được nội dung thì chèn vào chỉ thêm một bong bóng trống.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncService.IsSameMessage(Lada.Framework.Data.Domains.SocialChat.ChatMessage,Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage)">
            <summary>
            Hai bản ghi có phải cùng một tin không, khi mã tin không giúp được.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncService.IsCaptionOf(Lada.Framework.Data.Domains.SocialChat.ChatMessage,Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage)">
            <summary>
            Tin chữ kéo về có phải chú thích của một bản ghi ảnh LADA đã gửi không.
            <para>
            LADA gửi ảnh kèm chú thích thành MỘT bản ghi, còn Facebook giữ thành HAI tin (ảnh + chữ) — chèn
            tin chữ là mọc thêm một bong bóng lặp lại đúng câu chú thích dưới tấm ảnh.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncService.IsComparable(Lada.Framework.Data.Domains.SocialChat.ChatMessage,Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage)">
            <summary>Cùng chiều, cùng khoảng thời gian, và bản ghi có sẵn đã thật sự tới nền tảng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatHistorySyncService.ApplyToConversation(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.Collections.Generic.List{Lada.Framework.Data.Domains.SocialChat.ChatMessage})">
            <summary>
            Cập nhật dòng xem trước và mốc tin khách sau khi chèn.
            </summary>
            <remarks>
            Cố ý KHÔNG đụng <c>UnreadCount</c>, <c>WaitingSinceAt</c>, trạng thái hay máy phân phối: tin kéo
            về là tin CŨ đã xảy ra, không phải việc mới. Cộng chưa đọc là bắt nhân viên đọc lại thứ họ có thể
            đã thấy trên Business Suite; mở lượt chờ là bấm đồng hồ hạn phản hồi cho một câu khách nói từ trước.
            <c>LastInboundAt</c> thì có nâng nếu tin khách kéo về MỚI hơn — đó là sự thật về cửa sổ trả lời của
            nền tảng, giữ mốc cũ là cảnh báo sai.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatMediaArchiveService">
            <summary>
            Tải tệp đính kèm chat (ảnh, video, tin thoại, tệp) từ CDN của Zalo / Facebook về máy chủ LADA
            rồi thay <c>ChatMessage.AttachmentUrl</c> bằng URL LADA (sổ nợ SC-9).
            <para>
            Lý do phải làm: URL nền tảng trả về CÓ HẠN. Đo 2026-10-23 trên DB dev: ảnh khách gửi qua Zalo ngày
            08/10 15:28 đã 404, ngày 09/10 20:39 còn sống — tức sống khoảng <b>14 ngày</b>, không phải 30. Tệp,
            video, tin thoại cùng nhịp. Ảnh OA gửi (<c>brcast-msg-photo.zadn.vn</c>), nhãn dán và gif thì còn sống
            sau 46 ngày. Facebook: ảnh 8 ngày tuổi còn sống, chưa đo được mốc chết.
            </para>
            <para>
            Chạy bằng job quét (<c>chat-media-archive</c>), KHÔNG trên đường webhook: Zalo đòi trả lời trong
            2 giây và Facebook trong 5 giây, còn một video vài chục MB tải mất cả chục giây. Trễ vài phút
            không mất gì vì URL nền tảng còn sống cả tuần. Cũng nhờ vậy mà tin nhân viên gửi thẳng từ app
            Zalo / Messenger (echo — 101 trên 103 ảnh/tệp chiều ra của DB dev) được lưu luôn, không cần một
            đường riêng.
            </para>
            <para>
            Tệp lưu xuống cùng chỗ với ảnh LADA gửi đi (<c>Media.RootPath</c>), nên cũng mang đúng rủi ro
            của chỗ đó: site media phục vụ tĩnh, KHÔNG chấm quyền — ai có URL là xem được. Tên tệp là GUID
            nên không đoán được, nhưng URL lọt ra ngoài thì không thu hồi được (giống mọi ảnh trong
            <c>Media.RootPath</c> hôm nay).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatMediaArchiveService.ArchivePendingAsync(System.Threading.CancellationToken)">
            <summary>
            Lưu một lượt các tin còn chờ, cũ trước mới sau (tệp cũ gần mốc chết hơn). Một tệp hỏng không
            làm dừng cả lượt.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatMediaArchiveService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.HttpClientName">
            <summary>Tên HttpClient đã đăng ký ở <c>DependencyRegister</c></summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.AuthorName">
            <summary>Tên ghi vào <c>UpdatedByUserName</c> — cùng tên job để tra ngược được từ dòng dữ liệu.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.MaxAttempts">
            <summary>
            Trần số lần thử. Lỗi tạm (mạng, 5xx, quá hạn chờ) được thử lại ở các lượt sau, năm lượt là
            khoảng 25 phút — đủ qua một lần CDN chập chờn, mà tệp hỏng vĩnh viễn thì không bị gọi mãi.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.BatchSize">
            <summary>Số tin mỗi lượt. Lượt 5 phút một lần → ~8.600 tin/ngày, dư cho tồn đọng lúc mới bật.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.ScanWindow">
            <summary>
            Chỉ quét tin trong 90 ngày — phủ trọn lịch sử chat hiện có (bắt đầu 2026-09-07). Không lấy 30:
            tệp khách gửi qua Zalo chết sau ~14 ngày, nhưng ảnh OA gửi, nhãn dán và gif còn sống sau 46
            ngày (đo 2026-10-23), cửa sổ hẹp là bỏ rơi đúng nhóm còn cứu được. Một link đã chết chỉ tốn một
            lời gọi 404 rồi bị đặt mức trần, nên cửa sổ rộng không làm job chạy nặng hơn về lâu dài.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.RunBudget">
            <summary>
            Ngân sách thời gian một lượt — dưới chu kỳ 5 phút của job, để lượt sau không phải xếp hàng
            chờ khoá <c>[DisableConcurrentExecution]</c> của lượt trước.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.MaxFileBytes">
            <summary>
            Trần dung lượng một tệp. Video mẫu trên DB dev nặng 4,2 MB; 100 MB dư cho video dài mà vẫn
            chặn được một tệp bất thường lấp đầy ổ đĩa. Quá trần thì không lưu, ghi lý do.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.ArchivableTypes">
            <summary>
            Loại tin mang tệp do nền tảng lưu hộ. Không có Link / Location / BusinessCard: ba loại đó
            không có tệp nào để giữ.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.AllowedHostSuffixes">
            <summary>
            Host được phép tải (kể cả tên miền con). Đây là hàng rào SSRF: <c>AttachmentUrl</c> đến từ
            payload webhook, và lần tải chạy từ chính máy chủ LADA. Danh sách lấy từ dữ liệu thật trên
            DB dev 2026-10-23: Zalo dùng <c>zdn.vn</c> (ảnh, tin thoại, gif), <c>zadn.vn</c> (ảnh OA gửi,
            nhãn dán), <c>dlfl.vn</c> (tệp), <c>dlmd.me</c> (video); Facebook dùng <c>fbcdn.net</c>, cộng
            <c>fbsbx.com</c> là CDN tệp của Messenger. Host mới xuất hiện thì tin bị đánh dấu không tải
            được kèm tên host — đọc lý do là biết phải thêm gì vào đây.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.ArchivePendingAsync(System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.DownloadAsync(System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Tải về <paramref name="partialPath"/>, đọc luôn 16 byte đầu để nhận dạng định dạng.
            <para>
            Tự đi theo chuyển hướng thay vì để HttpClient đi (client đăng ký <c>AllowAutoRedirect = false</c>):
            đi tự động thì một host hợp lệ chuyển hướng sang địa chỉ nội bộ là lọt qua hàng rào SSRF. Mỗi
            bước chuyển phải lại nằm trong danh sách host.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.DetectExtension(System.Byte[],System.String)">
            <summary>
            Phần mở rộng suy từ CHỮ KÝ NỘI DUNG, hoặc <c>null</c> nếu không thuộc định dạng được lưu.
            <para>
            Không tin <c>Content-Type</c>: gif của Zalo về với <c>image/jpeg</c> trong khi nội dung là
            <c>GIF89a</c> (đo 2026-10-23). Không tin đuôi tệp trên URL trừ đúng một chỗ — phân biệt
            docx/xlsx/pptx/zip (cùng là ZIP) và doc/xls/ppt (cùng là OLE) — và ở đó đuôi chỉ được CHỌN
            trong danh sách đóng. Tệp văn bản (txt, csv, html…) không lưu: không có chữ ký để phân biệt
            với một trang HTML, mà site media phục vụ tĩnh.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.FolderFor(System.String)">
            <summary>
            Thư mục gốc theo loại tệp. <c>Images</c> là chỗ ảnh chat LADA gửi đi đang nằm,
            <c>Videos</c> là chỗ <c>VideoService</c> đang dùng — hai thư mục site media đã phục vụ.
            <c>Files</c> là thư mục MỚI cho tin thoại và tài liệu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.ResolveOwnMediaAsync(System.String,System.String)">
            <summary>
            URL đã là của LADA (tin LADA gửi đi trước bản vá ghi <c>AttachmentSystemPath</c>) thì không tải lại.
            Trả kèm đường dẫn đĩa nếu tệp còn đó.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.UpdateMessageAsync(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.PendingAttachment,System.Action{Lada.Framework.Data.Domains.SocialChat.ChatMessage})">
            <summary>
            Nạp lại tin NGAY trước khi ghi rồi chỉ sửa các cột của việc lưu tệp — khoảng hở với webhook
            còn vài mili giây thay vì cả lượt (xem chú thích ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.ArchivePendingAsync(System.Threading.CancellationToken)"/>).
            Trả <c>false</c> nếu tin đã bị xoá, hoặc đã có đường dẫn đĩa (lượt khác lưu trước), hoặc URL
            đã đổi khỏi URL vừa tải.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.PendingAttachment">
            <summary>Ba cột lượt quét cần — cố ý không phải entity, xem <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.ArchivePendingAsync(System.Threading.CancellationToken)"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.PendingAttachment.#ctor(System.Int32,System.String,System.DateTimeOffset)">
            <summary>Ba cột lượt quét cần — cố ý không phải entity, xem <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveService.ArchivePendingAsync(System.Threading.CancellationToken)"/>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ArchiveOutcome">
            <summary>Kết quả xử lý một tin trong lượt lưu.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ArchiveOutcome.Archived">
            <summary>Đã tải về và thay URL</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ArchiveOutcome.AlreadyOwn">
            <summary>URL đã là của LADA — chỉ ghi lại đường dẫn đĩa</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ArchiveOutcome.WillRetry">
            <summary>Hỏng tạm, lượt sau thử lại</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ArchiveOutcome.Gone">
            <summary>Hỏng vĩnh viễn (tệp đã chết, định dạng không lưu, host lạ) — thôi thử</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatMediaArchiveRunResult">
            <summary>Tổng kết một lượt của job lưu tệp đính kèm.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavPermissions">
            <summary>
            Các liên kết điều hướng và khối cấu hình của miền chat có được hiện cho một người hay không
            (sổ nợ PP-39, PP-46).
            </summary>
            <remarks>
            <para>
            <b>Hàm thuần</b> — không chạm database, không đọc <c>HttpContext</c>: nhận danh sách role đã
            phân giải, trả các cờ. Tách ra đúng cách <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatRealtimeAudience"/> tách khỏi lớp
            đẩy tin, và vì đúng một lý do: hai khuôn cùng họ đang chạy trong sản phẩm —
            <c>CanViewTeam</c> ở <c>ChatQualityController</c> và <c>CanReplay</c> ở
            <c>ChatDistributionController</c> — đều tính thẳng trong controller và vì thế
            <b>không có một ca test nào</b>. Một luật quyết định ai thấy gì thì phải có ca test gọi
            thẳng vào nó.
            </para>
            <para>
            <b>Vì sao cần cờ từ máy chủ.</b> SPA cố ý không nhận danh sách role vào router (xem
            <c>routers/socialChat.js</c>), nên <c>meta.roles</c> là tài liệu chứ không phải hàng rào —
            thứ duy nhất ẩn được một liên kết là một cờ như thế này. Chép tên role sang JavaScript là
            dựng nguồn sự thật thứ hai, và cái lệch chỉ lộ ra khi một sale bấm vào rồi ăn 403.
            </para>
            <para>
            Đây là lần thứ <b>bảy và tám</b> của họ lỗi "route mở cho vai A nhưng API đòi vai B" trong
            cùng một đợt.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavPermissions.Founder">
            <summary>Vai bỏ qua mọi kiểm tra role của hệ thống.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavPermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c>; <c>null</c> = không có role nào</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavFlags">
            <summary>Kết quả của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavPermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String})"/>.</summary>
            <param name="CanViewDistribution">Được thấy liên kết "Điều phối" → <c>/dieu-phoi-chat</c></param>
            <param name="CanOpenChannelPage">
            Được thấy liên kết "Kênh chat" → <c>/kenh-chat</c>, tức dùng được <b>ít nhất một</b> khối
            trên trang đó
            </param>
            <param name="CanManageChannels">
            Được cấp quyền OAuth / bật-tắt / xoá kênh — <b>hẹp hơn</b>
            <paramref name="CanOpenChannelPage"/>
            </param>
            <param name="CanUpdateAssignmentSettings">
            Được thấy khối "Cấu hình kênh" (bưu cục sở hữu + chế độ phân phối) — đòi <b>cả hai</b>
            <c>ChatChannel.StaffAssign</c> và <c>ChatDistribution.Manage</c>, hoặc <c>Founder</c>;
            độc lập với <paramref name="CanManageChannels"/>
            </param>
            <param name="CanUseQuickReplies">
            Được thấy nút "Tin nhắn nhanh" ở ô soạn tin, nạp danh sách chọn và gửi từ mẫu —
            <c>ChatConversation.Send</c> hoặc <c>Founder</c>
            </param>
            <param name="CanManageSharedQuickReplies">
            Được thấy nút Thêm/Sửa/Xoá mẫu dùng chung ở <c>/tin-nhan-nhanh</c> —
            <c>ChatQuickReply.ManageShared</c> hoặc <c>Founder</c>
            </param>
            <param name="CanCreateCustomer">
            Được thấy nút "Tạo khách hàng mới" trong ô gắn khách — đòi <b>cả hai</b>
            <c>Customer.CreateOrUpdate</c> và <c>ChatConversation.LinkCustomer</c>, hoặc <c>Founder</c>
            </param>
            <param name="CanCreateOrder">
            Được thấy nút "Tạo đơn" của hội thoại đã gắn khách — <c>Order.CreateOrder</c> hoặc <c>Founder</c>
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavFlags.#ctor(System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean)">
            <summary>Kết quả của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavPermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String})"/>.</summary>
            <param name="CanViewDistribution">Được thấy liên kết "Điều phối" → <c>/dieu-phoi-chat</c></param>
            <param name="CanOpenChannelPage">
            Được thấy liên kết "Kênh chat" → <c>/kenh-chat</c>, tức dùng được <b>ít nhất một</b> khối
            trên trang đó
            </param>
            <param name="CanManageChannels">
            Được cấp quyền OAuth / bật-tắt / xoá kênh — <b>hẹp hơn</b>
            <paramref name="CanOpenChannelPage"/>
            </param>
            <param name="CanUpdateAssignmentSettings">
            Được thấy khối "Cấu hình kênh" (bưu cục sở hữu + chế độ phân phối) — đòi <b>cả hai</b>
            <c>ChatChannel.StaffAssign</c> và <c>ChatDistribution.Manage</c>, hoặc <c>Founder</c>;
            độc lập với <paramref name="CanManageChannels"/>
            </param>
            <param name="CanUseQuickReplies">
            Được thấy nút "Tin nhắn nhanh" ở ô soạn tin, nạp danh sách chọn và gửi từ mẫu —
            <c>ChatConversation.Send</c> hoặc <c>Founder</c>
            </param>
            <param name="CanManageSharedQuickReplies">
            Được thấy nút Thêm/Sửa/Xoá mẫu dùng chung ở <c>/tin-nhan-nhanh</c> —
            <c>ChatQuickReply.ManageShared</c> hoặc <c>Founder</c>
            </param>
            <param name="CanCreateCustomer">
            Được thấy nút "Tạo khách hàng mới" trong ô gắn khách — đòi <b>cả hai</b>
            <c>Customer.CreateOrUpdate</c> và <c>ChatConversation.LinkCustomer</c>, hoặc <c>Founder</c>
            </param>
            <param name="CanCreateOrder">
            Được thấy nút "Tạo đơn" của hội thoại đã gắn khách — <c>Order.CreateOrder</c> hoặc <c>Founder</c>
            </param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavFlags.CanViewDistribution">
            <summary>Được thấy liên kết "Điều phối" → <c>/dieu-phoi-chat</c></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavFlags.CanOpenChannelPage">
            <summary>
            Được thấy liên kết "Kênh chat" → <c>/kenh-chat</c>, tức dùng được <b>ít nhất một</b> khối
            trên trang đó
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavFlags.CanManageChannels">
            <summary>
            Được cấp quyền OAuth / bật-tắt / xoá kênh — <b>hẹp hơn</b>
            <paramref name="CanOpenChannelPage"/>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavFlags.CanUpdateAssignmentSettings">
            <summary>
            Được thấy khối "Cấu hình kênh" (bưu cục sở hữu + chế độ phân phối) — đòi <b>cả hai</b>
            <c>ChatChannel.StaffAssign</c> và <c>ChatDistribution.Manage</c>, hoặc <c>Founder</c>;
            độc lập với <paramref name="CanManageChannels"/>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavFlags.CanUseQuickReplies">
            <summary>
            Được thấy nút "Tin nhắn nhanh" ở ô soạn tin, nạp danh sách chọn và gửi từ mẫu —
            <c>ChatConversation.Send</c> hoặc <c>Founder</c>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavFlags.CanManageSharedQuickReplies">
            <summary>
            Được thấy nút Thêm/Sửa/Xoá mẫu dùng chung ở <c>/tin-nhan-nhanh</c> —
            <c>ChatQuickReply.ManageShared</c> hoặc <c>Founder</c>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavFlags.CanCreateCustomer">
            <summary>
            Được thấy nút "Tạo khách hàng mới" trong ô gắn khách — đòi <b>cả hai</b>
            <c>Customer.CreateOrUpdate</c> và <c>ChatConversation.LinkCustomer</c>, hoặc <c>Founder</c>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavFlags.CanCreateOrder">
            <summary>
            Được thấy nút "Tạo đơn" của hội thoại đã gắn khách — <c>Order.CreateOrder</c> hoặc <c>Founder</c>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSpan">
            <summary>
            Một khoảng nhật ký trạng thái, đã tách khỏi entity để hàm dựng bảng thời lượng là hàm thuần.
            </summary>
            <param name="Status">Trạng thái khai báo trong khoảng</param>
            <param name="FromTime">Bắt đầu khoảng</param>
            <param name="ToTime">Kết thúc khoảng, <c>null</c> = đang mở</param>
            <param name="ExpiresAt">Thời hạn trạng thái tự hết, <c>null</c> = không có hạn</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSpan.#ctor(Lada.Framework.Data.Enums.ChatAgentStatus,System.DateTimeOffset,System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset})">
            <summary>
            Một khoảng nhật ký trạng thái, đã tách khỏi entity để hàm dựng bảng thời lượng là hàm thuần.
            </summary>
            <param name="Status">Trạng thái khai báo trong khoảng</param>
            <param name="FromTime">Bắt đầu khoảng</param>
            <param name="ToTime">Kết thúc khoảng, <c>null</c> = đang mở</param>
            <param name="ExpiresAt">Thời hạn trạng thái tự hết, <c>null</c> = không có hạn</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSpan.Status">
            <summary>Trạng thái khai báo trong khoảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSpan.FromTime">
            <summary>Bắt đầu khoảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSpan.ToTime">
            <summary>Kết thúc khoảng, <c>null</c> = đang mở</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSpan.ExpiresAt">
            <summary>Thời hạn trạng thái tự hết, <c>null</c> = không có hạn</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceDurations">
            <summary>
            Dựng bảng "trạng thái nào bao nhiêu phút" từ nhật ký trạng thái — <b>hàm thuần</b>, không
            chạm database, không hỏi đồng hồ.
            <para>
            Đây là hàm mà tiêu chí "xong khi" của giai đoạn C nói tới: <i>bảng thời lượng một ngày dựng
            lại từ <c>ChatAgentPresenceLog</c> khớp từng phút</i>. Và cũng là nơi tiêu chí chấm điểm
            <c>chat.availability</c> của giai đoạn F sẽ đọc.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceDurations.Build(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSpan},System.DateTimeOffset,System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Tổng thời lượng từng trạng thái trong cửa sổ <c>[from, to)</c>.
            </summary>
            <remarks>
            <para>
            <b>Hai phép cắt, và cả hai đều bắt buộc:</b>
            </para>
            <list type="number">
            <item><b>Cắt theo cửa sổ.</b> Khoảng bắc qua hai đầu cửa sổ chỉ được tính phần nằm
            trong. Không có phép cắt này thì xem báo cáo của một ngày lại cộng cả thời lượng của
            hôm trước.</item>
            <item><b>Cắt theo hạn.</b> Trạng thái tự khai có hạn thì <b>tự hết</b> lúc
            <c>ExpiresAt</c> — phần từ đó tới khi dòng thật sự đóng là
            <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Available"/>, không phải trạng thái cũ. Bỏ phép cắt này là
            đếm một lượt "Bận 30 phút" lúc 9 giờ sáng thành "Bận cả ngày", vì dòng nhật ký chỉ đóng
            khi người ta bấm đổi trạng thái lần sau. Cách chữa khác duy nhất là một job quét, mà
            job thì chỉ chính xác tới đúng chu kỳ của nó — "khớp từng phút" sẽ không bao giờ đúng.</item>
            </list>
            <para>
            <b>Không</b> lấp khoảng trống giữa hai dòng nhật ký. Người chưa từng đổi trạng thái lần
            nào không có dòng nào, và trả về một bảng rỗng là câu trả lời đúng — coi khoảng trống là
            <see cref="F:Lada.Framework.Data.Enums.ChatAgentStatus.Available"/> ở đây nghĩa là bịa ra thời lượng cho người chưa
            bao giờ dùng tính năng. Ai cần "phần còn lại của ngày" thì tự lấy độ dài cửa sổ trừ đi
            tổng của bảng này — phép trừ đó nằm ở người gọi vì chỉ họ biết cửa sổ nào có nghĩa
            (cả ngày hay chỉ giờ làm việc).
            </para>
            </remarks>
            <param name="spans">Các khoảng nhật ký, không cần sắp xếp trước</param>
            <param name="from">Đầu cửa sổ (tính vào)</param>
            <param name="to">Cuối cửa sổ (không tính vào)</param>
            <param name="now">
            "Bây giờ", dùng làm điểm kết cho khoảng đang mở. Truyền vào chứ không hỏi đồng hồ.
            </param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresencePermissions">
            <summary>
            Ba đường GHI của hộp thoại quản lý trạng thái sale có mở cho một người hay không
            (sổ nợ PP-36, chỗ (b)).
            </summary>
            <remarks>
            <para>
            <b>Hàm thuần</b>, cùng lý do và cùng khuôn với <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavPermissions"/>.
            </para>
            <para>
            <b>Vì sao BA cờ chứ không một.</b> Ba tab của hộp thoại gọi ba endpoint khác nhau, và bó
            quyền của chúng <b>không giống nhau</b>: <c>POST presence/staff</c> và
            <c>POST presence/suspend</c> chỉ nhận <c>ChatAgentPresence.ManageOthers</c>, còn
            <c>POST presence/delegate</c> nhận thêm <c>ChatDistribution.Manage</c>. Một cờ dùng chung
            sẽ hoặc ẩn tab "Uỷ quyền tạm" khỏi người điều phối được phép dùng nó, hoặc mở hai tab kia
            cho người chắc chắn ăn 403 — tức chính lỗi đang chữa, chỉ đổi vai người chịu.
            </para>
            <para>
            <b>Đường ĐỌC không có cờ, và đó là chủ ý.</b> <c>GET presence/staff/{id}</c> cùng
            <c>POST presence/report</c> mở rộng hơn hẳn — thêm <c>ChatDistribution.Manage</c> và
            <c>ChatConversation.ViewChannel</c> — nên một trưởng nhóm kênh đọc được bảng thời lượng mà
            không đặt được trạng thái hộ. Chính khoảng lệch đó là PP-36 (b): hộp thoại mở cho người chỉ
            có <c>ViewChannel</c> và cả ba tab đều chắc chắn 403.
            </para>
            <para>
            <b>Cờ chỉ phản ánh ROLE, không phản ánh PHẠM VI.</b> Ba đường ghi còn một hàng rào thứ hai
            theo từng nhân viên đích ("Không tìm thấy nhân viên trong phạm vi quản lý của bạn"), và cố
            ý <b>không</b> đưa vào đây. Ranh giới: cái gì <b>không bao giờ</b> chạy được thì ẩn đi; cái
            gì chạy được với người này mà không với người kia thì để nút đó, và để máy chủ trả lời bằng
            một câu nói đúng lý do. Ẩn theo phạm vi còn cần một cờ cho <b>mỗi dòng</b> nhân viên, mà
            dòng ấy đi trong <c>SmartTableResult</c> — kiểu không có chỗ cho trường phụ.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresencePermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <param name="roles">Role đã phân giải qua <c>IUserRoleResolver</c></param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceFlags">
            <summary>Kết quả của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresencePermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String})"/>.</summary>
            <param name="CanSetStatus">Đặt trạng thái hộ — <c>POST presence/staff</c></param>
            <param name="CanSuspend">Tạm ngưng nhận khách — <c>POST presence/suspend</c></param>
            <param name="CanDelegate">Uỷ quyền tạm — <c>POST presence/delegate</c></param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceFlags.#ctor(System.Boolean,System.Boolean,System.Boolean)">
            <summary>Kết quả của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresencePermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String})"/>.</summary>
            <param name="CanSetStatus">Đặt trạng thái hộ — <c>POST presence/staff</c></param>
            <param name="CanSuspend">Tạm ngưng nhận khách — <c>POST presence/suspend</c></param>
            <param name="CanDelegate">Uỷ quyền tạm — <c>POST presence/delegate</c></param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceFlags.CanSetStatus">
            <summary>Đặt trạng thái hộ — <c>POST presence/staff</c></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceFlags.CanSuspend">
            <summary>Tạm ngưng nhận khách — <c>POST presence/suspend</c></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceFlags.CanDelegate">
            <summary>Uỷ quyền tạm — <c>POST presence/delegate</c></summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceConfigKeys">
            <summary>
            Tên khoá <c>AppConfig</c> của trạng thái sẵn sàng — seed bằng migration <c>M202608291530</c>,
            không hardcode giá trị ở nơi khác.
            <para>
            Đây là những khoá tiền tố <c>Chat.</c> đầu tiên của repo: cấu hình chat trước nay nằm ở
            <c>appsettings</c> (<c>SocialChat:Zalo:*</c>). Chọn <c>AppConfig</c> có chủ ý — giờ làm việc là
            thứ người vận hành phải đổi được từ màn quản trị mà không cần deploy lại.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceConfigKeys.WorkingHoursStart">
            <summary>Giờ vào làm, dạng <c>HH:mm</c></summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceConfigKeys.WorkingHoursEnd">
            <summary>Giờ tan làm, dạng <c>HH:mm</c></summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceConfigKeys.WorkingHoursBreakStart">
            <summary>Giờ bắt đầu nghỉ trưa, dạng <c>HH:mm</c></summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceConfigKeys.WorkingHoursBreakEnd">
            <summary>Giờ kết thúc nghỉ trưa, dạng <c>HH:mm</c></summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceConfigKeys.WorkingHoursWorkingDays">
            <summary>Ngày làm trong tuần, ngăn cách bằng dấu phẩy, 2 = Thứ Hai … 8 = Chủ Nhật</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceConfigKeys.MaxSelfStatusMinutes">
            <summary>Trần thời hạn cho trạng thái tự khai Bận / Ra ngoài, tính bằng phút</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceConfigKeys.MaxLeaveDays">
            <summary>Trần thời hạn cho trạng thái Nghỉ, tính bằng ngày</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceConfigKeys.DelegateOnLeaveDays">
            <summary>Nghỉ từ bấy nhiêu ngày trở lên thì tự uỷ quyền tạm; 0 = tắt hẳn uỷ quyền tự động</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceConfigKeys.TimeZoneOffsetHours">
            <summary>
            Múi giờ ứng dụng, đã được seed sẵn từ migration <c>M202608161200</c> của đợt chấm công
            nhưng <b>chưa có dòng code nào đọc</b> cho tới giai đoạn này.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatPresenceSettings">
            <summary>
            Đọc và diễn giải các khoá cấu hình của trạng thái sẵn sàng.
            </summary>
            <remarks>
            Tách riêng để chỉ có <b>một</b> nơi diễn giải chuỗi cấu hình — mỗi nơi tự parse một kiểu là mỗi
            nơi sai một kiểu (bài học phân hệ KPI). Cũng nhờ tách mà test chạy được lớp này <b>thật</b>
            trên <c>FakeAppConfigService</c> thay vì giả lập chính nó.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatPresenceSettings.GetWorkingHoursAsync">
            <summary>
            Cửa sổ giờ làm việc, đã dựng xong từ 6 khoá cấu hình. Không bao giờ trả <c>null</c> và
            không bao giờ ném lỗi — giá trị hỏng rơi về <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Default"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatPresenceSettings.GetMaxSelfStatusMinutesAsync">
            <summary>Trần thời hạn cho Bận / Ra ngoài, tính bằng phút (mặc định 120)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatPresenceSettings.GetMaxLeaveDaysAsync">
            <summary>Trần thời hạn cho Nghỉ, tính bằng ngày (mặc định 30)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatPresenceSettings.GetDelegateOnLeaveDaysAsync">
            <summary>
            Ngưỡng ngày nghỉ để tự uỷ quyền tạm (mặc định 1). Trả <c>0</c> nghĩa là tắt hẳn uỷ quyền
            tự động — quản lý vẫn bấm tay được.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSettings">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatPresenceSettings"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSettings.DefaultMaxSelfStatusMinutes">
            <summary>Trần mặc định cho Bận / Ra ngoài — §3.5 đề xuất 120 phút</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSettings.DefaultMaxLeaveDays">
            <summary>Trần mặc định cho Nghỉ</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSettings.DefaultDelegateOnLeaveDays">
            <summary>Ngưỡng uỷ quyền tạm mặc định — CH-7 chốt "nghỉ từ 1 ngày trở lên"</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSettings.DefaultTimeZoneOffsetHours">
            <summary>Múi giờ mặc định khi khoá <c>App.TimeZoneOffsetHours</c> đọc không ra</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSettings.GetWorkingHoursAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSettings.GetMaxSelfStatusMinutesAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSettings.GetMaxLeaveDaysAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatPresenceSettings.GetDelegateOnLeaveDaysAsync">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRawValue">
            <summary>
            Số thô của một tiêu chí kèm <b>cỡ mẫu</b> — thứ mọi provider phải trả về.
            </summary>
            <remarks>
            <c>Sample</c> không phải trường tuỳ chọn. Nó là thứ duy nhất phân biệt "điểm 100 vì làm tốt" với
            "điểm 100 vì có đúng một mẫu", và số đo F-0 làm điều đó thành vấn đề sống còn chứ không phải cẩn
            thận thừa: trên dev, hai người duy nhất có tin quy được về mình (<c>#251</c>, <c>#1</c>) không
            giao một phần tử nào với danh sách sale phụ trách kênh (<c>#252…#255</c>).
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRawValue.Value">
            <summary>Số thô — trung vị phút, tỉ lệ phần trăm…</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRawValue.Sample">
            <summary>
            Số quan sát đứng sau <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRawValue.Value"/>. <b>0 nghĩa là không chấm được</b>, khác hẳn "chấm
            được và ra 0".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRawValue.KhongCoMau">
            <summary>Không có mẫu nào — tiêu chí bị loại khỏi cả tử số lẫn mẫu số của điểm tổng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityCriterionScore">
            <summary>Một tiêu chí đã chấm xong: số thô, cỡ mẫu, điểm chuẩn hoá.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityCriterionScore.NormalizedScore">
            <summary>Điểm 0–100. <c>null</c> khi cỡ mẫu bằng 0 — <b>không chấm được</b>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityCriterionScore.ChamDuoc">
            <summary>Tiêu chí này có góp vào điểm tổng không</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityOverall">
            <summary>Kết quả gộp điểm của một người.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityOverall.Score">
            <summary>Điểm tổng 0–100</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityOverall.DistributionWeight">
            <summary>Trọng số phân phối suy từ <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityOverall.Score"/></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityOverall.IsProvisional">
            <summary>Điểm chưa đủ căn cứ — mang điểm mặc định thay vì số tính ra</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityOverall.ProvisionalReason">
            <summary>Câu tiếng Việt nói vì sao tạm tính; rỗng khi không tạm tính</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityOverall.TotalSample">
            <summary>Tổng cỡ mẫu của mọi tiêu chí chấm được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityOverall.ScoredCriteriaCount">
            <summary>Số tiêu chí thật sự chấm được</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityThreshold">
            <summary>Ngưỡng và chiều của một tiêu chí — phần <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules"/> cần để chấm.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules">
            <summary>
            Luật chấm điểm chất lượng chat (giai đoạn F) — <b>hàm thuần</b>: không chạm database, không đọc
            đồng hồ, không đọc cấu hình.
            </summary>
            <remarks>
            <para>
            Cùng khuôn <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules"/> của giai đoạn D và <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules"/> của
            giai đoạn E, và vì cùng một lý do: đây là phần <b>người ta sẽ đi khiếu nại</b>, nên nó phải kiểm
            được bằng một bảng ca đầu-vào → đầu-ra mà không cần dựng database.
            </para>
            <para>
            <b>Mượn công thức của <c>KpiEngineService.CalculateScore</c>, không mượn bảng</b> (§3.6): nội
            suy tuyến tính giữa hai ngưỡng, kẹp hai đầu, rồi nhân trọng số. Chỗ khác duy nhất là mẫu số —
            KPI chia cho hằng số 100 vì nó ép tổng trọng số phải đúng 100 % mới cho giao chỉ tiêu; ở đây
            mẫu số là <b>tổng trọng số của những tiêu chí thật sự chấm được</b>. Bốn trong năm tiêu chí rỗng
            dữ liệu lúc mở màn (số đo F-0), nên chia cho 100 là bắt một tiêu chí duy nhất gánh cả điểm và
            mọi sale sẽ ra dưới 25 điểm.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules.DiemToiThieu">
            <summary>Điểm thấp nhất và cao nhất sau chuẩn hoá</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules.DiemToiDa">
            <summary>Điểm cao nhất sau chuẩn hoá</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules.SanTrongSo">
            <summary>
            Sàn trọng số phân phối. <b>0,4 là cố ý</b> — xem <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules.TinhTrongSoPhanPhoi(System.Decimal)"/>.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules.TranTrongSo">
            <summary>Trần trọng số phân phối</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules.HeSoDiem">
            <summary>Hệ số nhân của điểm trong công thức trọng số</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules.SoChuSoThapPhan">
            <summary>Số chữ số thập phân giữ lại ở mọi bước — khớp <c>KpiEngineService.ScoreDecimals</c></summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules.ChuanHoa(System.Decimal,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityThreshold)">
            <summary>
            Chuẩn hoá một số thô về thang 0–100 bằng nội suy tuyến tính giữa
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityThreshold.BadThreshold"/> và
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityThreshold.GoodThreshold"/>, <b>kẹp hai đầu</b>.
            </summary>
            <remarks>
            <para>
            Kẹp chứ không ngoại suy: một sale trả lời trung vị 0,3 phút không được 400 điểm, và một sale
            trung vị 300 phút không bị âm điểm kéo tụt cả điểm tổng. Đây đúng là điều <c>CapPercent</c>
            của KPI làm ở đầu trên; đầu dưới thì KPI không cần vì % hoàn thành vốn không âm.
            </para>
            <para>
            Hai ngưỡng bằng nhau là <b>cấu hình hỏng</b>, không phải ca biên hợp lệ — không có phép nội
            suy nào giữa hai điểm trùng nhau. Trả <c>null</c> (không chấm được) thay vì chia cho 0 hay
            đoán một giá trị: cho 0 điểm là phạt người dùng vì người vận hành gõ sai cấu hình, cho 100
            điểm là thưởng họ vì cùng lý do.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules.Gop(System.Collections.Generic.IReadOnlyCollection{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityCriterionScore},System.Int32,System.Int32,System.Int32,System.Decimal)">
            <summary>
            Gộp điểm của các tiêu chí thành điểm tổng và trọng số phân phối.
            </summary>
            <param name="criteria">Điểm từng tiêu chí — cả những cái không chấm được</param>
            <param name="soNgayCoMat">Số ngày sale đã phụ trách kênh; dưới <paramref name="minDays"/> là tạm tính</param>
            <param name="minDays">Ngưỡng <c>Chat.Quality.MinDays</c></param>
            <param name="minSamples">Ngưỡng <c>Chat.Quality.MinSamples</c></param>
            <param name="defaultScore">Điểm mặc định <c>Chat.Quality.DefaultScore</c> khi tạm tính</param>
            <remarks>
            <para>
            <b>Điểm tổng = Σ(trọng số × điểm chuẩn hoá) / Σ trọng số</b>, chỉ trên những tiêu chí có cỡ
            mẫu &gt; 0. Tiêu chí không chấm được bị loại khỏi <b>cả tử số lẫn mẫu số</b> — cho nó 0 điểm
            rồi vẫn chia cho tổng trọng số đầy đủ là phạt sale vì hệ thống chưa có dữ liệu về họ.
            </para>
            <para>
            <b>Không tiêu chí nào chấm được</b> thì kết quả là tạm tính mang điểm mặc định, không phải 0.
            Đây là trạng thái của <b>mọi</b> sale trên dev hôm nay theo số đo F-0.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules.TinhTrongSoPhanPhoi(System.Decimal)">
            <summary>
            Từ điểm sang trọng số phân phối: <c>clamp(0,4 + 0,9 × score/100 , 0,4 , 1,3)</c>.
            </summary>
            <remarks>
            <b>Sàn 0,4 là cố ý</b> (§3.6), và đây là chỗ dễ bị đề nghị "cho về 0 cho dứt khoát" nhất nên
            lý do phải nằm ngay cạnh công thức. Đẩy một sale về 0 khách là đẩy họ vào chỗ <b>không bao
            giờ cải thiện được điểm nữa</b> — mọi tiêu chí ở đây đều cần có khách mới đo được, nên 0
            khách là 0 mẫu là điểm đứng yên vĩnh viễn. Đó là một vòng lặp chết, không phải một hình phạt.
            Và về quản lý nhân sự, cắt hẳn một người phải là quyết định của con người có tên chịu trách
            nhiệm: muốn cắt thì quản lý bấm tạm ngưng (<c>ChatAgentPresence.SuspendedUntil</c>).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules.LyDoTamTinh(System.Int32,System.Int32,System.Int32,System.Int32,System.Int32,System.Decimal)">
            <summary>
            Vì sao điểm này là tạm tính — <c>null</c> nghĩa là đủ căn cứ.
            </summary>
            <remarks>
            Bốn lý do, và cả bốn đều nói được thành một câu cho người dùng đọc. Trả về câu chữ chứ không
            trả về mã lý do vì đây là thứ hiện thẳng lên trang "điểm của tôi": một sale mới không cần
            biết mã, họ cần biết còn thiếu gì.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules.Kep(System.Decimal,System.Decimal,System.Decimal)">
            <summary>Kẹp một giá trị vào đoạn <c>[can, tran]</c></summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules.LamTron(System.Decimal)">
            <summary>Làm tròn về <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules.SoChuSoThapPhan"/> chữ số, làm tròn nửa lên</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRules.TrungVi(System.Collections.Generic.IReadOnlyList{System.Decimal})">
            <summary>
            Trung vị của một dãy số. Dãy rỗng trả <c>null</c> — <b>không</b> trả 0.
            </summary>
            <remarks>
            <para>
            <b>Trung vị chứ không phải trung bình</b> (§3.6): một hội thoại quên 6 tiếng không được phép
            xoá sổ cả tháng làm tốt. Số đo Đ5 cho thấy đuôi phân bố dài đến mức trung bình vô nghĩa —
            trung vị 0,82 phút trong khi max là 525.808 phút.
            </para>
            <para>
            Dãy chẵn phần tử lấy trung bình cộng hai phần tử giữa, theo định nghĩa chuẩn.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityConfigKeys">
            <summary>
            Tên khoá <c>AppConfig</c> của điểm chất lượng (giai đoạn F) — seed bằng migration, không
            hardcode giá trị ở nơi khác.
            </summary>
            <remarks>
            Theo đúng khuôn <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaConfigKeys"/> của giai đoạn E và
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionConfigKeys"/> của giai đoạn D: hằng tên khoá ở một chỗ, một lớp duy
            nhất diễn giải chuỗi, <c>InvariantCulture</c>, giá trị hỏng rơi về phía an toàn thay vì ném lỗi
            giữa một lượt tính điểm.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityConfigKeys.AffectsDistribution">
            <summary>
            Công tắc <b>duy nhất</b> để điểm chạm vào đường phân phối. <c>true</c> / <c>false</c>. Mặc
            định <b>TẮT</b>.
            </summary>
            <remarks>
            <para>
            Đây là mục 3 của nguyên tắc số 1: <i>"Điểm chất lượng không được ảnh hưởng phân phối trước
            khi có dữ liệu."</i> Tắt thì máy phân phối không đọc tới
            <c>ChatQualitySummary.DistributionWeight</c> và mọi người mang trọng số 1,0 — y hệt trước
            giai đoạn F.
            </para>
            <para>
            Bật nó là <b>bước 8</b> của trình tự lên production: sau ≥ 30 ngày có dữ liệu, và phải
            <b>báo đội sale trước</b> vì nó đổi <b>số lượng</b> việc họ nhận. Bước 6 (tắt
            <c>Chat.Distribution.DryRun</c>) đổi <i>cách</i> họ nhận việc; bước này đổi <i>bao nhiêu</i>.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityConfigKeys.MinDays">
            <summary>Dưới bấy nhiêu ngày phụ trách kênh thì điểm là tạm tính</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityConfigKeys.MinSamples">
            <summary>Dưới bấy nhiêu quan sát thì điểm là tạm tính</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityConfigKeys.DefaultScore">
            <summary>Điểm gán cho người chưa đủ dữ liệu</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQualitySettings">
            <summary>
            Đọc và diễn giải các khoá cấu hình của điểm chất lượng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQualitySettings.AffectsDistributionAsync">
            <summary>
            Điểm có được nhân vào trọng số phân phối không. <b>Mặc định <c>false</c></b>.
            </summary>
            <remarks>
            Cùng khuôn rơi-về-phía-an-toàn của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatSlaSettings.IsEnabledAsync"/>, và cùng
            chiều với nó: hai hướng hỏng không cân nhau. Không bật thì tệ nhất là máy chia đều như hôm
            nay; bật nhầm là đổi số lượng việc của người thật dựa trên một bảng điểm mà số đo F-0 cho
            thấy <b>4/5 tiêu chí đang rỗng dữ liệu</b>.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQualitySettings.GetMinDaysAsync">
            <summary>Ngưỡng số ngày phụ trách kênh để hết tạm tính (mặc định 14)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQualitySettings.GetMinSamplesAsync">
            <summary>Ngưỡng cỡ mẫu để hết tạm tính (mặc định 20)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQualitySettings.GetDefaultScoreAsync">
            <summary>Điểm mặc định của người tạm tính (mặc định 70)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualitySettings">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQualitySettings"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualitySettings.DefaultAffectsDistribution">
            <summary>
            Bật hay tắt khi khoá đọc không ra. Xem
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQualitySettings.AffectsDistributionAsync"/> để biết vì sao chiều này.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualitySettings.DefaultMinDays">
            <summary>Số ngày tối thiểu — 14, theo §3.6</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualitySettings.DefaultMinSamples">
            <summary>Cỡ mẫu tối thiểu — 20, theo §3.6</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualitySettings.DefaultDefaultScore">
            <summary>
            Điểm mặc định của sale mới — 70, theo §3.6. Cho trọng số phân phối 1,03: nhỉnh hơn mức
            trung bình một chút, đúng tinh thần <b>không phạt người mới vì họ mới</b>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualitySettings.AffectsDistributionAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualitySettings.GetMinDaysAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualitySettings.GetMinSamplesAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualitySettings.GetDefaultScoreAsync">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepResult">
            <summary>Kết quả một lượt quét hàng chờ — dùng cho log và cho test.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepResult.QueuedCount">
            <summary>Số hội thoại còn nằm hàng chờ lúc quét</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepResult.AssignedCount">
            <summary>Số hội thoại vừa giao được cho người</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepResult.AlertedCount">
            <summary>Số hội thoại vừa báo cho trưởng nhóm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepResult.SkippedNoOneOnShiftCount">
            <summary>
            Số hội thoại <b>không</b> được xét báo vì lúc quét không có ứng viên nào của kênh vào ca
            (KC-18, §8.7 câu 3b) — chúng chờ lượt quét đầu ca kế tiếp, không bị đánh dấu đã báo.
            </summary>
            <remarks>
            Số đếm riêng để log của job phân biệt được "hàng chờ im vì chưa tới ngưỡng" với "hàng chờ
            im vì cả kênh đang Nghỉ" — hai tình huống giống hệt nhau nếu chỉ nhìn <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepResult.AlertedCount"/>.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQueueSweepService">
            <summary>
            Quét hàng chờ: thử phân phối lại những hội thoại chưa ai nhận, và báo trưởng nhóm khi khách
            chờ quá lâu (giai đoạn D).
            </summary>
            <remarks>
            <para>
            Máy phân phối chạy ngay khi tin của khách đến, nên hàng chờ chỉ sinh ra khi <b>lúc đó</b>
            không ai đủ điều kiện — ngoài giờ làm, cả đội bận, hoặc chưa ai được xếp phụ trách kênh.
            Lượt quét này là thứ đưa hội thoại ra khỏi hàng chờ khi điều kiện đổi mà khách không nhắn
            thêm gì. Không có nó thì một khách nhắn lúc 22 giờ nằm chờ tới khi họ tự nhắn lại.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQueueSweepService.SweepAsync(System.DateTimeOffset)">
            <summary>Chạy một lượt quét.</summary>
            <param name="now">Mốc quét — tham số để test được mà không phụ thuộc đồng hồ máy</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQueueSweepService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.TranMoiLuot">
            <summary>
            Trần số hội thoại xử lý trong một lượt quét.
            </summary>
            <remarks>
            Job chạy mỗi 2 phút; một lượt quét ôm cả nghìn hội thoại là một lượt quét chạy quá 2
            phút rồi chồng lên lượt sau. Cắt trần thì phần dư sang lượt kế tiếp — hàng chờ được xếp
            theo tin đến sớm nhất nên người chờ lâu nhất luôn nằm trong mẻ đầu. <b>Cắt bao nhiêu
            thì log ra bấy nhiêu</b>: một phép cắt im lặng đọc thành "đã xử lý hết".
            <para>
            Khi vượt trần, kênh đang có người vào ca đứng trước kênh không ai trực (KC-18, bản vá sau
            review) — xem <c>LayMeKhiVuotTranAsync</c>.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.SweepAsync(System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.HangChoCua(System.Collections.Generic.List{System.Int32})">
            <summary>Hội thoại chưa ai nhận, chưa đóng, trên các kênh cho trước.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.TheoThuTuCho(System.Linq.IQueryable{Lada.Framework.Data.Domains.SocialChat.ChatConversation})">
            <summary>
            Người chờ lâu nhất đứng đầu — cùng thứ tự mà màn hàng chờ đang hiện, để người điều phối và
            máy không bao giờ nhìn hai thứ tự khác nhau.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.LayMeKhiVuotTranAsync(System.Collections.Generic.List{System.Int32},System.DateTimeOffset)">
            <summary>
            Lấy mẻ khi hàng chờ <b>vượt trần</b>: hội thoại của kênh <b>lúc này có người vào ca</b> đứng
            trước, rồi mới tới kênh không ai trực — mỗi nhóm vẫn xếp theo thứ tự chờ.
            </summary>
            <remarks>
            <para>
            Bản vá sau review KC-18. Trần "phần dư sang lượt sau" chỉ đúng khi đầu mẻ rồi cũng vơi đi.
            Từ khi mỗi người một giờ làm, một kênh chỉ có người ca ngày dồn hàng chờ suốt đêm — không
            ai nhận được, không ai bị báo (<see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.KetQuaBao.KhongAiVaoCa"/>) — và vì cũ nhất nên
            chiếm trọn mẻ 200 mỗi lượt. Hội thoại của một kênh <i>có</i> người trực đêm đứng sau vị trí
            200 thì cả đêm không được thử chia lại, trưởng nhóm của nó cũng không được báo.
            </para>
            <para>
            <b>Xếp sau chứ không loại hẳn</b>, dù kênh không ai trực thì thử chia cũng không ra ai:
            "có người vào ca" đọc từ nhật ký trạng thái, còn máy chia đọc dòng trạng thái hiện tại — hai
            nguồn có thể lệch (dòng nhật ký treo, PP-27). Loại hẳn thì một lần lệch là hội thoại ấy
            không bao giờ được thử; xếp sau thì nó vẫn lấp chỗ trống còn lại của mẻ.
            </para>
            <para>
            Chỉ chạy khi vượt trần nên đường thường không tốn thêm truy vấn nào. Khi chạy, nó nạp phủ
            sóng tại <b>đúng mốc</b> <paramref name="now"/> (một lần cho mọi kênh), tách khỏi lần nạp
            cho đồng hồ báo trưởng nhóm ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.NapPhuSongAsync(System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.SocialChat.ChatConversation},System.DateTimeOffset)"/> vì lần ấy cần khoảng tính từ mốc
            chờ sớm nhất <b>của mẻ</b> — thứ chưa biết trước khi có mẻ. Nạp lỗi thì rơi về thứ tự cũ.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.KetQuaBao">
            <summary>Lượt xét báo của một hội thoại kết thúc thế nào.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.KetQuaBao.KhongBao">
            <summary>Không báo — đã báo rồi, chưa tới ngưỡng, không có mốc chờ, hoặc kênh chưa có trưởng nhóm</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.KetQuaBao.KhongAiVaoCa">
            <summary>Không báo vì lúc này không ứng viên nào của kênh vào ca — chờ đầu ca kế tiếp</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.KetQuaBao.DaBao">
            <summary>Vừa gửi thông báo</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.NapPhuSongAsync(System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.SocialChat.ChatConversation},System.DateTimeOffset)">
            <summary>
            Nạp phủ sóng cho các kênh có hội thoại <b>còn có thể phải báo</b> (chưa đánh dấu đã báo, có
            mốc chờ). Trả <c>null</c> khi không nạp được — lượt này khi đó không báo ai.
            </summary>
            <remarks>
            <para>
            Khoảng nạp là <c>[mốc chờ sớm nhất, now]</c> của đúng những hội thoại ấy: hội thoại đã báo
            không bao giờ báo lại nên không cần đếm, và bỏ chúng đi giữ khoảng nạp ngắn — một hội
            thoại bị bỏ quên nhiều tháng đã báo từ lâu không được kéo cả lượt quét về tận lúc đó.
            </para>
            <para>
            Lỗi nạp <b>không</b> được giết cả lượt: phần thử phân phối lại vẫn phải chạy cho mọi người
            trong hàng chờ. Nuốt lỗi, log, và không báo ai — không biết ai đang vào ca thì im lặng còn
            hơn đánh thức trưởng nhóm theo một phỏng đoán; và vì không đánh dấu đã báo nên lượt sau
            báo lại được.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.BaoTruongNhomAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverageBatch)">
            <summary>
            Báo trưởng nhóm của kênh khi một hội thoại chờ quá <c>Chat.Queue.AlertMinutes</c> phút
            <b>có người vào ca</b> (KC-18). Trả <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.KetQuaBao.DaBao"/> nếu vừa gửi.
            </summary>
            <remarks>
            <para>
            Gửi bằng <c>SendToUsersAsync</c> với người nhận tự tra, <b>không</b> bằng
            <c>SendToRoleAsync</c>: bản theo role gửi cho mọi người có role đó trên toàn hệ thống,
            không lọc kênh cũng không lọc chi nhánh — tức là trưởng nhóm của một Page ở Hải Phòng
            nhận thông báo về khách của một OA ở Hà Nội. Cùng lý lẽ đã ghi ở
            <c>TruckMaintenanceNotifier</c>.
            </para>
            <para>
            Mỗi hội thoại báo <b>một lần</b> cho mỗi lượt vào hàng chờ (cột <c>QueueAlertedAt</c>).
            Job chạy mỗi 2 phút, nên không có mốc ấy thì một hội thoại chờ nửa buổi sinh ra mười
            lăm thông báo giống hệt nhau và người nhận sẽ tắt hết thông báo của cả hệ thống.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.DanhDauDaBaoAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.DateTimeOffset)">
            <summary>
            Ghi mốc đã-báo bằng một câu <c>UPDATE</c> chạm <b>đúng một cột</b>.
            </summary>
            <remarks>
            <para>
            <b>Không được dùng <c>UpdateAsync(hoiThoai)</c> ở đây.</b> Thực thể này được nạp ở đầu
            lượt quét, và <c>UpdateAsync</c> ghi lại <b>cả dòng</b> theo ảnh chụp lúc ấy. Giữa lúc
            nạp và lúc ghi, một webhook có thể đã giao hội thoại cho ai đó — mà đường giao ấy là một
            câu <c>UPDATE</c> đi thẳng xuống database, <b>không</b> qua bộ theo dõi thay đổi, nên
            thực thể trong tay lượt quét vẫn mang <c>AssignedStaffId = null</c>. Ghi cả dòng là
            <b>xoá mất lượt gán vừa thắng</b>: khách đã có người, rồi lại không có ai, và nhật ký
            phân công thì vẫn ghi là đã giao.
            </para>
            <para>
            Đây đúng là mặt trái của lựa chọn ở <c>EfChatConversationClaim</c> — cùng một sự thật
            (câu <c>UPDATE</c> không qua bộ theo dõi) đọc theo hai chiều. Ở đó nó bắt sổ phân công
            phải đồng bộ lại thực thể; ở đây nó cấm ghi lại cả dòng từ một ảnh chụp cũ.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQueueSweepService.TruongNhomKenhAsync(System.Int32)">
            <summary>Trưởng nhóm và chủ của một kênh — đọc từ cửa chung, không chép lại truy vấn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuickReplyService">
            <summary>
            Mẫu tin nhắn nhanh ở ô soạn tin của khung chat đa kênh (docs/plan-tin-nhan-nhanh-chat.md §3.2, §3.3).
            </summary>
            <remarks>
            <para>
            <b>Hàng rào phạm vi nằm ở đây, không nằm ở controller.</b> Hai luật, mỗi luật đúng một chỗ:
            <c>VisibleTo</c> — người này <b>đọc/gửi</b> được mẫu nào (mẫu dùng chung + mẫu cá nhân của chính mình);
            <c>WritableIn</c> — một endpoint <b>ghi</b> được bản ghi nào (đúng phạm vi của endpoint, và đúng chủ với
            mẫu cá nhân). Không tham số nào từ client chọn được chủ hay phạm vi. Founder bỏ qua role nhưng
            <b>không</b> bỏ qua luật chủ nhân (§3.2, quyết định §6.9).
            </para>
            <para>
            Mọi trường hợp "không có quyền với bản ghi này" — mã của người khác, mã thuộc phạm vi kia, mã không tồn
            tại, mẫu đã xoá — trả <b>cùng một</b> câu "không tìm thấy". Phân biệt được chúng là nói cho người dò mã
            biết mã nào đang tồn tại.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuickReplyService.ForPickerAsync(System.Int32)">
            <summary>
            Danh sách gọn cho ô chọn ở ô soạn tin: mẫu dùng chung đang bật + mẫu cá nhân đang bật của tôi, sắp
            theo lượt dùng giảm dần, rồi thứ tự, rồi tiêu đề.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuickReplyService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,Lada.Framework.Data.Enums.ChatQuickReplyScope,System.Int32,System.Boolean)">
            <summary>
            Bảng ở trang quản lý. <see cref="F:Lada.Framework.Data.Enums.ChatQuickReplyScope.Personal"/> → chỉ mẫu của tôi, mọi trạng thái;
            <see cref="F:Lada.Framework.Data.Enums.ChatQuickReplyScope.Shared"/> → có quyền quản lý thì mọi trạng thái, không thì chỉ mẫu đang bật.
            </summary>
            <param name="canManageShared">
            Người gọi có quyền quản lý mẫu dùng chung — controller lấy từ <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatNavPermissions"/>, cùng
            nguồn với cờ <c>CanManageSharedQuickReplies</c> mà giao diện đọc
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuickReplyService.GetByIdAsync(System.Int32,System.Int32,System.Boolean)">
            <summary>
            Một mẫu để mở form sửa; <c>null</c> khi không thấy được — cùng luật với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuickReplyService.SearchAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,Lada.Framework.Data.Enums.ChatQuickReplyScope,System.Int32,System.Boolean)"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuickReplyService.SavePersonalAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SaveChatQuickReplyModel,System.Int32,System.String)">
            <summary>Tạo/sửa mẫu cá nhân — chủ luôn là <paramref name="userId"/>, bất kể client gửi gì</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuickReplyService.SaveSharedAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SaveChatQuickReplyModel,System.Int32,System.String)">
            <summary>Tạo/sửa mẫu dùng chung — endpoint gọi hàm này đã gác bằng role <c>ChatQuickReply.ManageShared</c></summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuickReplyService.DeletePersonalAsync(System.Int32,System.Int32,System.String)">
            <summary>Xoá mềm mẫu cá nhân của chính mình; tệp ảnh giữ nguyên</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuickReplyService.DeleteSharedAsync(System.Int32,System.Int32,System.String)">
            <summary>Xoá mềm mẫu dùng chung; tệp ảnh giữ nguyên</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuickReplyService.SendAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.SocialChat.SendQuickReplyModel,System.Int32,System.String)">
            <summary>
            Gửi một tin vào hội thoại, xuất phát từ một mẫu (<c>send-quick-reply</c>).
            </summary>
            <remarks>
            <para>
            Bên trong gọi <b>đúng</b> <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.SendMessageAsync(Ladaer.BackEnd.Infrastructures.Services.SocialChat.SendChatMessageParam,System.Int32,System.String)"/> — hàm mà <c>send</c> và
            <c>send-image</c> dùng, không đổi chữ ký hay hành vi của nó (nguyên tắc 1.1). Vì thế hàng rào phạm vi
            ghi của hội thoại, kiểm kênh còn gửi được, luật "chỉ tin văn bản mới trích dẫn được" và việc lưu tin
            trước khi gọi nền tảng đều là của đường gửi sẵn có; ở đây không chép lại luật nào trong số đó.
            </para>
            <para>
            Hàm này chỉ thêm hai điều: mẫu phải <b>thấy được</b> với người gửi và <b>đang bật</b>; và ảnh gửi đi là
            ảnh <b>của mẫu</b>, tra theo mã mẫu. Gửi thành công mới cộng lượt dùng.
            </para>
            <para>
            <b>Vì sao nằm ở đây, không nằm trong <c>ISocialChatService</c> như prompt GĐ A đề xuất</b> (plan §3.3):
            đặt vào lõi chat là thêm một phụ thuộc vào constructor 15 tham số mà sáu chỗ trong năm file test đang
            dựng tay, và kéo luật "mẫu nào thấy được" ra khỏi lớp giữ luật ấy. Đặt ở đây thì
            <c>SocialChatService.cs</c> không bị sửa dòng nào.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQuickReplyService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuickReplyService" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQuickReplyService.MaxTitleLength">
            <summary>Bề rộng cột <c>Title</c></summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQuickReplyService.MaxContentLength">
            <summary>Bề rộng cột <c>Content</c> — giới hạn một tin nhắn của Zalo</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQuickReplyService.MaxPageSize">
            <summary>Trần cỡ trang của bảng quản lý. Cỡ trang đến từ client.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQuickReplyService.ShortcutPattern">
            <summary>Phím tắt sau khi chuẩn hoá — khớp đúng lời gợi ý ở biểu mẫu: không dấu, không khoảng trắng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQuickReplyService.VisibleTo(System.Int32)">
            <summary>
            Hàng rào ĐỌC — nguồn duy nhất của "người này thấy được mẫu nào": mẫu dùng chung, và mẫu cá nhân của
            chính mình. Không tính trạng thái bật/tắt; mỗi đường gọi tự quyết định có cần lọc thêm hay không.
            </summary>
            <remarks>
            Người gọi không xác định (<c>userId</c> ≤ 0) không thấy gì cả, kể cả mẫu dùng chung — thiếu tham số
            phải dẫn tới thấy ÍT hơn, không bao giờ nhiều hơn.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQuickReplyService.WritableIn(Lada.Framework.Data.Enums.ChatQuickReplyScope,System.Int32)">
            <summary>
            Hàng rào GHI — bản ghi mà một endpoint của <paramref name="scope"/> chạm được: đúng phạm vi ấy, và với
            mẫu cá nhân thì đúng chủ. Endpoint cá nhân không bao giờ chạm bản ghi dùng chung và ngược lại (§3.2).
            </summary>
            <remarks>
            Vế <c>OwnerUserId == userId</c> là thứ duy nhất đứng giữa một sale và mẫu của người ngồi cạnh — mật
            thử (a) của GĐ A bỏ đúng vế này để chứng minh ca test IDOR đỏ.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQuickReplyService.NormalizeShortcut(System.String)">
            <summary>
            Chuẩn hoá rồi kiểm phím tắt. Trả <c>(null, null)</c> khi bỏ trống.
            </summary>
            <remarks>
            Chỉ làm hai phép mà người gõ coi là "cùng một phím tắt": bỏ dấu <c>/</c> gõ kèm và hạ chữ thường.
            Không sửa hộ gì thêm (bỏ dấu tiếng Việt, thay khoảng trắng) — sửa hộ là lưu một phím tắt người dùng
            không hề gõ, rồi họ gõ đúng chữ của mình mà không ra mẫu.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQuickReplyService.IsShortcutUniqueViolation(System.Exception)">
            <summary>
            Lỗi ghi có phải do một trong hai unique index phím tắt của migration M202609151000 không.
            </summary>
            <remarks>
            <para>
            Soi <b>tên index</b> trong thông điệp của cả chuỗi exception, không soi <b>kiểu</b>. Hai đường ghi của
            <c>Repository</c> ném hai hình dạng khác nhau: <c>InsertAsync</c> ném <c>new Exception(exception.ToString())</c>
            KHÔNG kèm inner — tên index chỉ còn trong chuỗi thông điệp; <c>UpdateAsync</c> bọc <c>DbUpdateException</c> vào
            inner — tên index nằm ở <c>SqlException</c> sâu hơn. Bản đầu của GĐ A lần theo kiểu <c>DbUpdateException</c>
            nên đường TẠO MỚI không bao giờ khớp và trả 500 (review GĐ A).
            </para>
            <para>
            Chỉ hai index này. Lỗi ghi khác phải nổi lên như một sự cố thật, không được dịch thành "phím tắt vừa bị trùng".
            Hai tên dưới đây phải khớp migration từng ký tự — đổi tên index là phải sửa ở đây.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuickReplyUsageRecorder">
            <summary>
            Ghi một lượt dùng mẫu tin nhắn nhanh — <b>một câu <c>UPDATE</c></b> chạm đúng hai cột
            <c>UseCount</c> và <c>LastUsedAt</c>.
            </summary>
            <remarks>
            <para>
            <b>Vì sao không <c>UpdateAsync(mẫu)</c>.</b> Lượt gửi nạp mẫu <b>trước</b> một vòng gọi mạng ra
            Zalo/Facebook, mà <c>UpdateAsync</c> gọi <c>DbSet.Update</c> nên ghi lại <b>cả dòng</b> theo ảnh chụp
            lúc nạp. Chủ mẫu sửa nội dung, hay người quản lý tắt một mẫu dùng chung, trong đúng khe ấy thì sửa đổi
            của họ bị đè mất không dấu vết. Nạp lại rồi mới ghi cũng không chữa được: <c>Repository.Query()</c> có
            theo dõi, và trong cùng một <c>DbContext</c> Scoped EF trả lại <b>chính thực thể cũ</b> — bài học đã
            ghi ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConversationWriter.ReleaseOverdueAsync(System.Int32,System.Int32,System.DateTimeOffset)"/>.
            </para>
            <para>
            Cộng tại database (<c>UseCount + 1</c>) còn giữ đúng số đếm khi hai người gửi cùng một mẫu dùng chung
            cùng lúc; đọc-rồi-ghi thì mất một lượt.
            </para>
            <para>
            Tách interface vì đúng lý do của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatConversationWriter"/>: <c>ExecuteUpdateAsync</c> là tính
            năng của trình dịch truy vấn EF Core, kho dữ liệu giả của bộ test không có.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuickReplyUsageRecorder.RecordUseAsync(System.Int32,System.DateTimeOffset)">
            <summary>Cộng một lượt dùng và đóng dấu thời điểm. Mẫu đã xoá mềm thì không đổi gì.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.EfChatQuickReplyUsageRecorder">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuickReplyUsageRecorder"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.EfChatQuickReplyUsageRecorder.RecordUseAsync(System.Int32,System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuoteResolver">
            <summary>
            Tra nội dung tin gốc của những tin trả lời trích dẫn.
            <para>
            Phải tra ở MÁY CHỦ chứ không để phía trình duyệt tự dò trong mẻ tin đã nạp: cả hai nền tảng
            chỉ gửi MÃ tin gốc, không gửi nội dung (§8 SC-27), mà khách rất hay trích một câu từ hôm
            trước — tin đó nằm ngoài 50 tin gần nhất. Dò ở trình duyệt thì trường hợp thường gặp nhất
            lại là trường hợp hỏng, và khối trích dẫn hiện ra rỗng.
            </para>
            <para>
            Dùng chung cho CẢ HAI đường ra DTO (REST và SignalR) vì đúng lý do của
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffDirectory"/>: thiếu ở một đường thì khối trích dẫn biến mất ngay khi
            tin nhận được một cập nhật giao nhận, do phía trình duyệt thay nguyên phần tử bằng bản mới.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuoteResolver.ResolveAsync(Lada.Framework.Data.Domains.SocialChat.ChatMessage)">
            <summary>
            Tra đoạn trích của một tin. Trả <c>null</c> khi tin này không phải tin trả lời trích dẫn.
            Tin gốc không còn trong database thì vẫn trả về một đoạn trích <b>rỗng nội dung</b> —
            giao diện cần biết "đây là câu trả lời cho một tin cũ" ngay cả khi không dựng lại được nó.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuoteResolver.ResolveManyAsync(System.Int32,System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.SocialChat.ChatMessage})">
            <summary>
            Tra đoạn trích cho cả một mẻ tin bằng MỘT lời gọi database.
            Trả về bảng tra theo <c>ChatMessage.Id</c>, chỉ chứa những tin có trích dẫn.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQuoteResolver">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatQuoteResolver"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQuoteResolver.PreviewLength">
            <summary>
            Độ dài tối đa của đoạn trích. Khối trích dẫn là gợi nhớ ngữ cảnh, không phải chỗ đọc
            lại cả tin — dài quá thì nó át chính câu trả lời nằm ngay dưới.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQuoteResolver.NotFound">
            <summary>Đoạn trích của một tin gốc không dựng lại được.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatScopeRevoker">
            <summary>
            Đưa các phòng realtime của một người về đúng phạm vi hiện tại của họ — gỡ phòng đã mất
            quyền, vào phòng vừa mở.
            <para>
            Đây là mặt thứ ba của hàng rào quyền xem, sau REST và sau luật chọn nhóm khi phát tin.
            Hai mặt kia chỉ đúng ở <b>thời điểm gọi</b>; một kết nối SignalR thì sống hàng giờ, và nó
            giữ nguyên danh sách nhóm từ lúc mở. Chuyển hội thoại cho người khác mà không thu hồi là
            người cũ vẫn nghe được nguyên văn tin của khách cho tới khi họ đóng tab (finding F-3).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatScopeRevoker.RevokeAsync(System.Int32)">
            <summary>Chấm lại phạm vi của một người và sửa các phòng của mọi kết nối họ đang mở</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatScopeRevoker.RevokeForStaffAsync(System.Int32)">
            <summary>
            Phạm vi <b>liên quan tới một nhân viên</b> vừa đổi: chấm lại cho chính họ <b>và cho mọi
            người nhìn thấy họ</b>.
            <para>
            Vì sao cần vế thứ hai: phạm vi của một hội thoại không chỉ gồm người đang giữ nó. Mức
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityLevel.Team"/> cho người quản lý xem hội thoại của cấp dưới, nên
            khi hội thoại bị chuyển khỏi cấp dưới thì <b>người quản lý</b> cũng vừa mất quyền — mà
            mã của họ không xuất hiện ở bất kỳ đầu nào của lượt phân công. Thu hồi đúng hai người
            trực tiếp là để lại nguyên một lỗ cùng hình dạng với finding F-3, chỉ khác nạn nhân.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatScopeRevoker.RevokeAllAsync">
            <summary>
            Chấm lại phạm vi của <b>mọi</b> người đang kết nối — dùng khi bật/tắt hàng rào của một
            kênh, vì thao tác đó đổi phạm vi của tất cả cùng lúc.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatScopeRevoker">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatScopeRevoker"/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaAction">
            <summary>Việc mà lượt quét phải làm với một hội thoại.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaAction.None">
            <summary>Không làm gì</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaAction.Remind">
            <summary>Nhắc người đang giữ</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaAction.Reclaim">
            <summary>Thu hồi khỏi người đang giữ rồi chia lại</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaInput">
            <summary>
            Ảnh chụp một hội thoại, đủ để chấm hạn phản hồi mà <b>không phải đọc bảng tin nhắn</b>.
            </summary>
            <remarks>
            Đây là lý do §3.2 đặt các mốc thời gian lên <c>ChatConversation</c> chứ không tính từ
            <c>ChatMessage</c>: bảng tin sẽ lên hàng chục nghìn dòng mỗi ngày ở quy mô đích, và một job
            chạy mỗi 2 phút không được phép quét nó.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaInput.AssignedStaffId">
            <summary>Người đang giữ. <c>null</c> = hội thoại nằm hàng chờ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaInput.AssignedAt">
            <summary>Lúc người hiện tại nhận hội thoại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaInput.WaitingSinceAt">
            <summary>
            Tin <b>mở đầu</b> lượt chờ hiện tại (<c>ChatConversation.WaitingSinceAt</c>).
            <c>null</c> = khách không đang chờ ai.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaInput.SlaRemindedAt">
            <summary>Lần gần nhất lượt quét đã nhắc về hội thoại này</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaInput.Mode">
            <summary>Chế độ phân phối của kênh chứa hội thoại</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext">
            <summary>
            Đủ dữ liệu để giao diện hiện được "khách đã chờ bao lâu" — bằng <b>đúng</b> phép đếm mà hai lượt
            quét dùng để quyết định nhắc, thu hồi, báo trưởng nhóm.
            </summary>
            <remarks>
            <para>
            Dựng <b>một lần cho cả một trang</b> từ chính các hội thoại của trang
            (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatWaitingContextProvider.GetAsync(System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.SocialChat.ChatConversation},System.DateTimeOffset)"/>) rồi truyền vào từng dòng: dựng cho từng dòng
            là N+1 truy vấn giờ làm và nhật ký trạng thái trên màn được mở nhiều nhất.
            </para>
            <para>
            <b>KC-18 — hai loại dòng, hai cách đếm</b> (plan §6 Phiên 4, thiết kế mục 4), trước đó là một cửa
            sổ giờ làm chung cho mọi dòng:
            </para>
            <list type="bullet">
            <item>Dòng <b>có người cầm</b>: phút trong giờ riêng của người cầm
            (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext.HolderWorkingHours"/>), so ngưỡng <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext.RemindMinutes"/> — cùng nghĩa với
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules.Decide(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaInput,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours,System.Int32,System.Int32)"/> trong lượt quét hạn phản hồi.</item>
            <item>Dòng <b>hàng chờ</b>: phút có ít nhất một ứng viên của kênh vào ca
            (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext.ChannelCoverage"/>), so ngưỡng <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext.QueueAlertMinutes"/> — cùng nghĩa với lượt
            quét hàng chờ.</item>
            </list>
            </remarks>
            <param name="RemindMinutes">Ngưỡng nhắc của hạn phản hồi (<c>Chat.Sla.RemindMinutes</c>)</param>
            <param name="QueueAlertMinutes">Ngưỡng báo trưởng nhóm (<c>Chat.Queue.AlertMinutes</c>)</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext.#ctor(System.Int32,System.Int32)">
            <summary>
            Đủ dữ liệu để giao diện hiện được "khách đã chờ bao lâu" — bằng <b>đúng</b> phép đếm mà hai lượt
            quét dùng để quyết định nhắc, thu hồi, báo trưởng nhóm.
            </summary>
            <remarks>
            <para>
            Dựng <b>một lần cho cả một trang</b> từ chính các hội thoại của trang
            (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatWaitingContextProvider.GetAsync(System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.SocialChat.ChatConversation},System.DateTimeOffset)"/>) rồi truyền vào từng dòng: dựng cho từng dòng
            là N+1 truy vấn giờ làm và nhật ký trạng thái trên màn được mở nhiều nhất.
            </para>
            <para>
            <b>KC-18 — hai loại dòng, hai cách đếm</b> (plan §6 Phiên 4, thiết kế mục 4), trước đó là một cửa
            sổ giờ làm chung cho mọi dòng:
            </para>
            <list type="bullet">
            <item>Dòng <b>có người cầm</b>: phút trong giờ riêng của người cầm
            (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext.HolderWorkingHours"/>), so ngưỡng <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext.RemindMinutes"/> — cùng nghĩa với
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules.Decide(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaInput,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours,System.Int32,System.Int32)"/> trong lượt quét hạn phản hồi.</item>
            <item>Dòng <b>hàng chờ</b>: phút có ít nhất một ứng viên của kênh vào ca
            (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext.ChannelCoverage"/>), so ngưỡng <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext.QueueAlertMinutes"/> — cùng nghĩa với lượt
            quét hàng chờ.</item>
            </list>
            </remarks>
            <param name="RemindMinutes">Ngưỡng nhắc của hạn phản hồi (<c>Chat.Sla.RemindMinutes</c>)</param>
            <param name="QueueAlertMinutes">Ngưỡng báo trưởng nhóm (<c>Chat.Queue.AlertMinutes</c>)</param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext.RemindMinutes">
            <summary>Ngưỡng nhắc của hạn phản hồi (<c>Chat.Sla.RemindMinutes</c>)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext.QueueAlertMinutes">
            <summary>Ngưỡng báo trưởng nhóm (<c>Chat.Queue.AlertMinutes</c>)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext.HolderWorkingHours">
            <summary>
            Giờ làm riêng của người đang cầm, theo <c>StaffId</c>. Người không có mặt ở đây được đếm bằng
            cửa sổ "luôn trong ca" — đúng cách lượt quét hạn phản hồi xử lý người giữ không tra được.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext.ChannelCoverage">
            <summary>
            Phủ sóng "có người vào ca" theo <c>ChatChannelId</c>, dựng tới "bây giờ" của trang. Kênh không có
            mặt ở đây thì dòng hàng chờ của nó <b>không nói gì</b> về việc chờ — cùng chiều với lượt quét
            hàng chờ, vốn không báo khi không biết ai đang vào ca.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContext.HoursOfHolder(System.Int32)">
            <summary>Giờ làm dùng để đếm cho người cầm <paramref name="staffId"/>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaDecision">
            <summary>Kết luận cho một hội thoại, kèm con số và câu giải thích để ghi log.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaDecision.WaitingWorkingMinutes">
            <summary>Số phút giờ làm khách đã chờ, tính từ <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaDecision.ClockStart"/></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaDecision.ClockStart">
            <summary>Mốc bắt đầu đếm; <c>null</c> khi hội thoại không trong diện chấm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaDecision.Reason">
            <summary>Vì sao ra kết luận này — đọc được bằng mắt người, dùng cho log</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaDecision.HolderOffShift">
            <summary>
            <c>true</c> khi hội thoại bị bỏ qua <b>chỉ vì</b> người đang giữ đang ngoài giờ làm của chính
            họ (KC-18) — khách vẫn đang chờ, chỉ là chưa tới lúc chấm.
            </summary>
            <remarks>
            Cờ riêng chứ không để lượt quét so chuỗi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaDecision.Reason"/>: câu chữ là để người đọc, sửa
            một chữ trong đó không được phép làm bộ đếm của log lặng lẽ về 0.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules">
            <summary>
            Luật hạn phản hồi của giai đoạn E — <b>hàm thuần</b>: không chạm database, không đọc đồng hồ,
            không gửi gì đi đâu.
            </summary>
            <remarks>
            <para>
            Tách khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService"/> đúng cách <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionRules"/> tách
            khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionEngine"/> ở giai đoạn D: nhờ thế kiểm được bằng bảng ca (ảnh
            chụp hội thoại + thời điểm → việc phải làm) mà không cần dựng kho dữ liệu giả, không cần bản
            giả thông báo, và không cần một hội thoại thật nào.
            </para>
            <para>
            Đây là đường <b>tự động đổi người phụ trách</b> — thứ mà §3.12 xếp vào nhóm phải qua workflow
            <c>review-giai-doan</c> cộng <c>/security-review</c>. Mọi điều kiện chặn nằm ở đây, ở một chỗ,
            chứ không rải thành <c>if</c> trong lớp chạm dữ liệu.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules.HolderOffShiftReason">
            <summary>
            Lý do ghi log khi người đang giữ đang ngoài giờ làm của chính họ (KC-18). Hằng công khai để
            bảng ca so đúng câu mà log in ra, không chép lại một bản.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules.WaitingSince(System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset},Lada.Framework.Data.Enums.ChatConversationStatus)">
            <summary>
            Từ lúc nào khách bắt đầu chờ được trả lời — hoặc <c>null</c> nếu họ <b>không</b> đang chờ.
            </summary>
            <remarks>
            <para>
            Tách thành hàm công khai riêng vì có <b>hai</b> chỗ cần đúng câu trả lời này: lượt quét (để
            chấm hạn) và giao diện (để hiện cột "chờ trả lời"). Viết hai bản là dựng hai định nghĩa của
            cùng một khái niệm, và cái lệch chỉ lộ ra khi một sale hỏi vì sao màn hình nói 5 phút mà hệ
            thống vừa thu hồi hội thoại của họ.
            </para>
            <para>
            Nguồn là <c>ChatConversation.WaitingSinceAt</c> — tin <b>MỞ ĐẦU</b> lượt chờ, không phải tin
            cuối cùng của khách. Đường nhận tin mở nó ở tin đến đầu tiên (<c>??=</c>) và đóng nó ở
            <b>mọi</b> tin đi ra, kể cả tin admin gõ thẳng trên ứng dụng Zalo OA / Facebook Page — 91,9 %
            tin chiều ra trên dữ liệu thật thuộc loại đó (số đo E0-5, nợ PP-13) và chúng không cập nhật
            <c>LastStaffReplyAt</c>, nên chấm bằng cột kia là thu hồi hội thoại của một người đã trả lời
            khách, chỉ vì họ trả lời ở cửa khác.
            </para>
            <para>
            <b>Vì sao không dùng <c>LastInboundAt</c>.</b> Cột ấy tiến lên mỗi lần khách nhắn thêm, nên
            đo bằng nó là biến việc khách <i>giục</i> thành việc <i>hoãn đồng hồ</i>: nhắn 09:00, 09:12,
            09:25, 09:38, 09:52 mà không ai trả lời thì không lượt quét nào chấm quá 13 phút. Và nó làm
            hai định nghĩa trôi khỏi nhau — ngưỡng 15/45 suy từ Đ5 theo cách đo (c), nguyên văn "chỉ tin
            <b>mở đầu</b> một lượt chờ".
            </para>
            <para>
            Mốc là cái <b>muộn hơn</b> giữa lúc lượt chờ mở và lúc người hiện tại nhận việc: người vừa
            được giao một hội thoại đã chờ 40 phút không chịu trách nhiệm cho quãng chờ của người trước.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules.Decide(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaInput,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours,System.Int32,System.Int32)">
            <summary>
            Chấm một hội thoại: có phải nhắc, phải thu hồi, hay không làm gì.
            </summary>
            <remarks>
            <para>Thứ tự các cửa, cửa trước thắng:</para>
            <list type="number">
            <item>Kênh không ở chế độ tự phân phối ⇒ bỏ qua.</item>
            <item>Chưa ai giữ ⇒ bỏ qua (hàng chờ có lượt quét riêng).</item>
            <item>Khách không đang chờ (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules.WaitingSince(System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset},Lada.Framework.Data.Enums.ChatConversationStatus)"/> trả <c>null</c>) ⇒ bỏ qua.</item>
            <item><b>Người đang giữ ngoài giờ làm của chính họ</b> tại <paramref name="now"/> ⇒ bỏ qua,
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaDecision.HolderOffShift"/> = <c>true</c> (KC-18).</item>
            <item>So số phút giờ làm với hai ngưỡng — thu hồi trước, nhắc sau.</item>
            </list>
            <para>
            <b>Cửa thứ tư (KC-18, §8.7 câu 1b).</b> Trước KC-18 lượt quét có một cổng toàn cục: ngoài
            giờ làm <i>chung</i> thì dừng hẳn cả lượt. Nay mỗi người một giờ làm, nên "ngoài giờ" là
            chuyện của từng hội thoại chứ không của cả lượt — cổng chuyển vào đây, theo người đang giữ.
            Nó giữ đúng điều kiện nghiệm thu cũ "không thông báo nào gửi ngoài giờ làm", nay đọc là
            "ngoài giờ làm của người nhận". Không có nó thì một hội thoại chạm ngưỡng lúc 16:59 của
            người làm tới 17:00 sẽ bị lượt quét 17:01 nhắc — phép đếm phút đã dừng đúng, nhưng thông
            báo vẫn đi ra ngoài giờ; tệ hơn là lượt quét chết một giờ rồi sống lại lúc người đó đã về.
            </para>
            <para>
            Cửa này đứng <b>sau</b> phép đếm phút (dù đứng trước phép so ngưỡng) để kết luận bỏ qua vẫn
            mang đúng số phút và mốc bắt đầu — cùng con số mà cột "chờ bao lâu" của giao diện hiện cho
            cùng hội thoại. Phép đếm là hàm thuần, không tốn gì thêm.
            </para>
            <para>
            Người <b>chưa đặt</b> giờ riêng nhận cửa sổ <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.AlwaysOpen"/> từ
            lớp gọi: luôn trong ca, đếm phút đồng hồ thật — hàm này không phân biệt, nó chỉ hỏi cửa sổ.
            </para>
            </remarks>
            <param name="input">Ảnh chụp hội thoại</param>
            <param name="now">Thời điểm quét</param>
            <param name="workingHours">
            Cửa sổ giờ làm của <b>người đang giữ</b> hội thoại này (KC-18) — không phải cấu hình chung.
            Lớp gọi nạp hàng loạt qua <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffWorkingHoursProvider"/>.
            </param>
            <param name="remindMinutes">Ngưỡng nhắc, tính bằng phút giờ làm</param>
            <param name="reclaimMinutes">Ngưỡng thu hồi, tính bằng phút giờ làm</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules.IsHolderOnShift(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours,System.DateTimeOffset)">
            <summary>
            Người đang giữ có đang trong ca <b>của chính họ</b> tại <paramref name="now"/> không — cửa thứ
            tư của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules.Decide(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaInput,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours,System.Int32,System.Int32)"/>, tách thành hàm công khai để có <b>đúng một</b> định nghĩa cho hai
            chỗ dùng.
            </summary>
            <remarks>
            Chỗ dùng thứ hai là <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService"/>: nó phải gạt hội thoại của người đang
            ngoài ca ra <b>trước</b> khi cắt mẻ <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService.SweepLimit"/>. Để phép gạt
            ấy cho <c>Decide</c> lo (cắt mẻ trước, chấm sau) thì các hội thoại cũ nhất của người đã hết ca
            — không bị nhắc, không bị thu hồi, nên không bao giờ rời mẻ — chiếm trọn mẻ suốt đêm, và hội
            thoại của người đang trong ca đứng sau chúng không bao giờ được chấm. Lượt quét hỏi đúng hàm
            này nên hai chỗ không thể trả lời khác nhau cho cùng một người ở cùng một mốc.
            </remarks>
            <param name="holderHours">Cửa sổ giờ làm của người đang giữ (chưa đặt = luôn trong ca)</param>
            <param name="now">Thời điểm quét</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaConfigKeys">
            <summary>
            Tên khoá <c>AppConfig</c> của hạn phản hồi (giai đoạn E) — seed bằng migration, không hardcode
            giá trị ở nơi khác.
            <para>
            Theo đúng khuôn <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionConfigKeys"/> của giai đoạn D: hằng tên khoá ở một
            chỗ, một lớp duy nhất diễn giải chuỗi, <c>InvariantCulture</c>, giá trị hỏng rơi về phía an
            toàn thay vì ném lỗi giữa một lượt quét.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaConfigKeys.Enabled">
            <summary>
            Công tắc của cả giai đoạn E. <c>true</c> / <c>false</c>. Mặc định <b>TẮT</b>.
            </summary>
            <remarks>
            <para>
            Khoá này tồn tại vì một lý do rất cụ thể, ghi ở §4 Bản đồ phiên: cổng D2 đo <i>máy phân
            phối chia có đều không</i>. Nếu hạn phản hồi đồng thời thu hồi và chia lại thì bảng đối
            chiếu trộn hai hiệu ứng — một người "nhận nhiều" có thể là vì thuật toán chia lệch, mà cũng
            có thể vì họ liên tục nhận lại việc người khác bị thu hồi. Không tách được hai thứ đó ra
            khỏi cùng một con số.
            </para>
            <para>
            Nên trong trình tự lên production, bật khoá này là <b>bước sau</b> bước tắt
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatDistributionConfigKeys.DryRun"/>, không phải cùng lúc.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaConfigKeys.RemindMinutes">
            <summary>Quá bấy nhiêu phút <b>giờ làm</b> chưa trả lời thì nhắc người đang giữ</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaConfigKeys.ReclaimMinutes">
            <summary>Quá bấy nhiêu phút <b>giờ làm</b> chưa trả lời thì thu hồi và chia lại</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatSlaSettings">
            <summary>
            Đọc và diễn giải các khoá cấu hình của hạn phản hồi.
            </summary>
            <remarks>
            Tách riêng khỏi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionSettings"/> theo đúng lý do đã viết ở đó: hai nhóm
            khoá hai vòng đời. Ngưỡng hạn phản hồi là thứ §2.4 đã hẹn <b>đo lại sau 2 tuần chạy thật</b>,
            còn <c>DryRun</c> thì tắt một lần rồi thôi.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatSlaSettings.IsEnabledAsync">
            <summary>
            Hạn phản hồi có đang bật không. <b>Mặc định <c>false</c></b>: khoá đọc không ra thì coi như
            chưa bật.
            </summary>
            <remarks>
            Cùng khuôn rơi-về-phía-an-toàn của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatDistributionSettings.IsDryRunAsync"/>,
            nhưng chiều ngược lại vì hai cờ mang nghĩa ngược nhau: ở đó "hỏng thì cứ thử chạy", ở đây
            "hỏng thì đừng tự thu hồi của ai". Hai hướng hỏng không cân nhau — không bật thì tệ nhất là
            khách chờ lâu như hôm nay, còn bật nhầm là máy tự lấy hội thoại khỏi tay người đang làm.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatSlaSettings.GetRemindMinutesAsync">
            <summary>Ngưỡng nhắc lần 1, tính bằng phút giờ làm (mặc định 15)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatSlaSettings.GetReclaimMinutesAsync">
            <summary>Ngưỡng thu hồi, tính bằng phút giờ làm (mặc định 45)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSettings">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatSlaSettings"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSettings.DefaultEnabled">
            <summary>
            Bật hay tắt khi khoá đọc không ra. Xem <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatSlaSettings.IsEnabledAsync"/> để
            biết vì sao chiều này.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSettings.DefaultRemindMinutes">
            <summary>
            Nhắc lần 1. <b>15 phút lấy từ số đo Đ5</b> (§2.4, N = 206, cách đo (c) — chỉ tin mở đầu một
            lượt chờ, chỉ trong giờ làm): nằm giữa p75 (4,3′) và p90 (35,4′), tức nhắc khoảng 10–15 %
            lượt chậm nhất, không nhắc oan phần lớn.
            <para>
            Không phải hằng số vĩnh viễn: Đ5 chỉ có 3 ngày dữ liệu và phần lớn phát sinh trong lúc đội
            đang bấm thử, tức nhanh hơn vận hành thật. §2.4 đã hẹn <b>đo lại sau 2 tuần chạy thật</b> —
            đó là lý do con số này nằm trong <c>AppConfig</c> chứ không nằm trong code.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSettings.DefaultReclaimMinutes">
            <summary>
            Thu hồi. <b>45 phút lấy từ số đo Đ5</b>: trên p90 (35,4′), dưới p95 (156,4′). Cùng cảnh báo
            về độ tin cậy như <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSettings.DefaultRemindMinutes"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSettings.IsEnabledAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSettings.GetRemindMinutesAsync">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSettings.GetReclaimMinutesAsync">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatWaitingContextProvider">
            <summary>
            Dựng bối cảnh "khách đã chờ bao lâu" cho <b>một trang</b> hội thoại, thành <b>một</b> phụ thuộc.
            </summary>
            <remarks>
            <para>
            Tồn tại vì một lý do rất cụ thể, nói ra để người sau không tưởng đây là một tầng trừu tượng vô
            cớ: <c>SocialChatService</c> cần hai ngưỡng cộng cách đếm phút chờ, tức nhiều interface cấu hình
            và nạp dữ liệu. Nhét cả vào hàm dựng của một service vốn đã có 14 tham số là làm nặng thêm đúng
            chỗ đã nặng, trong khi chúng luôn đi cùng nhau và luôn được đọc cùng một lúc.
            </para>
            <para>
            <b>KC-18:</b> cách đếm nay phụ thuộc <b>chính các dòng</b> của trang — giờ riêng của người đang
            cầm, và ứng viên của kênh chứa hội thoại hàng chờ — nên hàm nhận danh sách hội thoại thay vì không
            nhận gì. Đọc một lần cho cả trang, không đọc lại cho từng dòng.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatWaitingContextProvider.GetAsync(System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.SocialChat.ChatConversation},System.DateTimeOffset)">
            <summary>
            Dựng bối cảnh cho đúng các hội thoại sắp được hiện — số truy vấn không phụ thuộc số dòng.
            </summary>
            <param name="conversations">Các hội thoại của trang (hoặc một hội thoại, ở màn chi tiết và bản đẩy realtime)</param>
            <param name="now">
            "Bây giờ" — <b>phải là đúng giá trị</b> người gọi truyền tiếp cho <c>ChatDtoMapper.ToItem</c>:
            phủ sóng hàng chờ dựng tới mốc này và không đếm được quá nó.
            </param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContextProvider">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatWaitingContextProvider"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWaitingContextProvider.GetAsync(System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.SocialChat.ChatConversation},System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepResult">
            <summary>Kết quả một lượt quét hạn phản hồi — dùng cho log và cho test.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepResult.Enabled">
            <summary>Công tắc <c>Chat.Sla.Enabled</c> có đang bật không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepResult.ExaminedCount">
            <summary>
            Số hội thoại đã chấm ở lượt này — chỉ gồm hội thoại của người đang <b>trong</b> ca, tối
            đa <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService.SweepLimit"/>. Hội thoại của người ngoài ca không vào
            mẻ chấm, chúng nằm ở <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepResult.SkippedOffShiftCount"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepResult.SkippedOffShiftCount">
            <summary>
            Số hội thoại khách đang chờ nhưng bị bỏ qua vì người đang giữ đang ngoài giờ làm <b>của
            chính họ</b> (KC-18) — không nhắc, không thu hồi. Đếm trên <b>cả diện chấm</b>, không bị
            trần <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService.SweepLimit"/> cắt, và <b>không</b> nằm trong
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepResult.ExaminedCount"/>.
            </summary>
            <remarks>
            <para>
            Thay cho cờ <c>WithinWorkingHours</c> cũ. Cờ ấy trả lời "lượt quét có rơi vào giờ làm
            chung không" — câu hỏi hết nghĩa khi mỗi người một giờ làm: cùng một lượt, người này
            trong ca còn người kia đã về. Giữ lại cờ là để log in "trong giờ làm" cho một lượt vừa
            bỏ qua nửa số hội thoại vì người giữ đã hết ca. Con số này mới là thứ người vận hành cần
            khi hỏi "sao khách chờ 2 tiếng mà không ai bị nhắc".
            </para>
            <para>
            Không còn là "trong số đã chấm": từ bản vá sau review, hội thoại của người ngoài ca bị gạt
            khỏi mẻ <b>trước</b> khi cắt trần (xem <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules.IsHolderOnShift(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours,System.DateTimeOffset)"/>), nên
            chúng không được chấm từng cái — con số đến từ một câu đếm riêng.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepResult.RemindedCount">
            <summary>Số hội thoại vừa nhắc người đang giữ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepResult.ReclaimedCount">
            <summary>Số hội thoại vừa thu hồi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepResult.RedistributedCount">
            <summary>Trong số vừa thu hồi, bao nhiêu hội thoại tìm được người mới ngay</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepResult.PresenceExpiry">
            <summary>Kết quả dọn trạng thái hết hạn chạy kèm (PP-26, PP-27)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatSlaSweepService">
            <summary>
            Quét hạn phản hồi: nhắc người đang giữ khi khách chờ quá lâu, rồi thu hồi và chia lại khi
            chờ lâu hơn nữa (giai đoạn E).
            </summary>
            <remarks>
            <para>
            Giai đoạn D dựng máy tự chia khách, nhưng <b>chia xong rồi thì không ai canh nữa</b> — một
            hội thoại giao cho người đang bận rồi để đó ba tiếng thì hệ thống hoàn toàn im lặng. Lượt
            quét này là cái đồng hồ đếm ngược cho mỗi hội thoại đã chia.
            </para>
            <para>
            <b>Chỉ đếm trong giờ làm việc — của người đang giữ.</b> Xem
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.WorkingMinutesBetween(System.DateTimeOffset,System.DateTimeOffset)"/>: hạn phản hồi không phải hiệu số hai
            mốc thời gian, nó là số phút giờ làm đã trôi qua. Từ KC-18 (§8.7 câu 1b) đó là giờ làm
            <b>riêng</b> của người đang giữ hội thoại; người chưa đặt thì luôn trong ca, đếm phút đồng
            hồ thật. Cấu hình chung <c>Chat.WorkingHours.*</c> không còn chạm tới lượt quét này.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatSlaSweepService.SweepAsync(System.DateTimeOffset)">
            <summary>Chạy một lượt quét.</summary>
            <param name="now">Mốc quét — tham số để test được mà không phụ thuộc đồng hồ máy</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatSlaSweepService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService.SweepLimit">
            <summary>
            Trần số hội thoại chấm trong một lượt quét.
            </summary>
            <remarks>
            <para>
            Cùng lý lẽ với <c>ChatQueueSweepService.TranMoiLuot</c>: job chạy mỗi 2 phút, một lượt
            ôm cả nghìn hội thoại là một lượt chồng lên lượt sau. Xếp theo tin của khách cũ nhất nên
            người chờ lâu nhất luôn nằm trong mẻ đầu. <b>Cắt bao nhiêu thì log ra bấy nhiêu</b> —
            một phép cắt im lặng đọc thành "đã chấm hết".
            </para>
            <para>
            <b>Trần chỉ áp lên hội thoại của người đang TRONG ca</b> (KC-18, bản vá sau review). "Phần
            dư sang lượt sau" chỉ đúng khi mọi dòng đầu mẻ rồi cũng rời mẻ — bị nhắc rồi thu hồi. Dòng
            của người đã hết ca riêng thì không: không nhắc, không thu hồi, nằm yên cả đêm, cả Chủ
            Nhật. Cắt mẻ trước rồi mới bỏ qua chúng là để 500 hội thoại cũ nhất của ca ngày chiếm
            trọn mẻ mỗi lượt, và hội thoại của người trực tối không bao giờ được chấm.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService.LookbackDays">
            <summary>
            Chỉ nhìn lại bấy nhiêu ngày (đồng hồ thường) kể từ tin gần nhất của khách.
            </summary>
            <remarks>
            <para>
            Cửa sổ này là thứ giữ cho <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService.SweepLimit"/> không bị lấp đầy bởi hội thoại cũ đã
            trả lời từ lâu. Nó <b>rộng hơn</b> luật ở <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules"/> chứ không lặp lại
            luật ấy: phép chấm "khách còn đang chờ hay không" nằm ở <b>đúng một chỗ</b>, trong hàm
            thuần. Chép nó xuống câu truy vấn là dựng hai bản của cùng một hàng rào, và lúc ấy gỡ
            bản nào đi cũng không có ca test nào đỏ — đúng họ lỗi số 2 mà đợt mật thử giai đoạn D
            bắt được bốn lần.
            </para>
            <para>
            Đánh đổi đã biết: một hội thoại mà khách nhắn hơn 30 ngày trước và <i>chưa ai trả lời</i>
            sẽ rơi ra khỏi diện chấm. Nó đã bị thu hồi ít nhất một lần trước đó (mỗi lần cách nhau
            45 phút giờ làm), nên cái còn lại không phải việc của một job — mà là việc của người.
            </para>
            <para>
            Nếu log cắt trần bắt đầu kêu ở production thì cách chữa là một filtered index trên
            <c>(AssignedStaffId, Status, LastInboundAt)</c> rồi đẩy vế "còn đang chờ" xuống SQL —
            và lúc ấy phải kèm một ca <c>*SqlTests</c> đối chiếu câu truy vấn với hàm thuần, chứ
            không chép ngầm.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService.SweepAsync(System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService.HoursOfHolder(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.Collections.Generic.IReadOnlyDictionary{System.Int32,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours})">
            <summary>
            Cửa sổ giờ làm của người đang giữ hội thoại, tra trong từ điển đã nạp cho cả mẻ.
            </summary>
            <remarks>
            Từ điển có đủ mọi mã hợp lệ đã hỏi (hợp đồng của
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffWorkingHoursProvider.GetManyAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32})"/>), và nó được nạp cho <b>cả diện
            chấm</b> trước khi cắt mẻ (người giữ vừa đổi tay thì được nạp bù), nên nhánh dự phòng chỉ
            gặp khi chưa ai giữ — lúc ấy <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules.Decide(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaInput,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours,System.Int32,System.Int32)"/> đã bỏ qua trước khi hỏi cửa
            sổ — hoặc khi mã giữ <c>&lt;= 0</c>. Dự phòng là "luôn trong ca" cho cùng nghĩa với người
            chưa đặt, <b>không</b> phải cấu hình chung: cấu hình chung từ KC-18 chỉ còn là giờ gợi ý
            (§8.7 câu 5).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService.BuildInput(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Lada.Framework.Data.Enums.ChatAssignmentMode)">
            <summary>Dựng ảnh chụp hội thoại cho hàm thuần.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService.SweepPresenceExpiryAsync(System.DateTimeOffset)">
            <summary>
            Bọc lượt dọn trạng thái hết hạn: nó là việc trả nợ, không phải việc chính, nên một lỗi
            ở đó không được làm cả lượt quét hạn phản hồi không chạy.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService.RemindHolderAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaDecision,System.DateTimeOffset)">
            <summary>
            Nhắc <b>chính người đang giữ</b>. Trả <c>true</c> nếu vừa gửi.
            </summary>
            <remarks>
            Không gửi cho trưởng nhóm ở bậc này, và đó là một quyết định chứ không phải một chỗ
            quên: trưởng nhóm không phải người phải trả lời khách. Báo họ ngay từ phút thứ 15 là
            biến một lời nhắc thành một lời mách, và sau vài ngày họ sẽ tắt nhóm thông báo này.
            Trưởng nhóm chỉ nghe ở bậc thu hồi — lúc đã có việc cần họ xử lý.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService.ReclaimOutcome">
            <summary>Kết quả một lượt thu hồi — hai vế tách rời vì chúng hỏng độc lập nhau.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService.ReclaimOutcome.#ctor(System.Boolean,System.Boolean)">
            <summary>Kết quả một lượt thu hồi — hai vế tách rời vì chúng hỏng độc lập nhau.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService.ReclaimAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaDecision,System.DateTimeOffset)">
            <summary>
            Thu hồi hội thoại khỏi người đang giữ rồi chia lại.
            </summary>
            <remarks>
            <para>
            Đi qua <b>sổ phân công</b> và <b>máy phân phối</b> sẵn có, không viết đường thứ hai:
            hai bản chọn người là hai bản sẽ lệch nhau. Quãng nghỉ
            <c>ChatCandidateExclusion.ReleaseCooldown</c> đã lo sẵn việc "vừa thu hồi của ai thì
            đừng giao lại ngay cho chính họ" — nó tính theo <b>mọi</b> lý do nhả, kể cả
            <see cref="F:Lada.Framework.Data.Enums.ChatReleaseReason.QuaHanPhanHoi"/>.
            </para>
            <para>
            Chia lại không tìm được ai thì hội thoại <b>ở lại hàng chờ</b>, và lượt quét hàng chờ
            tiếp quản. Trả nó về đúng người vừa bị thu hồi là biến cả việc thu hồi thành một câu
            lệnh không có tác dụng gì.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaSweepService.NotifyReclaimAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.Int32,System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaDecision)">
            <summary>
            Báo trưởng nhóm của kênh <b>và</b> chính người vừa bị thu hồi.
            </summary>
            <remarks>
            Người vừa bị thu hồi nằm trong danh sách nhận có chủ ý, dù §4 chỉ nói "thu hồi mới báo
            trưởng nhóm": hội thoại biến khỏi danh sách của họ trong im lặng là cách chắc chắn nhất
            để họ tưởng hệ thống hỏng, và tệ hơn — họ vẫn đang soạn câu trả lời cho một khách không
            còn là của mình.
            <para>
            Gửi bằng <c>SendToUsersAsync</c> với người nhận tự tra, <b>không</b> bằng
            <c>SendToRoleAsync</c>: bản theo role gửi toàn hệ thống, không lọc kênh cũng không lọc
            chi nhánh.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffDirectory">
            <summary>
            Tra tên nhân viên theo mã, phục vụ trường "đang phân công" trên khung chat.
            <para>
            Phải là một dịch vụ riêng chứ không phải một <c>Include</c>: cột
            <c>ChatConversation.AssignedStaffId</c> cố ý KHÔNG có khoá ngoại sang bảng người dùng
            (xem migration <c>M202608261600</c>), nên không có navigation nào để nạp kèm. Thêm khoá
            ngoại chỉ để lấy một cái tên là sửa lược đồ của bảng nghiệp vụ — trái với nguyên tắc số 1
            của đợt này.
            </para>
            <para>
            Dùng chung cho CẢ HAI đường ra DTO (REST và SignalR). Đây là bài học đắt nhất của giai
            đoạn C: một trường thiếu ở một đường ghi làm cả tính năng hỏng im lặng, và vì phía trình
            duyệt thay nguyên dòng trong danh sách bằng bản vừa nhận nên tên sẽ biến mất khỏi màn hình
            ngay khi có tin mới.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffDirectory.GetNamesAsync(System.Collections.Generic.IEnumerable{System.Nullable{System.Int32}})">
            <summary>
            Tên hiển thị của một loạt nhân viên. Mã không tra được (tài khoản đã xoá) thì
            không có mặt trong kết quả — người gọi tự lùi về chuỗi rỗng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffDirectory.GetNameAsync(System.Nullable{System.Int32})">
            <summary>Tên hiển thị của một nhân viên, chuỗi rỗng khi không tra được hoặc chưa phân công</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffDirectory.SuggestAsync(System.String,System.Nullable{System.Int32},System.Nullable{System.Int32},System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>
            Danh sách nhân viên có thể nhận phân công hội thoại, lọc theo từ khoá.
            <para>
            Chỉ lấy tài khoản kiểu nhân viên và chưa bị khoá — phân công cho một tài khoản đã khoá
            là để việc rơi vào chỗ không ai nhìn.
            </para>
            <para>
            <b>Người gọi PHẢI truyền phạm vi</b> đúng theo <c>DataAccessScope</c> của tài khoản
            đang đăng nhập, y như <c>UserController.SugStaff</c> làm. Mặc định của phạm vi ấy là
            <c>SelfOnly</c>, nên gọi hàm này không kèm ràng buộc là biến một tài khoản chỉ được
            thấy chính mình thành một tài khoản đọc được danh bạ nhân sự của cả công ty.
            </para>
            </summary>
            <param name="keyword">Từ khoá theo tên hoặc tên đăng nhập</param>
            <param name="managerId">Chỉ lấy nhân viên do người này quản lý trực tiếp</param>
            <param name="selfUserId">Chỉ lấy đúng tài khoản này</param>
            <param name="restrictToStaffIds">
            Danh sách phụ trách của kênh, khi kênh đó đã bật hàng rào. Truyền vào ĐÂY chứ đừng lọc
            kết quả trả về: hàm này cắt ở <c>SuggestLimit</c> dòng, nên lọc sau là lọc trên một lát
            cắt bảng chữ cái chứ không phải trên tập nhân viên của kênh.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffDirectory.IsAssignableAsync(System.Int32,System.Nullable{System.Int32},System.Nullable{System.Int32},System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>
            Một mã nhân viên có nằm trong tập mà <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffDirectory.SuggestAsync(System.String,System.Nullable{System.Int32},System.Nullable{System.Int32},System.Collections.Generic.IReadOnlyCollection{System.Int32})"/> sẽ trả về với cùng ràng
            buộc không — tức là tài khoản nhân viên, chưa khoá, và trong phạm vi.
            <para>
            Dùng để đối chiếu mã gửi lên ở endpoint phân công bằng CHÍNH luật của đường gợi ý,
            giống <c>link-customer</c> đối chiếu lại qua <c>ICustomerService.Suggest</c>. Không có
            bước này, phân công nhận mã tuỳ ý là một máy tra tên/tên đăng nhập theo mã cho toàn bộ
            bảng người dùng, kể cả tài khoản khách hàng (finding security review GĐ F, luật §6.10).
            </para>
            </summary>
            <param name="restrictToStaffIds">
            Danh sách được phép chọn — cùng tham số, cùng nghĩa với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffDirectory.SuggestAsync(System.String,System.Nullable{System.Int32},System.Nullable{System.Int32},System.Collections.Generic.IReadOnlyCollection{System.Int32})"/>.
            Cần cho nhánh <c>SelfOnly</c> của đường phân công/chuyển: ở đó "phạm vi" KHÔNG phải một
            mức <c>DataAccessScope</c> mà là danh sách phụ trách của một kênh (sổ nợ PP-38). Danh
            sách rỗng → không ai khớp → <c>false</c>, fail-closed.
            </param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffDirectory">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffDirectory"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffDirectory.CacheKeyPrefix">
            <summary>
            Tiền tố khoá bộ nhớ đệm. Tên nhân viên gần như không đổi, mà đường đẩy realtime thì
            chạy trên luồng xử lý webhook — nơi Zalo chỉ cho 2 giây để trả lời.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffDirectory.CacheDuration">
            <summary>Thời gian sống của một mục đệm. Đổi tên nhân viên thì chậm nhất 10 phút là hiện đúng.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffDirectory.SuggestLimit">
            <summary>Số nhân viên tối đa một lần gợi ý trả về — ô chọn, không phải danh sách nhân sự</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffDirectory.AssignableStaff(System.Nullable{System.Int32},System.Nullable{System.Int32},System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>
            Tập nhân viên nhận phân công được: tài khoản kiểu nhân viên, chưa khoá, trong phạm vi.
            Cả gợi ý lẫn đối chiếu mã đều đi qua đúng truy vấn này.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffWorkingHoursProvider">
            <summary>
            Nguồn <b>duy nhất</b> nạp giờ làm riêng của sale (KC-18) — hàng loạt, <b>một truy vấn cho cả
            lô</b>.
            <para>
            Bốn nơi cần giờ riêng của nhiều người cùng lúc: lượt quét hạn phản hồi (người đang cầm của mọi
            hội thoại), lượt quét hàng chờ và cột "chờ bao lâu" (ứng viên của kênh), job chấm tiêu chí 5
            (mọi sale). Mỗi nơi tự nạp và tự dựng là mỗi nơi một định nghĩa "chưa đặt" và "hỏng" — bài học
            phân hệ KPI; và nạp theo từng người trong vòng lặp là N+1 trên job chạy mỗi 2 phút.
            </para>
            <para>
            Luật dựng nằm ở hàm thuần <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.ForStaff(Lada.Framework.Data.Domains.SocialChat.ChatAgentPresence,System.TimeSpan)"/>;
            lớp này chỉ đi lấy dữ liệu, lấy múi giờ từ cấu hình chung và <b>ghi log cảnh báo</b> cho dòng
            hỏng (hàm thuần không log được).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffWorkingHoursProvider.GetManyAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <summary>
            Giờ làm riêng của một loạt người: một lần đọc cấu hình (múi giờ) + <b>một</b> truy vấn
            <c>ChatAgentPresence</c>.
            </summary>
            <returns>
            Từ điển đủ <b>mọi</b> mã hợp lệ được hỏi (mã <c>&lt;= 0</c> bị bỏ). Người không có dòng
            mang <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursState.NotSet"/> — người gọi không phải xử lý khoá
            thiếu, và phân biệt "chưa đặt" bằng <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours.HasOwnWorkingHours"/>.
            </returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffWorkingHoursProvider.GetAsync(System.Int32)">
            <summary>Giờ làm riêng của một người — bản một-người của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffWorkingHoursProvider.GetManyAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32})"/>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffWorkingHoursProvider.FromPresences(System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Collections.Generic.IReadOnlyDictionary{System.Int32,Lada.Framework.Data.Domains.SocialChat.ChatAgentPresence},System.TimeSpan)">
            <summary>
            Dựng giờ riêng từ các dòng <c>ChatAgentPresence</c> <b>người gọi đã nạp sẵn</b> — không
            truy vấn gì. Dành cho nơi đã có dòng trong tay (máy chia nạp cả lô ở
            <c>ChatAgentAvailabilityResolver</c>) để không phải đọc lại bảng, mà vẫn đi đúng một
            đường dựng và một đường log.
            </summary>
            <param name="staffIds">Các mã cần kết quả; mã không có trong <paramref name="presences"/> là "chưa đặt"</param>
            <param name="presences">Dòng đã nạp, khoá theo <c>StaffId</c></param>
            <param name="offset">Múi giờ cấu hình — người gọi thường đã có nó từ <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatPresenceSettings.GetWorkingHoursAsync"/></param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursProvider">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatStaffWorkingHoursProvider"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursProvider.GetManyAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32})">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursProvider.GetAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursProvider.FromPresences(System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Collections.Generic.IReadOnlyDictionary{System.Int32,Lada.Framework.Data.Domains.SocialChat.ChatAgentPresence},System.TimeSpan)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursProvider.LogIfInvalid(System.Int32,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours)">
            <summary>
            Dòng hỏng vẫn được dùng như "luôn trong ca" (fail-open), nhưng phải để lại dấu vết: không
            log thì một người lặng lẽ nhận khách cả đêm mà không ai biết giờ làm họ đặt đã mất tác dụng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursProvider.ScheduleRow">
            <summary>Các cột giờ của một dòng <c>ChatAgentPresence</c> — chiếu thẳng từ truy vấn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursProvider.ScheduleRow.#ctor(System.Int32,System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.String)">
            <summary>Các cột giờ của một dòng <c>ChatAgentPresence</c> — chiếu thẳng từ truy vấn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatTransferScopeRules">
            <summary>
            Phạm vi chọn người nhận của mức <c>DataAccessScope.SelfOnly</c> — "cùng danh sách phụ trách
            kênh của chính hội thoại đang mở" (sổ nợ PP-38, kế hoạch §6.6, chốt 2026-08-30).
            </summary>
            <remarks>
            <para>
            <b>Hàm thuần</b>, tách khỏi controller vì đây là một quyết định PHÂN QUYỀN và repo này chưa
            từng có ca test nào dựng <c>SocialChatController</c>: <c>User.GetCurrentUser()</c> bắt mọi
            ngoại lệ rồi trả <c>UserId = 0</c>, nên một ca test controller dựng thiếu claim sẽ XANH vì
            lý do sai (rơi vào nhánh <c>staffId &lt;= 0</c>) thay vì đỏ. Cùng lý do
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatRealtimeAudience"/> và <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatSlaRules"/> là hàm thuần.
            </para>
            <para>
            Luật cố ý <b>hai chiều</b>. Xem XML-doc của
            <c>SocialChatController.IsStaffInMyScopeAsync</c> để biết vì sao vế "người chuyển cũng phải
            ở trong danh sách" không phải trang trí.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatTransferScopeRules.CungDanhSachPhuTrach(System.Collections.Generic.IReadOnlyCollection{System.Int32},System.Int32,System.Int32)">
            <summary>
            Hai người có cùng nằm trong một danh sách phụ trách kênh không.
            </summary>
            <param name="danhSachPhuTrach">
            Danh sách phụ trách <b>đang hoạt động</b> của kênh chứa hội thoại — luôn là kết quả của
            <c>IChatChannelStaffService.GetChannelPeerIdsOfConversationAsync</c>. Rỗng nghĩa là
            không tra được kênh hoặc kênh chưa có ai phụ trách: khi đó không ai được chọn.
            </param>
            <param name="currentUserId">Người đang thực hiện việc chuyển / phân công</param>
            <param name="staffId">Người được chọn làm người nhận</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityLevel">
            <summary>
            Mức phạm vi hội thoại chat của một người dùng, theo §3.7 của kế hoạch phân phối khách chat.
            Giá trị số chỉ dùng để so mức cao thấp trong bộ nhớ, KHÔNG lưu xuống database.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityLevel.Self">
            <summary>Chỉ hội thoại mình đang giữ — mặc định của mọi tài khoản</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityLevel.Team">
            <summary>Hội thoại của mình và của cấp dưới trực tiếp (<c>DataAccessScope.ManagedTeam</c>)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityLevel.Channel">
            <summary>Mọi hội thoại của những kênh mình là trưởng nhóm hoặc chủ kênh</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityLevel.All">
            <summary>Mọi hội thoại của toàn hệ thống</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility">
            <summary>
            Phạm vi hội thoại chat của một người dùng tại một thời điểm — kết quả của
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatVisibilityResolver.ResolveAsync(System.Int32)"/>.
            <para>
            Lớp này giữ <b>một</b> điều kiện lọc duy nhất (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.BuildConversationFilter"/>) dùng
            lại ở mọi đường đọc. Chép luật lọc ra 13 chỗ là cách chắc chắn nhất để chúng lệch nhau, và
            một chỗ lệch trên bề mặt này là một lỗ IDOR (bài học <c>docs/security-audit-2026-07-11.md</c>).
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.Level">
            <summary>Mức phạm vi cao nhất người này đạt được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.UserId">
            <summary>Người dùng mà phạm vi này thuộc về</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.GuardedChannelIds">
            <summary>
            Những kênh <b>có hàng rào</b> — kênh mà quản trị đã chuyển khỏi
            <see cref="F:Lada.Framework.Data.Enums.ChatAssignmentMode.Shared"/>.
            <para>
            Cố ý liệt kê kênh CÓ hàng rào chứ không đọc <c>AssignmentMode</c> qua navigation
            <c>ChatConversation.ChatChannel</c>: điều kiện lọc phải chạy đúng cả khi lời gọi không
            <c>Include</c> navigation đó. Danh sách này rất nhỏ (đo trên dev 2026-08-28: 3 kênh).
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.VisibleChannelIds">
            <summary>
            Những kênh người này xem được TOÀN BỘ hội thoại — kênh mình là trưởng nhóm
            (<see cref="F:Lada.Framework.Data.Enums.ChatChannelRole.Leader"/>) hoặc chủ kênh (<see cref="F:Lada.Framework.Data.Enums.ChatChannelRole.Owner"/>).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.VisibleStaffIds">
            <summary>
            Những nhân viên mà người này xem được hội thoại của họ: luôn có chính mình, thêm cấp
            dưới trực tiếp khi <c>DataAccessScope = ManagedTeam</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.ReadableConversationIds">
            <summary>
            Những hội thoại người này <b>từng</b> giữ và còn được đọc — quyết định §6.2, sổ nợ
            PP-10 đã đóng ở giai đoạn B.
            <para>
            Nạp sẵn thành một danh sách mã thay vì lồng một <c>Any()</c> vào biểu thức lọc, vì hai
            lý do. Thứ nhất, biểu thức phải dịch được sang SQL ở <b>mọi</b> đường đọc cùng lúc, và
            một <c>EXISTS</c> lồng đòi navigation collection trên <c>ChatConversation</c> — thêm
            một navigation vào entity đang phục vụ khách thật chỉ để phục vụ hàng rào là cái giá
            đắt hơn cần thiết. Thứ hai, và quan trọng hơn: danh sách nạp sẵn chạy <b>giống hệt
            nhau</b> trên database thật và trên kho dữ liệu giả của bộ test, còn navigation
            collection thì rỗng trong test trừ khi từng ca tự dựng nó — nghĩa là ca test sẽ xanh
            vì lý do sai.
            </para>
            <para>
            Cỡ danh sách: đo trên dev 2026-08-28, toàn hệ thống 21 hội thoại/ngày. Một sale làm
            tròn năm tích khoảng vài trăm mã. Nếu con số này lớn lên tới mức phải cắt, chỗ sửa là
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityResolver"/> chứ không phải lớp này.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.Everything(System.Int32)">
            <summary>Phạm vi "thấy tất cả" — dùng cho Founder, quyền <c>ChatConversation.ViewAll</c>, và các luồng máy chạy (webhook, job)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.BuildConversationFilter">
            <summary>
            Điều kiện lọc dùng chung cho MỌI đường đọc hội thoại.
            <para>
            Đọc thành lời: <i>hội thoại thuộc kênh chưa bật hàng rào</i> (giữ nguyên hành vi hôm
            nay, §6.3) <i>hoặc thuộc kênh mình phụ trách toàn bộ</i> <i>hoặc đang giao cho người
            trong phạm vi của mình</i>.
            </para>
            <para>
            Hệ quả có chủ ý: hội thoại <b>chưa giao cho ai</b> ở một kênh đã bật hàng rào thì sale
            thường KHÔNG thấy — nó là hàng chờ, thuộc về trưởng nhóm và người điều phối. Ở giai
            đoạn A chưa có máy phân phối nên kênh vừa bật <c>AutoDistribute</c> sẽ có hàng chờ
            không ai ngoài trưởng nhóm nhìn thấy; đó là lý do giao diện phải cảnh báo rõ khi đổi
            chế độ, và là lý do trình tự production bật thử đúng một kênh trước.
            </para>
            <para>
            Mức <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityLevel.Self"/> chấm cả người <b>đang</b> giữ lẫn người
            <b>từng</b> giữ hội thoại với <c>KeepReadAccess = true</c> (§6.2, PP-10 đóng ở giai
            đoạn B). Nhánh "từng giữ" chỉ MỞ RỘNG phạm vi, không bao giờ thu hẹp — nên một hội
            thoại đang trong phạm vi vẫn ở trong phạm vi dù lịch sử nói gì.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.BuildWritableConversationFilter">
            <summary>
            Điều kiện lọc cho các đường <b>GHI</b>: giống
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.BuildConversationFilter"/> nhưng <b>bỏ nhánh "từng giữ"</b>.
            </summary>
            <remarks>
            <para>
            Quyết định §6.2 viết nguyên văn: sale cũ <i>"còn xem chỉ đọc"</i>. Hai chữ <b>chỉ đọc</b>
            là ranh giới này. Không có nó thì việc mở phạm vi ở giai đoạn B (PP-10) đồng thời mở cả
            mười đường ghi: người từng giữ hội thoại ba tháng trước vẫn <b>gửi tin cho khách</b> của
            người đang giữ, gỡ liên kết khách hàng, đổi trạng thái, thậm chí phân công lại hội thoại
            đó cho chính mình. Đó không phải một lỗ do sơ suất — nó là hệ quả trực tiếp và bắt buộc
            của việc nới một hàng rào, đúng bài học F-7 của giai đoạn A: <b>mỗi lần nới phạm vi
            phải soi lại xem những đường nào vừa được nới theo mà không ai định thế</b>.
            </para>
            <para>
            Biểu thức này chính là biểu thức của giai đoạn A, giữ nguyên từng nhánh. Người ĐANG giữ,
            trưởng nhóm của kênh, người xem-tất-cả và kênh <c>Shared</c> ghi được như cũ.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.Allows(Lada.Framework.Data.Domains.SocialChat.ChatConversation)">
            <summary>
            Chấm một hội thoại đã nạp sẵn — phạm vi <b>đọc</b>. Dùng CHÍNH biểu thức của
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.BuildConversationFilter"/> đã biên dịch — không có luật thứ hai để lệch.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.AllowsWrite(Lada.Framework.Data.Domains.SocialChat.ChatConversation)">
            <summary>
            Chấm một hội thoại đã nạp sẵn — phạm vi <b>ghi</b>, tức có được thay đổi hội thoại này
            không. Xem <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.BuildWritableConversationFilter"/>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatVisibilityResolver">
            <summary>
            Nguồn duy nhất của luật "ai xem được hội thoại chat của ai" (kế hoạch phân phối khách chat §3.7).
            <para>
            Tách riêng vì phân hệ chat có <b>13 đường đọc/ghi</b> cùng chạm một tập dữ liệu, và bài học
            của <c>KpiVisibilityResolver</c> đã chỉ đích danh rủi ro: đường thứ hai quên lọc phạm vi là
            lỗ IDOR kinh điển. Mọi đường phải hỏi đúng lớp này.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatVisibilityResolver.ResolveAsync(System.Int32)">
            <summary>
            Phạm vi hội thoại của một người dùng. <paramref name="userId"/> ≤ 0 (luồng máy chạy:
            webhook, job nền) trả về phạm vi rỗng nhất có thể — mọi đường máy chạy phải tự truyền
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility.Everything(System.Int32)"/> khi thật sự cần toàn quyền, chứ không được
            hưởng nó nhờ thiếu một tham số.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatVisibilityResolver.ResolveForQueueAsync(System.Int32)">
            <summary>
            Phạm vi dùng RIÊNG cho màn điều phối hàng chờ.
            </summary>
            <remarks>
            <para>
            Khác <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatVisibilityResolver.ResolveAsync(System.Int32)"/> đúng một điểm: người có <c>ChatDistribution.Manage</c>
            được mức <c>All</c>. Lý lẽ: sau bản vá F-1, quyền ấy là quyền <b>duy nhất</b> đổi được
            chế độ phân phối của một kênh và đặt được vai trò <c>Owner</c>/<c>Leader</c> — người
            giữ nó đã có thể tự ghi mình làm chủ kênh bất kỳ rồi đọc tất cả. Cho họ nhìn hàng chờ
            không mở thêm cửa nào; giấu đi chỉ khiến họ đi đường vòng bằng cách tự nâng vai trò,
            và đường vòng đó mới là thứ không ai rà được.
            </para>
            <para>
            <b>Chỉ dùng cho hàng chờ.</b> Người gọi phải lọc thêm
            <c>AssignedStaffId == null</c>; dùng phạm vi này ở một đường đọc thường là biến quyền
            quản trị phân phối thành quyền đọc mọi hội thoại của mọi sale — đúng thứ §3.7 cố ý
            KHÔNG cho, khi nó tách <c>ChatConversation.ViewAll</c> ra thành một quyền riêng.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityResolver">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatVisibilityResolver" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityResolver.RoleFounder">
            <summary>Bỏ qua mọi ràng buộc phạm vi</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityResolver.RoleViewAll">
            <summary>Xem hội thoại của toàn hệ thống</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityResolver.RoleViewChannel">
            <summary>Xem toàn bộ hội thoại của kênh mình là trưởng nhóm</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityResolver.RoleDistributionManage">
            <summary>Quản trị phân phối toàn hệ thống — xem <c>ResolveForQueueAsync</c></summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityResolver.ResolveForQueueAsync(System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityResolver.ResolveAsync(System.Int32)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibilityResolver.ReadPastConversationIdsAsync(System.Collections.Generic.List{System.Int32},System.Collections.Generic.List{System.Int32})">
            <summary>
            Những hội thoại mà người này (hoặc cấp dưới của họ) <b>từng</b> giữ và còn được đọc —
            quyết định §6.2, đóng sổ nợ PP-10.
            </summary>
            <remarks>
            <para>
            Lấy theo cả <paramref name="visibleStaffIds"/> chứ không riêng người đang hỏi, để nhánh
            "từng giữ" đi cùng luật với nhánh "đang giữ" ngay cạnh nó trong biểu thức lọc: quản lý
            mức <c>Team</c> xem được hội thoại cấp dưới đang cầm thì cũng xem được hội thoại cấp
            dưới từng cầm. Hai nhánh lệch nhau ở điểm này là thứ không ai giải thích nổi cho người
            dùng, và cũng không ai nhớ nổi khi sửa lần sau.
            </para>
            <para>
            <b>Chỉ MỞ RỘNG.</b> Truy vấn hỏng hay trả rỗng thì phạm vi trở về đúng bằng giai đoạn
            A — hẹp hơn, chưa bao giờ rộng hơn.
            </para>
            <para>
            <c>Query()</c> chứ không <c>QueryAll()</c>: đây là điều kiện MỞ RỘNG phạm vi nên đọc
            bản ghi đã xoá mềm vào đây là dùng dữ liệu chết để cấp quyền — ngược hẳn ngoại lệ có
            chủ ý của <c>guardedChannelIds</c> ở trên, nơi bản ghi đã xoá chỉ làm phạm vi hẹp lại.
            </para>
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatUserScope">
            <summary>
            Đọc <see cref="T:Lada.Framework.Data.Enums.DataAccessScope"/> của một tài khoản — <b>một luật, một chỗ</b> cho cả hàng
            rào quyền xem lẫn đường cấu hình sale phụ trách kênh.
            <para>
            Nguồn là <c>UserPreference.DataAccessScope</c>, KHÔNG phải <c>User</c>. Tài khoản chưa có
            dòng cấu hình nào thì mặc định <see cref="F:Lada.Framework.Data.Enums.DataAccessScope.SelfOnly"/> — cùng giá trị mà
            <c>KpiVisibilityResolver</c> dùng. Đọc thẳng repository thay vì gọi
            <c>IUserService.GetDataAccessScopeAsync</c> để hai chỗ này dựng được trong test mà không
            phải giả lập một interface 54 method.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatUserScope.ReadAsync(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Identity.UserPreference},System.Int32)">
            <param name="userPreferenceRepository">Kho cấu hình người dùng</param>
            <param name="userId">Tài khoản cần tra; ≤ 0 trả về phạm vi hẹp nhất</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours">
            <summary>
            Cửa sổ giờ làm việc của đội sale — <b>hàm thuần</b>, không chạm database, không đọc
            <c>AppConfig</c>, không hỏi đồng hồ hệ thống.
            <para>
            Tách ra khỏi phần chạm hạ tầng đúng cách <c>ChatRealtimeAudience.Resolve</c> đã làm ở giai
            đoạn A: nhờ thế kiểm được bằng bảng ca (thời điểm vào → trong hay ngoài giờ làm) mà không
            cần dựng kho dữ liệu giả nào. Repo <b>không có</b> abstraction đồng hồ (không
            <c>ISystemClock</c>, không <c>TimeProvider</c>) nên "bây giờ" phải là <b>tham số</b>, đúng
            khuôn <c>IComponentConditionEvaluator.Evaluate(input, asOf)</c>.
            </para>
            <para>
            Vì sao giờ làm việc quan trọng đến thế ở giai đoạn C: số đo Việc 0 loại bỏ hai trong bốn
            nguồn mà §3.5 dự kiến (nghỉ phép — bảng rỗng, PP-11; chấm công — chỉ 20/40 sale dùng,
            PP-12), và chủ dự án trả lời "chưa ai" cho câu hỏi bao nhiêu sale sẽ dùng menu tự đổi trạng
            thái. Nên đây là nguồn <b>chính</b> quyết định ai đang nhận khách, không phải nguồn phụ.
            </para>
            <para>
            <b>KC-18 (2026-09-27) đảo tiền đề trên:</b> chủ dự án chốt nhận khách theo <b>trạng thái</b>
            sale đặt, không theo giờ làm (plan khoá học chat §8.6–§8.7). Lớp này nay có ba đường dựng:
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Parse(System.String,System.String,System.String,System.String,System.String,System.Int32)"/> cho cấu hình chung (giữ nguyên nghĩa cũ — chỉ còn là giờ gợi ý, múi giờ
            và bộ lọc tiêu chí "trả lời đầu tiên"), <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.ForStaff(System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.String,System.TimeSpan)"/>
            cho giờ riêng một sale tự đặt, và <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.CreateAlwaysOpen(System.TimeSpan)"/> cho người chưa đặt.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Default">
            <summary>
            Cửa sổ mặc định, dùng khi cấu hình thiếu hoặc không đọc được:
            08:00–17:30, Thứ Hai đến Thứ Bảy, nghỉ trưa 12:00–13:00, múi giờ +07:00.
            <para>
            Đây là <b>giờ làm chính thức đã xác nhận với chủ dự án 2026-08-29</b>, không phải một
            con số tròn bịa ra. Rơi về đây là fail-<i>safe</i>, không phải fail-open: cấu hình hỏng
            không được biến cả tuần thành giờ làm (chia khách lúc 2 giờ sáng) mà cũng không được
            biến cả tuần thành ngoài giờ (cả đội ngừng nhận khách).
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.EndOfDayInput">
            <summary>
            Giờ kết thúc mà người dùng chọn để nói "làm tới hết ngày" (KC-18, thiết kế mục 3).
            <para>
            Cột SQL <c>time</c> không chứa được <c>24:00</c>, ô chọn giờ trên trình duyệt cũng
            không cho chọn <c>24:00</c> — nên <c>23:59</c> là cách duy nhất người dùng nói được ý
            đó. Đường giờ RIÊNG (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.ForStaff(System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.String,System.TimeSpan)"/>)
            đổi nó thành <c>24:00</c> trong bộ nhớ. Đường cấu hình chung (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Parse(System.String,System.String,System.String,System.String,System.String,System.Int32)"/>)
            <b>không</b> đổi — giữ nguyên nghĩa cũ để bảng ca cũ không đổi.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.OneDay">
            <summary>Một ngày tròn — giờ kết thúc "hết ngày" trong bộ nhớ (<c>24:00</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.AlwaysOpen">
            <summary>
            Cửa sổ <b>luôn trong ca</b> ở múi giờ mặc định +07:00 — xem <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.CreateAlwaysOpen(System.TimeSpan)"/>.
            Người gọi có múi giờ cấu hình trong tay thì dùng <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.CreateAlwaysOpen(System.TimeSpan)"/> với múi
            giờ đó thay vì thuộc tính này.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Epoch">
            <summary>
            Mốc gốc để quy một thời điểm về "tổng số phút giờ làm đã trôi qua kể từ mốc gốc".
            <c>0001-01-01</c> là <b>Thứ Hai</b>, nên số ngày kể từ mốc này chia 7 ra đúng số tuần
            tròn mà không phải chỉnh lệch pha.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours._minutesPerWorkingDay">
            <summary>Số phút làm việc của một ngày làm trọn vẹn (đã trừ nghỉ trưa)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours._minutesPerWeek">
            <summary>Số phút làm việc của một tuần trọn vẹn</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Start">
            <summary>Giờ bắt đầu làm việc (giờ địa phương theo <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Offset"/>)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.End">
            <summary>
            Giờ kết thúc làm việc. Khoảng làm việc là nửa mở <c>[Start, End)</c>.
            <para>
            Với giờ riêng chọn <c>23:59</c> và với <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.AlwaysOpen"/>, giá trị này là
            <c>24:00</c> (<c>1.00:00:00</c>) — định dạng nó bằng <c>hh\:mm</c> sẽ ra <c>00:00</c>.
            Hiển thị thì hỏi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.EndsAtEndOfDay"/> trước.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.EndsAtEndOfDay">
            <summary>
            Ca kéo tới hết ngày (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.End"/> là <c>24:00</c>) — để lớp hiển thị in "23:59"
            hoặc "hết ngày" thay vì "00:00".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.IsAlwaysOpen">
            <summary>
            Cửa sổ "luôn trong ca" (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.CreateAlwaysOpen(System.TimeSpan)"/>): mọi thời điểm đều là giờ làm,
            số phút giờ làm bằng số phút đồng hồ thật.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.BreakStart">
            <summary>Giờ bắt đầu nghỉ trưa, <c>null</c> = không có nghỉ trưa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.BreakEnd">
            <summary>
            Giờ kết thúc nghỉ trưa, <c>null</c> = không có nghỉ trưa.
            <para>
            Giờ riêng nghỉ tới <c>23:59</c> trong ca kết thúc <c>23:59</c> mang giá trị <c>24:00</c> ở
            đây — cùng luật với <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.End"/>; hiển thị thì hỏi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.BreakEndsAtEndOfDay"/>.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.BreakEndsAtEndOfDay">
            <summary>
            Nghỉ trưa kéo tới hết ngày (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.BreakEnd"/> là <c>24:00</c>) — để lớp hiển thị không
            in <c>00:00</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Offset">
            <summary>Múi giờ áp cho cửa sổ này (Việt Nam = +07:00)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.WorkingDays">
            <summary>Các ngày làm việc trong tuần</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Parse(System.String,System.String,System.String,System.String,System.String,System.Int32)">
            <summary>
            Dựng cửa sổ giờ làm việc từ các chuỗi cấu hình thô. <b>Không bao giờ ném lỗi</b>: mọi
            giá trị không đọc được đều rơi về vế tương ứng của <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Default"/>.
            </summary>
            <param name="start">Giờ vào, dạng <c>HH:mm</c></param>
            <param name="end">Giờ ra, dạng <c>HH:mm</c></param>
            <param name="breakStart">Giờ bắt đầu nghỉ trưa, dạng <c>HH:mm</c>; rỗng = không nghỉ trưa</param>
            <param name="breakEnd">Giờ kết thúc nghỉ trưa, dạng <c>HH:mm</c>; rỗng = không nghỉ trưa</param>
            <param name="workingDays">
            Danh sách ngày làm, ngăn cách bằng dấu phẩy, đánh số <b>theo cách gọi tiếng Việt</b>:
            2 = Thứ Hai … 7 = Thứ Bảy, 8 = Chủ Nhật. Chọn cách đánh số này thay vì
            <c>DayOfWeek</c> của .NET (0 = Chủ Nhật) vì người vận hành sẽ sửa ô này trên màn quản
            trị, và ở đó "2" phải có nghĩa là Thứ Hai.
            </param>
            <param name="offsetHours">Múi giờ, tính bằng giờ so với UTC</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.CreateAlwaysOpen(System.TimeSpan)">
            <summary>
            Cửa sổ <b>luôn trong ca</b> (KC-18, thiết kế mục 2): <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.IsWorkingTime(System.DateTimeOffset)"/> luôn
            đúng, <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.WorkingMinutesBetween(System.DateTimeOffset,System.DateTimeOffset)"/> bằng số phút đồng hồ thật.
            </summary>
            <remarks>
            <para>
            Đây là cửa sổ của mọi sale <b>chưa tự đặt giờ làm</b> — chủ dự án chốt 2026-09-27 (§8.6,
            §8.7): nhận hay không nhận khách là do <b>trạng thái</b> sale đặt, không do giờ làm.
            Cấu hình chung <c>Chat.WorkingHours.*</c> không còn áp cho ai nữa, chỉ còn là giờ gợi ý.
            </para>
            <para>
            Vì sao không dựng bằng <c>Parse("00:00", "23:59", …)</c> như production đang làm: khoảng
            làm việc là nửa mở <c>[Start, End)</c>, nên cấu hình ấy để hở đúng phút 23:59 mỗi đêm —
            khách nhắn lúc 23:59:30 rơi vào "Ngoài giờ". Cửa sổ này có <c>End = 24:00</c> và đi đường
            tắt riêng nên không có lỗ đó.
            </para>
            <para>
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Start"/>/<see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.End"/>/<see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.WorkingDays"/> vẫn mang giá trị nhất quán
            (00:00–24:00, cả bảy ngày, không nghỉ trưa) để lớp nào lỡ đọc chúng cũng không thấy rác.
            </para>
            </remarks>
            <param name="offset">
            Múi giờ cấu hình (<c>App.TimeZoneOffsetHours</c>, lấy qua cấu hình chung). Vẫn cần dù
            đồng hồ không dừng: phép đếm tải trong ngày và phát lại quyết định chia ngày theo nó.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.ForStaff(Lada.Framework.Data.Domains.SocialChat.ChatAgentPresence,System.TimeSpan)">
            <summary>
            Dựng giờ làm <b>riêng</b> của một sale từ dòng <c>ChatAgentPresence</c> đã nạp sẵn —
            không có dòng nghĩa là chưa đặt.
            </summary>
            <param name="presence">Dòng trạng thái của người đó; <c>null</c> = chưa từng có dòng</param>
            <param name="offset">Múi giờ cấu hình</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.ForStaff(System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.String,System.TimeSpan)">
            <summary>
            Dựng giờ làm <b>riêng</b> của một sale từ bốn cột giờ và cột ngày làm (KC-18, thiết kế
            mục 2–3). <b>Không bao giờ ném lỗi</b> và không bao giờ trả <c>null</c>.
            </summary>
            <remarks>
            <list type="bullet">
            <item><b>Chưa đặt</b> (<paramref name="workStart"/> và <paramref name="workEnd"/> cùng
            <c>null</c>) ⇒ <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.CreateAlwaysOpen(System.TimeSpan)"/>, trạng thái
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursState.NotSet"/>.</item>
            <item><b>Hợp lệ</b> ⇒ cửa sổ riêng, trạng thái <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursState.Own"/>.
            <paramref name="workEnd"/> từ <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.EndOfDayInput"/> trở lên nghĩa là "hết ngày" và
            thành <c>24:00</c> trong bộ nhớ; <paramref name="breakEnd"/> cũng vậy (nghỉ tới hết ca
            "hết ngày" thì phút 23:59 cũng là giờ nghỉ, không phải giờ làm).</item>
            <item><b>Hỏng</b> ⇒ vẫn <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.CreateAlwaysOpen(System.TimeSpan)"/>, trạng thái
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursState.Invalid"/>, kèm câu mô tả để <b>người gọi</b> ghi
            log (hàm thuần không log được).</item>
            </list>
            <para>
            <b>Vì sao dữ liệu hỏng rơi về "luôn trong ca" chứ không về <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Default"/>
            08:00–17:30</b> như <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Parse(System.String,System.String,System.String,System.String,System.String,System.Int32)"/>: rơi về <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Default"/> là âm thầm đẩy
            một người ra "Ngoài giờ" từ 17:30 tới sáng hôm sau và cả Chủ Nhật, trong khi người đó
            chưa từng chọn giờ ấy. Cùng triết lý fail-open của
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailability.Resolve(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAgentAvailabilityInput,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours)"/>: hỏng thì tệ nhất là chia khách cho người
            không muốn nhận lúc ấy, và họ đổi trạng thái là xong.
            </para>
            <para>
            Luật hợp lệ dùng <b>chung</b> với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.ValidateStaffInput(System.String,System.String,System.String,System.String,System.String)"/> — dòng nào API nhận
            được thì hàm này dựng được, không có vùng xám giữa hai định nghĩa.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.ValidateStaffInput(System.String,System.String,System.String,System.String,System.String)">
            <summary>
            Kiểm hợp lệ giờ làm riêng mà sale (hoặc quản lý đặt hộ) gửi lên — <b>hàm thuần</b>, trả
            danh sách lỗi tiếng Việt để trả thẳng cho người dùng, kèm giá trị đã chuẩn hoá để ghi
            xuống cột.
            </summary>
            <remarks>
            <list type="bullet">
            <item>Giờ bắt đầu và giờ kết thúc <b>cùng trống</b> ⇒ yêu cầu <b>xoá</b> giờ riêng, về
            "chưa đặt" (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursValidation.IsClear"/>); các ô còn lại bị bỏ
            qua.</item>
            <item>Giờ dạng <c>HH:mm</c> (hoặc <c>H:mm</c>); giờ bắt đầu phải sớm hơn giờ kết thúc
            — ca qua đêm chưa hỗ trợ, cùng lý do với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Parse(System.String,System.String,System.String,System.String,System.String,System.Int32)"/>. Giờ kết thúc
            <c>23:59</c> nghĩa là hết ngày; gõ <c>24:00</c> được hiểu là <c>23:59</c>.</item>
            <item>Nghỉ trưa: đủ cả hai đầu hoặc trống cả hai; đầu trước sớm hơn đầu sau; nằm trong
            <c>[giờ bắt đầu, giờ kết thúc]</c>; không phủ kín cả ca (phủ kín là một người vĩnh viễn
            "Ngoài giờ" mà không ai hiểu vì sao). Trong ca kết thúc <c>23:59</c>, nghỉ tới
            <c>23:59</c> (hay <c>24:00</c>) là nghỉ tới <b>hết ngày</b> — <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.ForStaff(System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.String,System.TimeSpan)"/>
            dựng đúng nghĩa ấy.</item>
            <item>Ngày làm: tập con <b>khác rỗng</b> của mã 2 (Thứ Hai) … 8 (Chủ Nhật), cùng cách
            đánh số với <c>Chat.WorkingHours.WorkingDays</c>. Mã lặp được gộp, không coi là lỗi.</item>
            </list>
            <para>
            Khác <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Parse(System.String,System.String,System.String,System.String,System.String,System.Int32)"/> có chủ ý: <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Parse(System.String,System.String,System.String,System.String,System.String,System.Int32)"/> đọc cấu hình người vận hành đã
            lưu nên phải nuốt mọi thứ và rơi về mặc định; hàm này đứng ở cửa API nên phải <b>từ
            chối</b> và nói rõ vì sao — nhận bừa rồi rơi về một giá trị khác là lưu một thứ người
            dùng không hề chọn.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.IsWorkingTime(System.DateTimeOffset)">
            <summary>
            Thời điểm <paramref name="at"/> có nằm trong giờ làm việc không.
            </summary>
            <remarks>
            Quy về múi giờ <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Offset"/> trước khi hỏi thứ mấy và mấy giờ. Không làm bước
            này thì cùng một thời điểm cho hai câu trả lời khác nhau tuỳ máy chủ chạy ở UTC hay ở
            giờ Việt Nam — đúng lớp lỗi lệch múi giờ đã cắn ở đợt bảo dưỡng xe.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.WorkingMinutesBetween(System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Số phút <b>giờ làm</b> trôi qua giữa hai thời điểm. Trả <c>0</c> khi
            <paramref name="to"/> không muộn hơn <paramref name="from"/>.
            </summary>
            <remarks>
            <para>
            Đây là phép đo mà giai đoạn E đứng lên: "quá hạn phản hồi" <b>không phải</b> hiệu số hai
            mốc thời gian. Khách nhắn 17:20 Thứ Sáu, sale trả lời 08:10 Thứ Hai — đồng hồ thường nói
            62 giờ, đồng hồ giờ làm nói 60 phút. Đo bằng đồng hồ thường là biến mọi tin đến buổi tối
            thành một lượt vi phạm ngay khi trời sáng, và đó đúng là điều §4 GĐ E cấm ("tin nhắn 2
            giờ sáng không được làm hỏng điểm của ai").
            </para>
            <para>
            <b>Không lặp vòng từng phút, cũng không lặp từng ngày.</b> Một hội thoại bị bỏ quên ba
            tháng sẽ làm một vòng lặp theo phút chạy 130 nghìn bước trong một job quét 2 phút — và
            dữ liệu dev đã có sẵn một bản ghi lệch <i>một năm</i> (Đ5 §2.4). Cách làm ở đây quy mỗi
            thời điểm về "tổng phút giờ làm kể từ <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Epoch"/>" rồi lấy hiệu: số tuần tròn
            tính bằng một phép nhân, phần dư nhiều nhất 6 ngày.
            </para>
            <para>
            <b>Chưa trừ ngày lễ</b> — nợ PP-25, cố ý. Bảng <c>Holiday</c> đo được 0 dòng trên dev
            (2026-08-29), nên dựng nhánh ấy bây giờ là dựng thêm một nhánh chết, đúng bài học PP-11.
            Khi nhân sự bắt đầu điền bảng đó thì phép trừ nằm ở lớp gọi, không nằm trong hàm thuần
            này.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.ShiftRangesBetween(System.DateTimeOffset,System.DateTimeOffset)">
            <summary>
            Các khoảng <b>trong ca</b> nằm lọt trong <c>[from, to)</c>, đã sắp theo thời gian và không
            chồng nhau — mỗi ngày làm nhiều nhất hai khoảng (trước và sau nghỉ trưa).
            </summary>
            <remarks>
            <para>
            Tồn tại cho phép hợp khoảng của đồng hồ hàng chờ (KC-18, thiết kế mục 5): "có ít nhất một
            ứng viên vào ca" là <b>hợp</b> của nhiều cửa sổ giờ làm khác nhau, mà hợp thì phải có khoảng
            trong tay — <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.WorkingMinutesBetween(System.DateTimeOffset,System.DateTimeOffset)"/> chỉ trả một con số, cộng số của hai người là
            đếm đôi phút cả hai cùng trong ca.
            </para>
            <para>
            Cùng một định nghĩa với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.IsWorkingTime(System.DateTimeOffset)"/>: một thời điểm nằm trong khoảng trả về
            khi và chỉ khi <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.IsWorkingTime(System.DateTimeOffset)"/> nói đúng, và tổng độ dài các khoảng bằng
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.WorkingMinutesBetween(System.DateTimeOffset,System.DateTimeOffset)"/> (bảng ca đối chiếu ở <c>ChatCoverageTests</c>). Viết
            lại luật nghỉ trưa theo một cách khác ở đây là dựng định nghĩa thứ hai của "trong ca".
            </para>
            <para>
            Lặp <b>theo ngày</b>, không theo phút — người gọi phải tự giới hạn độ dài khoảng (đồng hồ hàng
            chờ cắt ở <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatCoverage.MaxSpan"/>).
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.DayPieces">
            <summary>
            Ca của một ngày làm, tính bằng giờ trong ngày: <c>[Start, End)</c> trừ nghỉ trưa
            <c>[BreakStart, BreakEnd)</c>. Đúng điều kiện mà <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.IsWorkingTime(System.DateTimeOffset)"/> kiểm — nghỉ trưa
            thiếu một đầu hoặc ngược chiều thì coi như không có.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.WorkingMinutesSinceEpoch(System.DateTimeOffset)">
            <summary>
            Tổng số phút giờ làm từ <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Epoch"/> tới <paramref name="at"/>. Hàm đơn điệu
            không giảm, nên hiệu của hai lần gọi chính là số phút giờ làm giữa chúng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.WholeDayMinutes(System.DayOfWeek)">
            <summary>Số phút làm việc của trọn một ngày, theo thứ trong tuần.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.PartialDayMinutes(System.DayOfWeek,System.TimeSpan)">
            <summary>
            Số phút làm việc đã trôi qua trong một ngày, tính từ 00:00 tới
            <paramref name="timeOfDay"/>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.BreakOverlapMinutes(System.TimeSpan,System.TimeSpan,System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan})">
            <summary>
            Số phút nghỉ trưa nằm lọt trong khoảng <c>[windowStart, windowEnd)</c> của một ngày.
            Không có nghỉ trưa, hoặc nghỉ trưa nằm ngoài khoảng, thì bằng 0.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.DayOfWeekFromCodeOrNull(System.Int32)">
            <summary>2 = Thứ Hai … 7 = Thứ Bảy, 8 = Chủ Nhật; mã khác trả <c>null</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.ParseInputTime(System.String,System.String,System.String,System.Collections.Generic.List{System.String})">
            <summary>
            Đọc một ô giờ người dùng gửi lên. Nhận thêm <c>24:00</c> như <c>23:59</c> — cả hai đều
            là "hết ngày", và bắt người dùng hiểu cột SQL <c>time</c> để gõ đúng là vô lý.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.ParseStrictDayCodes(System.String,System.Collections.Generic.List{System.String})">
            <summary>
            Đọc chuỗi mã ngày làm theo luật <b>chặt</b> — khác <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.ParseWorkingDays(System.String)"/> của cấu
            hình chung (bỏ qua mã lạ, rỗng thì rơi về mặc định). Mã lạ hay rỗng ở đây là lỗi.
            Trả tập mã đã sắp xếp tăng dần, không lặp.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.CheckOrder(System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.Nullable{System.TimeSpan},System.Collections.Generic.List{System.String})">
            <summary>
            Kiểm thứ tự các mốc. Chỉ so khi đã đọc được đủ các vế liên quan — so trên một vế hỏng
            chỉ đẻ thêm lỗi thứ hai cho cùng một nguyên nhân. <paramref name="end"/> là giá trị
            người dùng thấy (<c>23:59</c> = hết ngày), chưa đổi sang <c>24:00</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.NormalizeOffset(System.TimeSpan)">
            <summary>
            <see cref="M:System.DateTimeOffset.ToOffset(System.TimeSpan)"/> chỉ nhận múi giờ tròn phút trong ±14 giờ — ngoài
            khoảng đó nó ném lỗi. Múi giờ lạ rơi về +07:00 như <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.Parse(System.String,System.String,System.String,System.String,System.String,System.Int32)"/> đang làm.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursState">
            <summary>
            Giờ làm riêng của một sale đang ở tình trạng nào (KC-18).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursState.NotSet">
            <summary>
            Chưa đặt — không có dòng <c>ChatAgentPresence</c>, hoặc giờ bắt đầu và giờ kết thúc
            cùng trống. Đây là trạng thái BÌNH THƯỜNG của gần như mọi sale (§8.6: mặc định ẩn giờ
            làm). Cửa sổ là "luôn trong ca"; tiêu chí 5 coi là chưa có mẫu (§8.7 câu 2).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursState.Own">
            <summary>Đã tự đặt (hoặc được quản lý đặt hộ) và dữ liệu hợp lệ.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursState.Invalid">
            <summary>
            Có dữ liệu nhưng hỏng (sửa tay trong DB, hoặc luật hợp lệ siết lại sau này). Cửa sổ vẫn
            là "luôn trong ca" — fail-open; người gọi phải ghi log cảnh báo để có người sửa.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours">
            <summary>
            Kết quả dựng giờ làm riêng của một sale: cửa sổ để dùng ngay, kèm tình trạng để người gọi
            phân biệt "chưa đặt" với "đã đặt" (tiêu chí 5, giao diện) và biết khi nào phải log.
            </summary>
            <param name="Hours">
            Cửa sổ để dùng — <b>không bao giờ</b> <c>null</c>. Chưa đặt hoặc hỏng thì là "luôn trong ca".
            </param>
            <param name="State">Tình trạng của giờ riêng</param>
            <param name="Problem">Mô tả lỗi dữ liệu bằng tiếng Việt khi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours.State"/> là <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursState.Invalid"/>; còn lại <c>null</c></param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours.#ctor(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursState,System.String)">
            <summary>
            Kết quả dựng giờ làm riêng của một sale: cửa sổ để dùng ngay, kèm tình trạng để người gọi
            phân biệt "chưa đặt" với "đã đặt" (tiêu chí 5, giao diện) và biết khi nào phải log.
            </summary>
            <param name="Hours">
            Cửa sổ để dùng — <b>không bao giờ</b> <c>null</c>. Chưa đặt hoặc hỏng thì là "luôn trong ca".
            </param>
            <param name="State">Tình trạng của giờ riêng</param>
            <param name="Problem">Mô tả lỗi dữ liệu bằng tiếng Việt khi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours.State"/> là <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursState.Invalid"/>; còn lại <c>null</c></param>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours.Hours">
            <summary>
            Cửa sổ để dùng — <b>không bao giờ</b> <c>null</c>. Chưa đặt hoặc hỏng thì là "luôn trong ca".
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours.State">
            <summary>Tình trạng của giờ riêng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours.Problem">
            <summary>Mô tả lỗi dữ liệu bằng tiếng Việt khi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours.State"/> là <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursState.Invalid"/>; còn lại <c>null</c></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours.HasOwnWorkingHours">
            <summary>
            Người này có giờ làm riêng dùng được không. Hỏng tính như chưa đặt: chấm tỉ lệ sẵn sàng
            trên một giờ làm mà chính dữ liệu của nó đã sai là chấm trên cát.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours.NotSet(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours)">
            <summary>Chưa đặt giờ riêng — dùng cửa sổ "luôn trong ca".</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours.Own(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours)">
            <summary>Giờ riêng hợp lệ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours.Invalid(Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours,System.String)">
            <summary>Giờ riêng hỏng — dùng cửa sổ "luôn trong ca", kèm lý do để log.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursValidation">
            <summary>
            Kết quả của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.ValidateStaffInput(System.String,System.String,System.String,System.String,System.String)"/>: danh sách lỗi tiếng Việt, hoặc
            các giá trị đã chuẩn hoá để ghi thẳng xuống bốn cột giờ và cột ngày làm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursValidation.Clear">
            <summary>Yêu cầu xoá giờ riêng, về "chưa đặt" — mọi cột giờ và ngày làm ghi <c>null</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursValidation.Errors">
            <summary>Lỗi tiếng Việt, trả thẳng cho người dùng. Rỗng = hợp lệ.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursValidation.IsValid">
            <summary>Hợp lệ (kể cả trường hợp xoá)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursValidation.IsClear">
            <summary>Giờ bắt đầu và giờ kết thúc cùng trống — xoá giờ riêng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursValidation.WorkStart">
            <summary>Giờ bắt đầu đã chuẩn hoá; <c>null</c> khi xoá hoặc không hợp lệ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursValidation.WorkEnd">
            <summary>
            Giờ kết thúc đã chuẩn hoá, <b>dạng lưu</b>: hết ngày là <c>23:59</c> (cột <c>time</c>
            không chứa được <c>24:00</c>); <c>null</c> khi xoá hoặc không hợp lệ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursValidation.BreakStart">
            <summary>Giờ bắt đầu nghỉ trưa; <c>null</c> = không nghỉ trưa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursValidation.BreakEnd">
            <summary>Giờ kết thúc nghỉ trưa; <c>null</c> = không nghỉ trưa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHoursValidation.WorkingDays">
            <summary>Mã ngày làm đã sắp xếp, không lặp, dạng <c>"2,3,4,5,6,7"</c></summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IFacebookApiService">
            <summary>
            Lớp duy nhất trong hệ thống biết giao thức của Facebook Graph API / Messenger Platform.
            <para>
            Mọi số liệu dưới đây lấy nguyên văn từ tài liệu thật ngày 2026-08-27 tại
            <c>developers.facebook.com</c> (Messenger Platform → Send API, Attachment Upload API,
            User Profile API; Facebook Login → Long-lived tokens; Pages API → Getting Started).
            </para>
            <para>
            Lớp này KHÔNG chạm tới database và KHÔNG biết gì về <c>ChatChannel</c>: nó nhận
            token đã giải mã sẵn và trả về kết quả thô. Việc lấy/lưu token là của
            <c>ChatChannelService</c>, việc ghép vào lõi chat là của <c>FacebookMessenger</c>.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IFacebookApiService.BuildAuthorizationLink(System.String)">
            <summary>
            Dựng đường dẫn hộp thoại cấp quyền để quản trị viên bấm vào và tự cấp quyền —
            đúng luồng <b>Facebook Login for Business</b> mà Pancake và các nền tảng khác dùng,
            thay cho việc dán tay user access token lấy từ Graph API Explorer.
            <para>
            Có khai <c>SocialChat:Facebook:LoginConfigId</c> thì đi bằng <c>config_id</c> (danh sách
            quyền cố định, khai sẵn trên cổng nhà phát triển); không khai thì lui về Facebook Login
            thường với tham số <c>scope</c>. Cả hai đều trả <c>code</c> về <c>RedirectUri</c>.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IFacebookApiService.ExchangeCodeAsync(System.String,System.Threading.CancellationToken)">
            <summary>
            Đổi <c>code</c> Facebook gửi kèm lần chuyển hướng về lấy user access token.
            <para>
            Token trả về ở đây <b>ngắn hạn</b> — phải đưa tiếp qua
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IFacebookApiService.ExchangeLongLivedUserTokenAsync(System.String,System.Threading.CancellationToken)"/> trước khi lấy Page token, nếu không Page
            token thừa hưởng tuổi thọ vài giờ rồi kênh chết im lặng.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IFacebookApiService.ExchangeLongLivedUserTokenAsync(System.String,System.Threading.CancellationToken)">
            <summary>
            Đổi user access token ngắn hạn (dán từ Graph API Explorer, sống ~1-2 giờ) lấy bản dài hạn
            (~60 ngày). Page access token lấy từ bản dài hạn thì <b>không có hạn dùng</b>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IFacebookApiService.GetManagedPagesAsync(System.String,System.Threading.CancellationToken)">
            <summary>
            Danh sách Page mà chủ tài khoản đang quản lý, kèm Page access token của từng Page
            (<c>GET /me/accounts</c>). Kết quả có chứa bí mật — không bao giờ ghi nhật ký, không trả thẳng ra API.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IFacebookApiService.SendTextAsync(System.String,System.String,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Gửi tin nhắn văn bản qua Send API.
            <para>
            <paramref name="replyToMessageId"/> là <c>mid</c> của tin mà tin này TRẢ LỜI TRÍCH DẪN,
            bỏ trống thì gửi tin thường. Nó đi vào thân request ở <b>cấp gốc</b> — <c>reply_to.mid</c>
            nằm ngang hàng với <c>recipient</c> và <c>message</c>, KHÔNG nằm trong <c>message</c>.
            Chiều nhận webhook thì ngược lại: ở đó <c>reply_to</c> nằm <b>trong</b> <c>message</c>
            (xem <c>FacebookWebhookParser.ReadRepliedMessageId</c>). Hai chiều lệch chỗ nhau là chỗ
            dễ viết sai nhất; đã đối chiếu tài liệu Send Messages ngày 2026-08-28.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IFacebookApiService.UploadImageAsync(System.String,System.String,System.String,System.Threading.CancellationToken)">
            <summary>Tải một tệp ảnh lên máy chủ Facebook để lấy <c>attachment_id</c> dùng lại được.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IFacebookApiService.SendImageAsync(System.String,System.String,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Gửi tin nhắn ảnh. Truyền một trong hai: <paramref name="attachmentId"/> (đã tải lên)
            hoặc <paramref name="imageUrl"/> (đường dẫn công khai).
            <para>
            Không có tham số chú thích: một tin Messenger mang <b>hoặc</b> <c>text</c> <b>hoặc</b>
            <c>attachment</c>, không mang cả hai. Chú thích là một tin văn bản riêng, do
            <c>FacebookMessenger</c> gửi tiếp sau.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IFacebookApiService.SendReactionAsync(System.String,System.String,System.String,System.String,System.String,System.Boolean,System.Threading.CancellationToken)">
            <summary>
            Thả (hoặc gỡ) một biểu tượng cảm xúc lên tin nhắn của khách.
            <para>
            Đi qua <c>sender_action</c> của chính Send API chứ không phải một endpoint riêng — đó là
            lý do nó dễ bị kết luận nhầm là "Facebook không cho Page thả cảm xúc" khi chỉ đọc trang
            Send API. Facebook nhận <b>emoji tuỳ ý</b>, không phải một tập mã cố định như Zalo.
            </para>
            <para>
            Tài liệu chốt hai ràng buộc: request <c>sender_action</c> chỉ được mang
            <c>recipient</c> + <c>sender_action</c> (+ <c>payload</c>), <b>không kèm</b>
            <c>message</c>; và khi gỡ thì bỏ hẳn trường <c>reaction</c> khỏi <c>payload</c>.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IFacebookApiService.GetUserProfileAsync(System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Lấy tên và ảnh đại diện của một người dùng đã nhắn tin cho Page (tra theo PSID).
            <para>
            Facebook từ chối hồ sơ bằng <c>100/33</c> (thiếu Advanced Access của
            <c>Business Asset User Profile Access</c>, sổ nợ SC-23) thì lui về đọc tên người tham
            gia hội thoại — đường này chỉ cần <c>pages_messaging</c>, nhưng không có ảnh đại diện.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IFacebookApiService.GetRecentMessagesAsync(System.String,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Kéo tối đa 20 tin gần nhất của hội thoại Messenger giữa Page và một khách
            (<c>GET /me/conversations?platform=messenger&amp;user_id={PSID}&amp;fields=messages…</c>).
            <para>
            Cùng endpoint mà đường dự phòng đọc tên khách (SC-23) đã gọi được bằng Page token hiện có
            (đo 2026-10-23), chỉ xin thêm trường <c>messages</c>. Tài liệu Conversations API ghi đòi
            <c>pages_manage_metadata</c> + <c>pages_read_engagement</c> + <c>pages_messaging</c> —
            thiếu quyền thì Facebook trả lỗi và lỗi ấy đi nguyên ra cho nhân viên.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IFacebookApiService.SubscribePageAsync(System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Đăng ký Page với App để webhook của Page bắt đầu chảy về
            (<c>POST /{page-id}/subscribed_apps</c>, sổ nợ SC-20).
            <para>
            Hai tầng đăng ký là HAI việc khác nhau và cần cả hai: subscription cấp App
            (<c>/{app-id}/subscriptions</c>, khai một lần trên cổng/Graph API) và bước này cho
            TỪNG Page. Thiếu bước này thì webhook im lặng tuyệt đối — không đến thì không có gì
            để ghi nhật ký. E3 đã phải làm tay hai lần, mỗi Page một lần.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IFacebookApiService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.HttpClientName">
            <summary>Tên HttpClient đã đăng ký ở <c>DependencyRegister</c></summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.GraphVersion">
            <summary>
            Phiên bản Graph API cố định trong mã nguồn. Meta gỡ từng phiên bản sau khoảng hai năm,
            nên đây là thứ phải rà lại định kỳ — ghim số ở một chỗ để lúc nâng chỉ sửa một dòng.
            v25.0 là phiên bản tài liệu ngày 2026-08-27 đang dùng trong mọi ví dụ.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.DialogBase">
            <summary>
            Hộp thoại cấp quyền nằm ở <c>www.facebook.com</c> chứ không phải <c>graph.facebook.com</c> —
            đây là trang người dùng nhìn thấy, không phải endpoint API.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.LoginScopes">
            <summary>
            Bộ quyền xin khi KHÔNG khai <c>LoginConfigId</c>. Giữ đúng bốn quyền mà luồng kết nối
            kênh thật sự dùng, không xin thừa: <c>pages_show_list</c> để liệt kê Page,
            <c>pages_messaging</c> để nhắn tin, <c>pages_manage_metadata</c> để đăng ký webhook, và
            <c>business_management</c> vì Page nằm trong Business Portfolio sẽ KHÔNG hiện trong
            <c>/me/accounts</c> nếu thiếu nó — đo được bằng loại trừ ngày 2026-08-27 (sổ nợ SC-22).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.MaxTextLength">
            <summary>Giới hạn tài liệu ghi cho nội dung tin nhắn văn bản của Send API</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.MaxImageBytes">
            <summary>
            Trần dung lượng ảnh tải lên. Trùng đúng trần của <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAttachmentService.MaxImageBytes"/>
            vì đó là nguồn DUY NHẤT sinh ra tệp đi qua đây — đặt rộng hơn chỉ tạo ra một con số
            không ai kiểm được. Facebook cho phép lớn hơn; muốn nới thì nới ở đầu vào, không nới ở đây.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.AppSecret">
            <summary>
            Khoá bí mật của ứng dụng Facebook. Đây <b>vừa</b> là khoá ký webhook
            (<c>X-Hub-Signature-256</c>) <b>vừa</b> là <c>client_secret</c> của luồng đổi token —
            khác Zalo, nơi hai việc đó dùng hai khoá khác nhau.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.RedirectUri">
            <summary>
            Đường dẫn công khai Facebook chuyển hướng về sau khi quản trị viên cấp quyền. Phải
            TRÙNG KHÍT chuỗi đã khai ở <i>Valid OAuth Redirect URIs</i> trên cổng nhà phát triển —
            lệch một dấu gạch chéo là Facebook từ chối cả lần dựng hộp thoại lẫn lần đổi token,
            và cùng chuỗi đó phải được gửi lại ở bước đổi <c>code</c> (bẫy Zalo đã cắn một lần).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.LoginConfigId">
            <summary>
            Mã cấu hình đăng nhập của Facebook Login for Business (App Dashboard → Facebook Login
            for Business → Configurations). Để trống thì lui về Facebook Login thường với
            <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.LoginScopes"/>; cả hai đều chạy, nhưng bản có <c>config_id</c> mới là thứ
            hồ sơ App Review đòi quay trong screencast.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.BuildAuthorizationLink(System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.ExchangeCodeAsync(System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.ExchangeLongLivedUserTokenAsync(System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.GetManagedPagesAsync(System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.SendTextAsync(System.String,System.String,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.SendImageAsync(System.String,System.String,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.SendReactionAsync(System.String,System.String,System.String,System.String,System.String,System.Boolean,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.SubscribedFields">
            <summary>
            Các field mà parser đang có nhánh xử lý. KHÔNG thêm field nào vào đây khi parser chưa có
            nhánh (nguyên tắc F1-1 của plan): bật là tin thật chảy vào, và một nhánh Ignore mới chỉ
            đổi chỗ vấn đề. Muốn thêm <c>message_reads</c> (SC-3) thì bật ở CẢ subscription cấp App
            rồi mới thêm vào đây, và đo lưu lượng thật trước khi lật <c>SupportsReadReceipt</c>.
            <para>
            🔴 <b>Đăng ký webhook Facebook có HAI TẦNG, và tầng dưới nằm ở đúng dòng này.</b> Tầng
            trên là subscription cấp App (tick trên cổng nhà phát triển); tầng dưới là
            <c>subscribed_fields</c> của từng Page — do <b>code</b> đặt, không phải do cổng. Tick
            trên cổng mà quên dòng này thì Facebook không gửi field đó về, và không có thao tác nào
            trên cổng sửa được. Đây chính là bẫy đã cắn với <c>message_reactions</c> ở GĐ G: parser
            có nhánh, cổng đã tick, mà chuỗi này vẫn còn ba field cũ.
            </para>
            <para>
            <b>Thứ tự bắt buộc khi thêm field:</b> bật ở subscription cấp App TRƯỚC, rồi mới deploy
            code này. Làm ngược thì Graph có thể từ chối cả lời gọi <c>subscribed_apps</c> và mọi
            lần kết nối Page mới đều báo "chưa đăng ký được webhook". Và sau khi deploy, các Page
            <b>đang chạy vẫn giữ bộ field cũ</b> — hàm này chỉ chạy lúc kết nối hoặc lúc bấm "Đăng
            ký lại webhook", nên phải bấm lại cho từng kênh Facebook.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.SubscribePageAsync(System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.UploadImageAsync(System.String,System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.ResolveImageMediaType(System.String)">
            <summary>
            Kiểu MIME suy từ đuôi tệp. Tệp đi qua đây đã được <c>ChatAttachmentService</c> nhận diện
            bằng chữ ký nội dung rồi đặt lại đuôi, nên đuôi ở đây là do máy chủ sinh chứ không phải
            do người dùng khai.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.GetUserProfileAsync(System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.ProfileDeniedCode">
            <summary>
            Mã lỗi Facebook trả cho <c>GET /{PSID}</c> khi App chưa có Advanced Access của
            <c>Business Asset User Profile Access</c>: "Object ... does not exist, cannot be loaded
            due to missing permissions". Đây là tín hiệu DUY NHẤT bật đường dự phòng.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.ProfileDeniedSubCode">
            <inheritdoc cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.ProfileDeniedCode"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.GetNameFromConversationAsync(System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Đọc tên khách từ danh sách người tham gia hội thoại Messenger của Page
            (<c>GET /me/conversations?platform=messenger&amp;user_id={PSID}&amp;fields=participants{id,name}</c>).
            <para>
            Đường này chỉ cần <c>pages_messaging</c> — quyền kênh đã có sẵn để nhắn tin — nên chạy
            được ngay khi App Review chưa nộp. Đo 2026-10-23 trên Page LADA Express: khách thật bị
            <c>100/33</c> ở <c>GET /{PSID}</c> vẫn ra đúng tên ở đây, 1 hội thoại, 700-765 ms.
            Không có ảnh đại diện: <c>participants</c> chỉ mang <c>id</c>, <c>name</c>, <c>email</c>.
            </para>
            <para>
            Đi bằng <c>/me</c> thay vì <c>/{page-id}</c>: với Page access token thì <c>/me</c> CHÍNH
            là Page (thử trên Graph API Explorer 2026-10-23 — cùng kết quả với <c>/{page-id}</c>).
            Lợi hơn hẳn việc truyền page id vào: Page được suy ra từ chính token nên không thể lệch
            token, và chữ ký hàm cùng <c>IPlatformMessenger</c> giữ nguyên.
            </para>
            <para>
            Danh sách người tham gia có CẢ chính Page (cùng <c>name</c> "LADA Express"), nên phải lọc
            đúng <c>id == PSID</c> — lấy phần tử đầu là ghi tên Page vào hội thoại của khách.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.GetJsonAsync(System.String,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Gọi một API đọc của Graph API và trả về phần tử gốc của JSON.
            Trả kèm mô tả lỗi tiếng Việt để luồng kết nối Page nói được lý do cho quản trị viên.
            <para>
            Token đi ở header <c>Authorization</c>, KHÔNG ở tham số <c>access_token</c> trên query
            string — dù tài liệu Facebook dùng cách thứ hai trong mọi ví dụ. Lý do: đường dẫn
            request bị ghi vào nhật ký ở mức Information bởi chính <c>IHttpClientFactory</c>
            (danh mục <c>System.Net.Http.HttpClient.*</c>), mà cấu hình của repo để
            <c>Logging:LogLevel:Default = Information</c> — nghĩa là token sẽ nằm nguyên văn trong
            tệp log. Page access token thì KHÔNG có hạn dùng, nên một dòng log là một chìa khoá vĩnh viễn.
            </para>
            <para>
            <c>Failure</c> là cặp mã Facebook trả về, <c>null</c> khi lời gọi không tới được
            Facebook (quá hạn chờ, lỗi mạng, phản hồi không đọc được) — hai trường hợp phải tách
            được nhau để đường dự phòng của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.GetUserProfileAsync(System.String,System.String,System.Threading.CancellationToken)"/> chỉ chạy khi bị TỪ CHỐI.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookApiService.TryReadError(System.Text.Json.JsonElement,System.ValueTuple{System.Int32,System.Int32,System.String}@)">
            <summary>
            Đọc khối <c>error</c> của Graph API. Mọi lỗi của Facebook đều về dưới hình dạng này,
            kể cả khi mã HTTP là 200.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookAuthorizationLink">
            <summary>
            Đường dẫn hộp thoại cấp quyền Facebook, kèm những gì giao diện cần nói cho quản trị viên.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookAuthorizationLink.Success">
            <summary>Dựng được đường dẫn hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookAuthorizationLink.Url">
            <summary>Đường dẫn để mở trong cửa sổ mới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookAuthorizationLink.Message">
            <summary>Lý do đọc được cho quản trị viên khi dựng không được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookAuthorizationLink.RedirectUri">
            <summary>Chuỗi redirect đang dùng — để đối chiếu với ô khai trên cổng nhà phát triển</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookAuthorizationLink.State">
            <summary>
            Chuỗi <c>state</c> đã ký của lần cấp quyền này. Giao diện phải giữ lại để hỏi danh
            sách Page sau khi cửa sổ đóng — đây là thứ thay cho việc cầm token trong trình duyệt.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookAuthorizationLink.UsesBusinessLogin">
            <summary>
            <c>true</c> khi đi bằng <c>config_id</c> (Facebook Login for Business),
            <c>false</c> khi lui về Facebook Login thường với <c>scope</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookAuthorizationLink.Scopes">
            <summary>Danh sách quyền đang xin; chỉ có giá trị khi KHÔNG dùng <c>config_id</c></summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookTokenResult">
            <summary>Token Facebook trả về sau khi đổi bản dài hạn.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookTokenResult.ExpiredAt">
            <summary>Hạn dùng; <c>null</c> nghĩa là token không hết hạn (Page token dài hạn).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookPage">
            <summary>Một Page mà tài khoản đang quản lý.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookPage.AccessToken">
            <summary>Page access token — BÍ MẬT, không bao giờ đi ra khỏi tầng service.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookPagesResult">
            <summary>Kết quả một lần hỏi danh sách Page.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookSendResult">
            <summary>Kết quả một lần gửi tin.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookSubscribeResult">
            <summary>Kết quả đăng ký Page với App (<c>subscribed_apps</c>, SC-20).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookUploadResult">
            <summary>Kết quả tải ảnh lên máy chủ Facebook.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookUserProfile">
            <summary>Hồ sơ rút gọn của một người dùng Messenger.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookErrorCatalog">
            <summary>
            Dịch mã lỗi của Facebook Graph API ra tiếng người.
            <para>
            Nội dung lấy từ tài liệu "Error Codes" và "Send API" đọc ngày 2026-08-27. Chỉ giữ những mã
            một nhân viên chăm sóc khách hàng có thể gặp — mã lạ thì trả nguyên văn thông điệp của
            Facebook kèm số hiệu, tuyệt đối không nuốt.
            </para>
            <para>
            Khác Zalo, Facebook phân biệt bằng CẶP mã chính + mã phụ: cùng mã 10 nhưng mã phụ khác nhau
            là hai nguyên nhân hoàn toàn khác. Tra cặp trước, rồi mới lùi về mã chính.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookErrorCatalog.Describe(System.Int32,System.Int32,System.String)">
            <summary>
            Trả về mô tả tiếng Việt của một mã lỗi Facebook, kèm số hiệu để tra cứu lại tài liệu.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookHistoryReader">
            <summary>
            Đọc phản hồi của API hội thoại Messenger
            (<c>GET /me/conversations?platform=messenger&amp;user_id={PSID}&amp;fields=messages…</c>) thành
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage"/> — cùng kiểu với tin đi qua webhook, để lõi đối chiếu được hai
            nguồn với nhau.
            <para>
            Hình dạng tin ở đây KHÁC hẳn webhook, đừng chép logic bên <c>FacebookWebhookParser</c> sang:
            nội dung chữ nằm ở <c>message</c> (webhook là <c>message.text</c>), tệp đính kèm mang
            <c>mime_type</c> + <c>image_data.url</c> / <c>video_data.url</c> / <c>file_url</c> (webhook là
            <c>type</c> + <c>payload.url</c>), nhãn dán là một trường chuỗi <c>sticker</c> riêng, thời gian
            là chuỗi <c>created_time</c> dạng <c>2026-10-19T08:01:23+0000</c> (webhook là số mili giây).
            </para>
            <para>
            Vai không đảo như webhook: tin nào <c>from.id</c> là khách thì là tin vào, còn lại là tin
            Page gửi ra.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookHistoryReader.MessageFields">
            <summary>
            Trường xin Graph API. Chỉ xin những trường đã có trong tài liệu Message / Message Attachment —
            một trường sai tên là Facebook từ chối CẢ lời gọi (lỗi 100), không phải bỏ qua trường đó.
            <para>
            <c>limit(20)</c> vì Facebook chỉ trả chi tiết của 20 tin gần nhất mỗi hội thoại; tin cũ hơn
            trả về là lỗi "message has been deleted" (Conversations API, đọc 2026-10-24).
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookHistoryReader.NoticePrefixes">
            <summary>
            Dòng HỆ THỐNG của hộp thư Meta Business Suite mà API hội thoại trả về lẫn như tin thường.
            <para>
            Đo trên Page LADA Express 2026-10-24: chúng mang đúng <c>from</c>, <c>to</c> và <c>tags</c>
            (<c>inbox,read,sent,source:web</c>) như một tin nhân viên gõ tay — không trường nào phân biệt
            được, chỉ có câu chữ. Khách chưa bao giờ nhận những dòng này; chèn vào là khung chat hiện
            "ngoài LADA" cho một câu không ai gửi, và dòng nhãn tự động còn đè luôn dòng xem trước của
            hội thoại (đã xảy ra ở lượt nghiệm thu đầu, hội thoại 902).
            </para>
            <para>
            Câu chữ theo ngôn ngữ của Page. Thêm biến thể mới khi gặp — để lọt chỉ là một bong bóng thừa,
            còn lọc nhầm một tin thật thì không ai biết mà tìm lại.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookHistoryReader.PostReplyNotice">
            <summary>
            Phía KHÁCH: "&lt;tên&gt; đã trả lời về một bài viết. Xem bài viết(https://…)" — dấu vết khách trả lời
            một bài viết của Trang, không phải câu khách gõ (đo được 2 lần).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookHistoryReader.Parse(System.Text.Json.JsonElement,System.String,System.String)">
            <summary>
            Đọc toàn bộ tin trong phản hồi, xếp từ cũ tới mới.
            </summary>
            <param name="root">Gốc JSON của phản hồi Graph API</param>
            <param name="pageId">Page của kênh — ghi vào <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.ExternalChannelId"/></param>
            <param name="psid">Khách của hội thoại — tin có <c>from.id</c> trùng mã này là tin vào</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookHistoryReader.IsPlatformNotice(System.String)">
            <summary>Câu này có phải dòng hệ thống của hộp thư chứ không phải tin ai đó gửi không</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookHistoryReader.ResolveKind(System.String,System.String,System.Text.Json.JsonElement)">
            <summary>
            Loại nội dung và đường dẫn tệp. Không có gì đọc được (tin mẫu có nút bấm của công cụ tự động,
            tin chia sẻ bài viết…) thì ra <see cref="F:Lada.Framework.Data.Enums.ChatContentType.Other"/> rỗng — lõi bỏ qua loại đó
            thay vì chèn một bong bóng trống.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.FacebookHistoryReader.ParseTime(System.String)">
            <summary>
            Graph API trả <c>created_time</c> kiểu <c>2026-10-19T08:01:23+0000</c> — độ lệch múi giờ
            KHÔNG có dấu hai chấm, dạng mà <c>DateTimeOffset.TryParse</c> không chắc nhận. Chèn dấu hai
            chấm trước rồi mới đọc. Đổi về giờ máy chủ cho cùng quy ước với webhook.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatRealtimeNotifier">
            <summary>
            Kênh đẩy sự kiện chat về giao diện quản trị theo thời gian thực.
            <para>
            Giai đoạn A đăng ký bản rỗng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.NoOpChatRealtimeNotifier"/> để lõi chat gọi được ngay;
            giai đoạn C chỉ thay bản hiện thực bằng SignalR, KHÔNG sửa tầng service.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatRealtimeNotifier.ConversationUpdatedAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation)">
            <summary>Một hội thoại vừa thay đổi (tin mới, đổi trạng thái, đổi số tin chưa đọc)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatRealtimeNotifier.MessageReceivedAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Lada.Framework.Data.Domains.SocialChat.ChatMessage)">
            <summary>Có tin nhắn mới trong hội thoại</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatRealtimeNotifier.DeliveryUpdatedAsync(Lada.Framework.Data.Domains.SocialChat.ChatMessage)">
            <summary>Trạng thái giao nhận của một tin gửi đi vừa đổi</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatRealtimeNotifier.ScopeChangedAsync(System.Int32)">
            <summary>
            Phạm vi xem của một người vừa đổi — <b>thu hồi</b> những phòng realtime họ không còn
            được ở, và cho vào những phòng vừa mở ra.
            <para>
            Hàng rào REST chặn ngay lần gọi kế tiếp, nhưng một kết nối SignalR đã mở thì ở lại trong
            nhóm cho tới khi đóng tab. Không có bước thu hồi này thì người vừa bị chuyển hội thoại
            đi vẫn nhận nguyên văn tin của khách theo thời gian thực — chặn cửa trước, mở cửa sau
            (finding F-3).
            </para>
            </summary>
            <param name="userId">Người có phạm vi vừa đổi</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatRealtimeNotifier.ChannelScopeChangedAsync(System.Int32)">
            <summary>
            Phạm vi của cả một kênh vừa đổi — dùng khi bật/tắt hàng rào phân phối, vì thao tác ấy
            đổi phạm vi của <b>mọi</b> người cùng lúc chứ không của riêng ai.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.NoOpChatRealtimeNotifier">
            <summary>
            Bản rỗng dùng cho tới khi có <c>ChatHub</c> ở giai đoạn C. Không làm gì, không lỗi.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.FacebookMessenger">
            <summary>
            Bản cài đặt Facebook Messenger của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger"/>.
            <para>
            Cố ý mỏng như <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.ZaloMessenger"/>: chỉ giải mã token của kênh rồi chuyển tiếp sang
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IFacebookApiService"/>. Mọi hiểu biết về Graph API nằm ở đó, mọi hiểu biết về
            hội thoại nằm ở <c>SocialChatService</c>. Lớp này ra đời mà lõi không đổi một dòng nào —
            đó chính là phép thử mà cả đợt này dựng lên để kiểm.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.FacebookMessenger.ProfileLookupTimeout">
            <summary>
            Hạn chờ khi hỏi hồ sơ người dùng — ngân sách CHUNG cho cả lời gọi hồ sơ lẫn đường dự
            phòng đọc tên qua hội thoại (sổ nợ SC-23) nối đuôi nó.
            <para>
            Hàm này chạy trên đường webhook, và controller chỉ trả 200 sau khi xử lý xong. Hạn của
            Facebook là <b>5 giây</b> (Messenger Platform → Webhooks, đọc 2026-10-23: "respond to all
            notifications with a 200 OK HTTPS response within 5 or less seconds"); hỏng thì Meta gửi
            lại, hỏng liên tục một giờ thì App bị gỡ đăng ký webhook khỏi Page. Mức 2 giây là của
            Zalo, không phải của Facebook.
            </para>
            <para>
            Đo 2026-10-23: <c>100/33</c> về sau ~300 ms, hội thoại thêm 700-765 ms — cộng lại sát
            mức 1,2 giây cũ, tức đường dự phòng sẽ bị cắt thường xuyên. 2,5 giây là gấp đôi số đo
            và vẫn chừa một nửa hạn của Meta cho phần ghi tin + đẩy SignalR. Không gọi hội thoại
            TRƯỚC để gọn một lời gọi, vì làm thế thì App Review có duyệt cũng không bao giờ lấy lại
            được ảnh đại diện.
            </para>
            <para>
            Cái giá chỉ trả khi hội thoại chưa có tên — lõi bỏ qua bước này khi đã có tên — nên
            thực tế mỗi khách tốn một lần ở tin đầu. Chỗ còn hở: một gói webhook gom nhiều khách
            MỚI cùng lúc mà Facebook lại treo thì các lượt cộng dồn; trùng tin khi Meta gửi lại đã
            được chặn theo mã tin.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.FacebookMessenger.HistoryFetchTimeout">
            <summary>
            Hạn chờ khi kéo lịch sử hội thoại. Rộng hơn hẳn hạn hỏi hồ sơ vì lời gọi này KHÔNG chạy
            trên đường webhook — nó chạy trong job <c>chat-history-sync</c> hoặc khi nhân viên bấm nút
            đồng bộ, nơi không có hạn 5 giây của Meta. 20 tin kèm tệp đính kèm nặng hơn một dòng tên.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.FacebookMessenger.ReplyWindow">
            <summary>
            Facebook cho trả lời tự do trong <b>24 giờ</b> kể từ tương tác cuối của khách — bằng nửa
            cửa sổ của Zalo. Ngoài khung này Facebook đòi message tag (sổ nợ SC-2) và trả lỗi
            10/2018278; lỗi ấy được lưu vào tin và hiện nguyên văn cho nhân viên.
            <para>
            Đây là chỗ DUY NHẤT trong hệ thống khai con số 24 giờ: lõi lấy nó ra để tính "còn bao
            nhiêu giờ", giao diện chỉ diễn đạt lại. Không có một số 24 nào viết cứng ở frontend.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.FacebookMessenger.SupportsReadReceipt">
            <summary>
            <b>Trả <c>false</c>, dù Facebook CÓ webhook <c>message_reads</c>.</b> Không phải vì nền
            tảng thiếu tín hiệu, mà vì tín hiệu ấy chưa đi hết được đường ống:
            <para>
            Facebook báo "đã xem" bằng một MỐC THỜI GIAN (<c>read.watermark</c> — mọi tin gửi trước
            mốc này đã được xem), trong khi hợp đồng chuẩn hoá của lõi
            (<c>DeliveryStatusUpdate</c>) mang đúng một mã tin cho một lần cập nhật. Diễn đạt được
            mốc thời gian là phải mở rộng lõi, mà giai đoạn E cố ý không sửa lõi — nên
            <c>FacebookWebhookParser</c> bỏ qua sự kiện đó, và ở đây phải nói thật rằng mức "đã xem"
            sẽ không bao giờ tới.
            </para>
            <para>
            Đây đúng nguyên tắc §6.9: giao diện không được hứa hẹn một dấu hiệu chết, vì nhân viên
            sẽ diễn giải nó thành "khách chưa đọc" rồi ngồi chờ. Mở lại là việc của sổ nợ SC-3 —
            và khi làm thì phải đo trên lưu lượng Facebook THẬT trước, đúng bài học SC-8 của Zalo:
            một sự kiện có trong tài liệu không có nghĩa là nền tảng thật sự gửi nó.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.FacebookMessenger.SupportsQuotedReply(Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient)">
            <summary>
            Send API nhận <c>reply_to.mid</c> ở cấp gốc thân request, và tài liệu nói rõ trích dẫn
            được <b>cả</b> tin của khách lẫn tin của Page. Messenger không có khái niệm khách ẩn
            danh nên câu trả lời không phụ thuộc người nhận.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.FacebookMessenger.SupportsReaction(Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient)">
            <inheritdoc />
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.FacebookMessenger.ReactionEmojis">
            <summary>
            <b>Mảng rỗng — Facebook không giới hạn.</b> Tài liệu Sender Actions nhận thẳng ký tự
            emoji ở <c>payload.reaction</c> chứ không phải một tập mã như Zalo, nên giao diện được
            phép cho chọn biểu tượng bất kỳ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.FacebookMessenger.SendReactionAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient,System.String,System.String,System.Boolean)">
            <summary>
            Thả hoặc gỡ biểu tượng cảm xúc qua <c>sender_action</c> của chính Send API.
            <para>
            🔴 <b>Chưa đo bằng lưu lượng thật.</b> Bằng chứng đến từ trang hướng dẫn Sender Actions
            (đọc 2026-08-28, xác minh trên hai đường dẫn tài liệu độc lập), không phải từ một lần
            gọi thật. Và câu hỏi "Page tự thả thì có webhook về không" thì tài liệu im lặng — nghĩa
            là sau khi gọi thành công, LADA vẫn phải tự ghi nhớ cảm xúc mình vừa thả chứ không chờ
            nền tảng xác nhận. Đúng hình dạng bẫy SC-25 đã cắn một lần.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.FacebookMessenger.SendImageAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient,System.String,System.String,System.String)">
            <summary>
            Gửi ảnh, và nếu có chú thích thì gửi tiếp một tin văn bản riêng.
            <para>
            Lý do phải tách làm hai: một tin Messenger mang <b>hoặc</b> <c>text</c> <b>hoặc</b>
            <c>attachment</c>, không mang cả hai — khác Zalo, nơi chú thích đi kèm ngay trong tin ảnh.
            Khung chat của LADA lưu chú thích vào nội dung tin, nên bỏ qua nó là nhân viên tưởng
            khách đã đọc một câu chưa bao giờ được gửi đi.
            </para>
            <para>
            Ảnh gửi trước để mã tin trả về là mã của ảnh — đó là tin mang phần nội dung chính, và
            trạng thái giao nhận bám theo nó. Chú thích gửi hụt thì cả tin bị đánh
            <c>Failed</c> kèm lý do: thà nhân viên gửi lại còn hơn tưởng khách đã đọc.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.FacebookMessenger.SupportsHistorySync">
            <summary>
            Bật vì có một loại tin mà webhook không chở tới: tin Page trả lời riêng từ bình luận
            (private reply) đi ra TRƯỚC khi khách mở Messenger, và Facebook không cam kết bắn
            <c>message_echoes</c> cho nó. Khách trả lời bằng số điện thoại thì khung chat LADA chỉ có
            con số, mất câu hỏi đứng trước — trong khi hộp thư Meta Business Suite có đủ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.FacebookMessenger.ReadAccessToken(Lada.Framework.Data.Domains.SocialChat.ChatChannel)">
            <summary>
            Giải mã Page access token của kênh, hoặc trả về lý do đọc tiếng Việt nếu không dùng được.
            Không bao giờ đưa giá trị token vào thông điệp lỗi hay nhật ký.
            <para>
            Khác Zalo ở một điểm: Page access token lấy từ user token dài hạn <b>không có hạn dùng</b>,
            nên <c>TokenExpiredAt</c> của kênh Facebook thường là rỗng và nhánh kiểm hạn dưới đây
            không chạy. Vẫn giữ nhánh đó vì token vẫn có thể bị thu hồi (đổi mật khẩu, gỡ ứng dụng,
            đổi quyền Page) — lúc đó Facebook trả lỗi 190 và nhân viên đọc được lý do thật.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.SendResult">
            <summary>
            Kết quả một lần gửi tin ra nền tảng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.SendResult.Success">
            <summary>Nền tảng đã nhận tin hay chưa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.SendResult.ExternalMessageId">
            <summary>Định danh tin nhắn nền tảng trả về, dùng để đối chiếu trạng thái giao nhận sau này</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.SendResult.Error">
            <summary>Mô tả lỗi khi gửi thất bại — hiển thị cho nhân viên, không chứa token</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.SendResult.Ok(System.String)">
            <summary>Gửi thành công</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.SendResult.Fail(System.String)">
            <summary>Gửi thất bại</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformUserProfile">
            <summary>
            Hồ sơ rút gọn của một người dùng trên nền tảng, đã chuẩn hoá về dạng lõi chat hiểu được.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformUserProfile.DisplayName">
            <summary>Tên hiển thị của khách trên nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformUserProfile.AvatarUrl">
            <summary>Ảnh đại diện</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformHistoryResult">
            <summary>
            Kết quả một lần kéo các tin gần nhất của hội thoại từ nền tảng về.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformHistoryResult.Success">
            <summary>Nền tảng trả lời được hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformHistoryResult.Messages">
            <summary>
            Các tin nền tảng đang giữ, đã chuẩn hoá về dạng lõi hiểu — cùng kiểu với tin đi qua
            webhook để lõi đối chiếu được hai nguồn với nhau.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformHistoryResult.Error">
            <summary>Lý do đọc được khi thất bại — hiển thị cho nhân viên, không chứa token</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformHistoryResult.IsTransient">
            <summary>
            Lỗi tạm (mạng, quá hạn chờ, vượt hạn mức gọi): lượt sau thử lại có thể được. <c>false</c>
            với lỗi mà lượt sau vẫn y nguyên (thiếu quyền, token hỏng) — thử lại chỉ đốt hạn mức.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformHistoryResult.Ok(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage})">
            <summary>Kéo được</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformHistoryResult.Fail(System.String,System.Boolean)">
            <summary>Kéo không được</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient">
            <summary>
            Địa chỉ nhận tin trên nền tảng — thứ duy nhất tầng nền tảng cần biết về một hội thoại.
            <para>
            Sinh ra ở giai đoạn F1 vì tin nhắn ẩn danh của Zalo: API gửi cho người ẩn danh
            (<c>POST /v2.0/oa/message</c>) đòi CẢ HAI mã <c>anonymous_id</c> và <c>conversation_id</c>,
            trong khi hợp đồng cũ <c>SendTextAsync(channel, recipientId, text)</c> chỉ mang một. Đây là
            chỗ thứ hai trong cả đợt mà trừu tượng của giai đoạn A không phủ được (chỗ đầu là
            <c>watermark</c>, §6.11) — và lần này thì nới, vì SC-27 dù sao cũng buộc phải viết migration
            nên chi phí thật nhỏ hơn hẳn. Lý do đầy đủ ở §6.12 của kế hoạch.
            </para>
            <para>
            Truyền một địa chỉ chứ KHÔNG truyền cả <c>ChatConversation</c>: tầng nền tảng không có việc
            gì với khách hàng đã gắn hay nhân viên được phân công, và nền tảng thứ ba cần một mã thứ ba
            thì mở rộng lớp này chứ không đổi chữ ký giao diện lần nữa.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient.ExternalUserId">
            <summary>Định danh người dùng phía nền tảng (Zalo user id / PSID / anonymous_id)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient.ExternalConversationId">
            <summary>
            Định danh hội thoại phía nền tảng, chỉ có với nền tảng đòi hai mã. <c>null</c> với
            mọi hội thoại thường — bản cài đặt nào cần nó mà thấy <c>null</c> thì phải trả lỗi
            đọc được, đừng gửi đi một nửa địa chỉ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient.IsAnonymous">
            <summary>
            Người nhận là khách ẩn danh. Bản cài đặt dùng cờ này để chọn endpoint, thay vì đoán
            theo việc <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient.ExternalConversationId"/> có rỗng hay không.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient.From(Lada.Framework.Data.Domains.SocialChat.ChatConversation)">
            <summary>Lấy địa chỉ nhận tin từ một hội thoại.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger">
            <summary>
            Điểm mở rộng chiều GỬI TIN. Mỗi nền tảng hiện thực đúng một lớp này.
            Giai đoạn A chỉ định nghĩa giao diện; bản Zalo nằm ở giai đoạn B, bản Facebook ở giai đoạn E.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger.Platform">
            <summary>Nền tảng mà lớp này phụ trách</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger.ReplyWindow">
            <summary>
            Khoảng thời gian kể từ tin nhắn cuối của khách mà nền tảng còn cho phép trả lời tự do
            (Zalo 48 giờ, Facebook 24 giờ).
            <para>
            Đây là luật riêng của từng nền tảng nên nó nằm ở đây chứ không nằm trong lõi. Lõi chỉ
            lấy con số này để tính ra "còn bao nhiêu giờ" cho giao diện cảnh báo — và đó là
            CẢNH BÁO, không phải chốt chặn: quyết định cuối cùng thuộc về nền tảng, hết cửa sổ thì
            nó trả lỗi và lỗi ấy được lưu vào tin.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger.SupportsReadReceipt">
            <summary>
            Nền tảng có báo về việc khách đã XEM tin hay không.
            <para>
            Đây là câu trả lời cho một câu hỏi đã đo được chứ không phải một giả định:
            giai đoạn C đếm 53 request thật qua tunnel và không có sự kiện <c>user_seen_message</c>
            nào của Zalo (sự kiện duy nhất thuộc loại đó đến từ IPv6 dân dụng — chính là bản mô
            phỏng của giai đoạn B). Với nền tảng trả <c>false</c>, thang giao nhận dừng ở
            <c>Delivered</c> và giao diện KHÔNG được hứa hẹn một mức "đã xem" không bao giờ tới.
            </para>
            <para>
            Lưu ý cho ai kiểm lại: phân biệt sự kiện thật với sự kiện tự dựng bằng
            <c>X-Forwarded-For</c>, KHÔNG bằng <c>User-Agent</c> — chuỗi đó do bên gửi tự khai nên
            bản mô phỏng cũng mang đúng <c>ZaloWebhook</c>.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger.SupportsQuotedReply(Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient)">
            <summary>
            Nền tảng có nhận tham số trích dẫn khi gửi tin văn bản hay không.
            <para>
            Cùng khuôn với <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger.SupportsReadReceipt"/> và cùng lý do: giao diện phải biết được
            điều này để <b>ẩn</b> nút "Trả lời" ở nơi bấm vào cũng không gửi được, thay vì để nhân
            viên soạn xong một câu trả lời rồi mới nhận lỗi. Không có cờ này thì phía trình duyệt
            buộc phải viết <c>if (platform === …)</c> — đúng thứ mà ghi chú đầu <c>SocialChatService</c>
            cấm, vì nó rải kiến thức riêng của nền tảng ra khắp nơi.
            </para>
            <para>
            Đây là câu trả lời cho một câu hỏi đã tra tài liệu chứ không phải giả định (sổ nợ SC-33,
            tra ngày 2026-08-28): Zalo có <c>message.quote_message_id</c> ở tin tư vấn v3.0, Facebook
            có <c>reply_to.mid</c> ở Send API. <b>Riêng luồng ẩn danh của Zalo thì KHÔNG</b> — tài
            liệu endpoint v2.0 không có trường nào cho trích dẫn.
            </para>
            <para>
            Vì thế đây là một <b>hàm nhận người nhận</b> chứ không phải một thuộc tính: câu trả lời
            khác nhau giữa hai hội thoại của cùng một nền tảng. Để nó là thuộc tính thì cái điều
            kiện "trừ khách ẩn danh" sẽ phải nằm ở tầng dựng DTO — tức là kiến thức riêng của Zalo
            leo vào lõi, đúng thứ §6.12 đã cẩn thận đẩy xuống đây bằng <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient"/>.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger.SupportsReaction(Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient)">
            <summary>
            Nền tảng có cho phép LADA <b>thả</b> biểu tượng cảm xúc lên tin nhắn của người nhận này
            hay không. Cũng là hàm chứ không phải thuộc tính, cùng lý do với
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger.SupportsQuotedReply(Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient)"/>.
            <para>
            Tách hẳn khỏi việc nền tảng có <b>báo về</b> cảm xúc khách thả — hai chiều độc lập nhau,
            và chiều nhận đi bằng webhook nên không có cờ ở đây.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger.ReactionEmojis">
            <summary>
            Bộ biểu tượng cảm xúc mà nền tảng chấp nhận, theo đúng thứ tự hiển thị.
            <b>Mảng rỗng nghĩa là nền tảng không giới hạn</b> — giao diện được phép cho chọn biểu
            tượng bất kỳ.
            <para>
            Hai nền tảng khác nhau thật ở điểm này nên không gộp được: Zalo chỉ nhận sáu mã cố định
            và trả lỗi với mọi thứ ngoài bảng, còn Facebook nhận emoji tuỳ ý. Danh sách đi từ máy chủ
            ra giao diện chứ không để phía trình duyệt tự chép — hai bảng song song là hai bảng sẽ
            lệch, và cái lệch chỉ lộ ra khi nền tảng từ chối một biểu tượng đã bấm được.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger.SendTextAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient,System.String,System.String)">
            <summary>
            Gửi tin nhắn văn bản.
            <para>
            <paramref name="quotedExternalMessageId"/> là mã tin gốc <b>phía nền tảng</b> mà tin này
            trả lời trích dẫn, <c>null</c> với tin thường. Lõi đã tra mã này từ database theo cặp
            (hội thoại, tin) nên tầng nền tảng cứ dùng thẳng. Bản cài đặt của nền tảng không hỗ trợ
            trích dẫn phải <b>trả lỗi</b> chứ không được âm thầm bỏ tham số: nhân viên sẽ tưởng khách
            nhìn thấy ngữ cảnh mà thật ra không.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger.SendReactionAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient,System.String,System.String,System.Boolean)">
            <summary>
            Thả hoặc gỡ một biểu tượng cảm xúc lên một tin nhắn đã có.
            <para>
            <paramref name="targetExternalMessageId"/> là mã tin phía nền tảng; <paramref name="emoji"/>
            là ký tự emoji thật (bỏ qua khi <paramref name="isRemove"/> bật). Lõi luôn nói chuyện
            bằng emoji — việc đổi sang mã riêng của nền tảng là việc của bản cài đặt, vì mã ấy mà rò
            lên tới lõi là nó sẽ rò tiếp ra màn hình (bẫy SC-34).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger.SendImageAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient,System.String,System.String,System.String)">
            <summary>
            Gửi tin nhắn hình ảnh.
            <para>
            Nhận cả hai dạng vì mỗi nền tảng đòi một kiểu: Zalo phải tải tệp lên trước
            (<paramref name="localImagePath"/>), Facebook nhận thẳng đường dẫn công khai
            (<paramref name="publicUrl"/>). Bản hiện thực dùng cái nào hợp với nền tảng của mình
            và trả lỗi rõ ràng nếu thiếu.
            </para>
            <para>
            <paramref name="caption"/> là chú thích đi kèm ảnh. Bắt buộc có trong giao diện vì lõi
            chat lưu nó vào nội dung tin: khung chat hiện chú thích mà nền tảng không nhận được nó
            thì nhân viên tưởng khách đã đọc một câu chưa bao giờ được gửi đi.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger.TryGetUserProfileAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,System.String)">
            <summary>
            Lấy tên hiển thị và ảnh đại diện của một người dùng trên nền tảng.
            <para>
            Đây là đường PHỤ TRỢ, không phải đường nghiệp vụ: webhook của Zalo không gửi kèm tên
            khách nên hội thoại sinh ra từ webhook không có tên, và danh sách hội thoại sẽ là một
            cột trống nếu không hỏi lại nền tảng. Hỏng thì trả <c>null</c> chứ không ném — mất tên
            khách là khó chịu, mất tin nhắn mới là hỏng việc.
            </para>
            <para>
            Bản cài đặt phải TỰ đặt hạn chờ ngắn: hàm này được gọi trên đường xử lý webhook, mà
            Zalo đòi phản hồi trong 2 giây, quá hạn thì nó gửi lại và cuối cùng vô hiệu hoá webhook.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger.SupportsHistorySync">
            <summary>
            Nền tảng có cho kéo lại các tin gần nhất của một hội thoại hay không — để lõi bù những
            tin webhook không chở tới (tin Page trả lời riêng từ bình luận Facebook là ca gốc).
            <para>
            Có cài đặt mặc định <c>false</c> ngay trong giao diện: đây là năng lực THÊM, chỉ nền tảng
            nào đã đo được API lịch sử mới bật. Zalo có API hội thoại nhưng chưa ai đo nó trên OA thật.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger.FetchRecentMessagesAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient,System.Threading.CancellationToken)">
            <summary>
            Kéo các tin gần nhất của hội thoại với <paramref name="recipient"/> từ nền tảng về.
            <para>
            Chỉ ĐỌC — không gửi gì ra nền tảng. Không ném lỗi: mọi hỏng hóc đi ra bằng
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformHistoryResult.Error"/>, kèm cờ lỗi tạm để job biết có nên thử lại.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessengerResolver">
            <summary>
            Tìm bản gửi tin ứng với một nền tảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessengerResolver.Resolve(Lada.Framework.Data.Enums.SocialPlatform)">
            <summary>Lấy bản gửi tin của nền tảng, trả <c>null</c> nếu chưa nền tảng nào đăng ký</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformMessengerResolver">
            <summary>
            Gom mọi <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger"/> đã đăng ký DI thành một bảng tra theo nền tảng.
            Thêm nền tảng mới chỉ cần đăng ký thêm một <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger"/> — KHÔNG sửa lớp này.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.ZaloMessenger">
            <summary>
            Bản cài đặt Zalo của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger"/>.
            <para>
            Cố ý mỏng: chỉ giải mã token của kênh rồi chuyển tiếp sang <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IZaloApiService"/>.
            Mọi hiểu biết về giao thức Zalo nằm ở đó, mọi hiểu biết về hội thoại nằm ở
            <c>SocialChatService</c>. Thêm nền tảng mới là thêm một lớp như lớp này — không sửa lõi,
            không sửa resolver.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.ZaloMessenger.ProfileLookupTimeout">
            <summary>
            Hạn chờ khi hỏi hồ sơ người dùng. Ngắn hơn hẳn 2 giây Zalo cho phép webhook phản hồi,
            để phần còn lại của việc xử lý tin vẫn kịp.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.ZaloMessenger.ReplyWindow">
            <summary>
            Zalo cho trả lời tự do trong 48 giờ kể từ tương tác cuối của khách. Ngoài khung này tin
            trừ vào hạn mức của gói OA (LADA đang dùng gói Nâng cao, 2.000 tin/tháng) và Zalo trả
            mã lỗi -232 khi không còn gửi được.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.ZaloMessenger.SupportsReadReceipt">
            <summary>
            <b>Zalo KHÔNG báo khách đã xem tin.</b> Sự kiện <c>user_seen_message</c> có trong tài
            liệu và đã được bật trên cổng, nhưng đo thật ở giai đoạn C thì trong 53 request qua
            tunnel không có lấy một sự kiện nào của Zalo thuộc loại đó — cái duy nhất thấy được là
            bản mô phỏng do chính giai đoạn B gửi (nhận ra bằng <c>X-Forwarded-For</c>, không phải
            bằng <c>User-Agent</c>).
            <para>
            Vì thế thang trạng thái của kênh Zalo dừng ở "Đã nhận". Trả <c>false</c> ở đây là để
            giao diện nói thẳng điều đó với nhân viên, thay vì để họ chờ một dấu hiệu chết.
            Nếu về sau Zalo bật lại sự kiện này thì chỉ cần đổi đúng dòng dưới — đường xử lý
            <c>user_seen_message</c> phía sau vẫn còn nguyên và đã được kiểm chứng chạy đúng.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.ZaloMessenger.SupportsQuotedReply(Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient)">
            <summary>
            Zalo nhận trích dẫn ở tin tư vấn thường (<c>message.quote_message_id</c>, tài liệu
            "Gửi tin tư vấn trích dẫn" đọc 2026-08-28) nhưng <b>không</b> ở luồng ẩn danh: endpoint
            v2.0 dành cho khách widget web không có trường nào cho việc này. Trả <c>false</c> cho
            khách ẩn danh để giao diện ẩn hẳn nút, thay vì để nhân viên soạn xong rồi mới nhận lỗi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.ZaloMessenger.SupportsReaction(Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient)">
            <summary>
            Cùng ranh giới với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.ZaloMessenger.SupportsQuotedReply(Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient)"/>: API thả cảm xúc nhận
            <c>recipient.user_id</c>, mà khách ẩn danh không có mã ấy — họ chỉ có cặp
            (<c>anonymous_id</c>, <c>conversation_id</c>).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.ZaloMessenger.ReactionEmojis">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.ZaloMessenger.ReadAccessToken(Lada.Framework.Data.Domains.SocialChat.ChatChannel)">
            <summary>
            Giải mã access token của kênh, hoặc trả về lý do đọc tiếng Việt nếu không dùng được.
            Không bao giờ đưa giá trị token vào thông điệp lỗi hay nhật ký.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.PlatformContactField">
            <summary>
            Chỗ DUY NHẤT trong phân hệ biết nền tảng nào ứng với trường liên hệ nào trên hồ sơ khách hàng.
            <para>
            Hồ sơ khách hàng có sẵn hai cột văn bản tự do <c>ZaloContact</c> và <c>FacebookContact</c>
            từ trước đợt này, nên gắn hội thoại không cần thêm cột nào. Nhưng "Zalo thì ghi vào
            ZaloContact" là kiến thức về nền tảng, mà lõi chat cố ý không được biết điều đó — nên nó
            nằm ở đây, tách hẳn ra, thay vì thành một <c>switch</c> giữa <c>SocialChatService</c>.
            Thêm nền tảng mới thì thêm một nhánh ở đây; lõi không đổi một dòng nào.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.PlatformContactField.MaxLength">
            <summary>Độ dài tối đa của hai cột liên hệ trên hồ sơ khách hàng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.PlatformContactField.Read(Lada.Framework.Data.Domains.Crm.Customer,Lada.Framework.Data.Enums.SocialPlatform)">
            <summary>Giá trị hiện có của trường liên hệ ứng với nền tảng</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.PlatformContactField.Append(Lada.Framework.Data.Domains.Crm.Customer,Lada.Framework.Data.Enums.SocialPlatform,System.String,System.String)">
            <summary>
            Ghi thêm một dấu vết liên hệ vào hồ sơ khách hàng, KHÔNG đè thứ đang có.
            <para>
            Cột này là văn bản tự do do người dùng nhập từ nhiều năm nay — đè lên là xoá dữ liệu
            của người khác. Đã có định danh nền tảng trong đó rồi thì không ghi lần hai.
            </para>
            </summary>
            <returns><c>true</c> khi có thay đổi thật sự cần lưu</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatAvailabilityProvider">
            <summary>
            Tiêu chí <c>chat.availability</c> — tỉ lệ phần trăm thời gian <b>giờ làm riêng</b> của từng
            sale ở trạng thái sẵn sàng.
            </summary>
            <remarks>
            <para>
            Nguồn duy nhất là <c>ChatAgentPresenceLog</c>, đúng như §3.2 đã ghi: *"không có bảng này thì
            tiêu chí đó là số bịa"*. Đo bằng <b>phút giờ làm</b> (<c>WorkingMinutesBetween</c>) ở cả tử số
            lẫn mẫu số — khác hẳn <c>chat.first-response</c>, và có lý do: ở đây câu hỏi là *"trong khoảng
            thời gian đáng lẽ bạn phải trực, bạn trực bao nhiêu"*, nên đơn vị bắt buộc phải là giờ làm.
            Ngoài giờ làm mà bật "Bận" thì không ai quan tâm.
            </para>
            <para>
            <b>"Giờ làm" ở đây là giờ RIÊNG người đó tự đặt (KC-18), không phải cấu hình chung.</b> Chủ dự
            án chốt ở §8.7 câu 1: mỗi người chỉ có <b>một</b> định nghĩa "đang trong ca", và nó vừa quyết
            định "Ngoài giờ", vừa dừng đồng hồ hạn phản hồi, vừa là mẫu số của tiêu chí này. Mẫu số theo
            cấu hình chung là thứ gây ra §7.9: production đặt <c>00:00–23:59</c> cả tuần để "nhận khách theo
            trạng thái" (§8.6), nên sale đặt "Nghỉ" từ tối tới sáng — đúng điều bài giảng muốn dạy — bị
            chấm như vắng mặt 15 giờ mỗi ngày và tỉ lệ rơi về khoảng 35–40 %. Chấm trên giờ của chính họ thì
            Nghỉ ngoài ca không trừ phút nào. Vì vậy lớp này <b>không đọc</b>
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityWindow.WorkingHours"/> — trường đó vẫn giữ cấu hình chung cho
            <c>chat.first-response</c> (điều cấm "không đổi bốn tiêu chí còn lại").
            </para>
            <para>
            <b>Người CHƯA đặt giờ làm thì chưa có mẫu</b> (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRawValue.KhongCoMau"/>) —
            kể cả khi họ có nhật ký trạng thái. Đây là lựa chọn "Bỏ tiêu chí 5" của chủ dự án ở §8.7 câu 2,
            và nó là lựa chọn duy nhất không bịa số: người chưa đặt mặc định "luôn trong ca"
            (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatWorkingHours.AlwaysOpen"/>), lấy đó làm mẫu số là quay lại đúng mẫu số 24 giờ của
            §7.9; lấy cấu hình chung làm mẫu số thì là chấm người ta trên một giờ làm họ chưa từng chọn — mà
            §8.7 câu 5 đã hạ cấu hình chung xuống thành "giờ gợi ý". Không mẫu thì <c>ChatQualityRules.Gop</c>
            loại tiêu chí khỏi cả tử lẫn tổng trọng số, nên điểm của người đó không bị kéo xuống. Giờ riêng
            <b>hỏng</b> cũng tính như chưa đặt (<see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatStaffWorkingHours.HasOwnWorkingHours"/>):
            chấm trên một giờ làm mà chính dữ liệu của nó đã sai là chấm trên cát.
            </para>
            <para>
            Giới hạn biết trước (plan phiên 4): giờ riêng không có lịch sử, nên cả cửa sổ 30 ngày được chấm
            bằng giờ <b>hiện tại</b> của người đó — cùng giới hạn cấu hình chung đã có từ trước.
            </para>
            <para>
            <b>Bảng rỗng KHÔNG phải là 100 % sẵn sàng.</b> Đây là quyết định đáng ghi vì cái sai ngược lại
            rất dễ viết ra: nhật ký chỉ sinh dòng khi ai đó <i>đổi</i> trạng thái, nên "không có dòng nào"
            đọc được theo hai nghĩa — sẵn sàng suốt, hoặc chưa ai từng dùng menu. Số đo C0-3 đã phân xử:
            chủ dự án trả lời *"Chưa ai — chưa có gì buộc họ"*, và F0-3 đo được bảng <b>0 dòng</b>. Nên
            không có dòng = <b>không đo được</b> (<c>Sample = 0</c>), chứ không phải 100 điểm. Cho 100 điểm
            vì thiếu dữ liệu là thưởng người không dùng hệ thống, và nó sẽ nâng điểm tổng của mọi sale bằng
            một tiêu chí không quan sát gì cả.
            </para>
            <para>
            Cỡ mẫu là <b>số ngày có ít nhất một dòng nhật ký</b>, không phải số dòng: một người bấm đổi
            trạng thái 20 lần trong một buổi không có nhiều dữ liệu hơn người bấm 2 lần trong 10 ngày.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatAvailabilityProvider.ProviderCode">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatAvailabilityProvider.GetAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityWindow)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatAvailabilityProvider.MocKetThucHieuLuc(System.Nullable{System.DateTimeOffset},System.Nullable{System.DateTimeOffset},System.DateTimeOffset)">
            <summary>
            Một khoảng trạng thái hết hiệu lực ở mốc <b>sớm hơn</b> giữa "lúc đóng dòng nhật ký" và
            "lúc hết hạn tự khai"; không có mốc nào thì kéo tới hết cửa sổ.
            </summary>
            <remarks>
            Tách thành hàm riêng để nó kiểm được bằng một bảng ca thuần, và để định nghĩa này nằm ở
            <b>một chỗ</b> — nó phải khớp với <c>ChatPresenceDurations.Build</c> của giai đoạn C, vốn
            dựng bảng thời lượng mà quản lý đọc trên <c>/trang-thai-sale</c>. Hai phép cắt lệch nhau là
            hai con số khác nhau cho cùng câu hỏi "người này bận bao lâu".
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatConversionProvider">
            <summary>
            Tiêu chí <c>chat.conversion</c> — tỉ lệ phần trăm hội thoại phát sinh đơn hàng trong 14 ngày.
            </summary>
            <remarks>
            <para>
            <b>Đường nối chat → đơn hàng CÓ tồn tại</b>, và F-0 đã kiểm trước khi viết dòng code đầu tiên
            đúng như prompt dặn: <c>ChatConversation.CustomerId</c> → <c>Order.CustomerId</c>, cộng
            <c>Order.CreatedTime</c> để kẹp cửa sổ 14 ngày. Không phải suy đoán — đã chạy thật trên dev.
            </para>
            <para>
            <b>Nhưng cỡ mẫu gần như bằng không, và lý do nằm ở một số đo cũ.</b> Chỉ <b>2/63</b> hội thoại
            trên dev có <c>CustomerId</c> (số đo Đ2: 3,17 %), cả hai trỏ về cùng một khách, và cả hai ra
            <b>0</b> đơn trong cửa sổ 14 ngày — dù khách ấy có 24 đơn, chúng nằm ngoài cửa sổ. Nên tiêu chí
            này là tiêu chí rỗng <b>thứ tư</b> trên năm, ngoài ba cái prompt đã cảnh báo.
            </para>
            <para>
            <b>Chỉ hội thoại ĐÃ GẮN KHÁCH mới vào mẫu.</b> Hội thoại chưa gắn khách không phải "không chốt
            được đơn" — nó là "không biết có chốt hay không", và hai thứ đó khác nhau. Đưa chúng vào mẫu
            với giá trị 0 là chấm điểm kém cho một sale vì hệ thống không quan sát được họ. Đây cũng là lý
            do câu gợi ý của tiêu chí nói thẳng *"gắn khách hàng vào hội thoại ngay khi biết họ là ai"* —
            tỉ lệ gắn khách 3,17 % tự nó là chỉ số §2.4 đã hẹn đưa vào báo cáo quản lý giai đoạn G.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatConversionProvider.SoNgayTinhChuyenDoi">
            <summary>Cửa sổ tính chuyển đổi kể từ lúc nhận hội thoại — 14 ngày, theo §3.6</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatConversionProvider.ProviderCode">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatConversionProvider.GetAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityWindow)">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatFirstResponseProvider">
            <summary>
            Tiêu chí <c>chat.first-response</c> — <b>trung vị</b> thời gian phản hồi lần đầu, tính bằng phút.
            </summary>
            <remarks>
            <para>
            <b>Đo đúng cách (c) của số đo Đ5</b> (§2.4), từng chi tiết một, và điều đó là bắt buộc chứ không
            phải tuỳ chọn: ngưỡng <c>Good = 2</c> / <c>Bad = 35</c> phút được suy ra từ chính phép đo ấy
            (trung vị 0,82′ và p90 35,40′ trên N = 206). Đo bằng một cách khác rồi áp ngưỡng của cách này là
            lỗi đắt nhất của giai đoạn E lặp lại — ở đó luật chấm từ <c>LastInboundAt</c> (tin cuối) trong
            khi ngưỡng suy từ tin <i>mở đầu</i> một lượt chờ, và *"con số ấy không còn nghĩa gì"*.
            </para>
            <para>
            Ba chi tiết của cách (c), và cả ba đều có mặt trong code dưới:
            </para>
            <list type="number">
            <item>
            <b>Chỉ tin inbound MỞ ĐẦU một lượt chờ</b> — tin liền trước nó không phải tin đến. Trong cách
            (a), một khách gửi 5 tin liên tiếp thì tin thứ 5 chỉ cách câu trả lời vài giây còn tin thứ 1
            gánh cả cụm, làm lệch cả hai đầu phân bố.
            </item>
            <item>
            <b>Chỉ tin đến trong giờ làm</b> — đúng tinh thần *"tin nhắn 2h sáng không được làm hỏng điểm
            của ai"*. Lọc theo giờ <b>đến</b> của tin khách, không lọc theo giờ trả lời.
            </item>
            <item>
            <b>Đo bằng đồng hồ thường, không bằng phút giờ làm.</b> Đây là chỗ tiêu chí này cố ý <b>khác</b>
            hạn phản hồi của giai đoạn E, nên phải nói rõ kẻo người sau tưởng là quên: giai đoạn E đếm phút
            giờ làm vì nó <i>thu hồi hội thoại</i>, còn ở đây mọi con số phải so được với Đ5 — mà Đ5 lấy hiệu
            hai mốc đồng hồ thường rồi mới lọc theo giờ tin đến. Đổi đơn vị đo là làm ngưỡng 2/35 mất căn cứ.
            Ghi thành nợ <b>PP-32</b>: lượt đo lại sau 2 tuần chạy thật (§2.4 đã hẹn) nên đo <b>cả hai
            cách</b> rồi chốt một.
            </item>
            </list>
            <para>
            <b>Và một lọc mà Đ5 không có: chỉ tin trả lời quy được về người.</b> Tin outbound không mang
            <c>SenderStaffId</c> là tin admin gõ thẳng trên ứng dụng Zalo OA / Facebook Page ngoài LADA —
            số đo E0-5 và F0-1 đều đo được <b>91,9 %</b> tin chiều ra thuộc loại đó. Không quy được về ai thì
            không tính cho ai (sổ nợ PP-13). Hệ quả đã đo và phải nói ra: trên dev, hai người duy nhất có
            tin quy được về mình (<c>#251</c>, <c>#1</c>) <b>không giao</b> một phần tử nào với danh sách
            sale phụ trách kênh (<c>#252…#255</c>), nên cỡ mẫu thật của tiêu chí này hiện là <b>0</b> cho
            mọi sale — và đó chính là lý do <c>Sample</c> phải đi kèm mọi con số.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatFirstResponseProvider.TranPhut">
            <summary>
            Trần khoảng cách inbound → outbound, tính bằng phút. <b>24 giờ</b>, theo đúng chỉ dẫn của
            §2.4.
            </summary>
            <remarks>
            Không phải để làm đẹp số: dev có bản ghi <c>ChatMessage</c> đề ngày <b>2025-08-26</b> trong
            khi hội thoại sớm nhất là 2026-08-26 — sớm hơn đúng một năm. Nó đã làm hỏng <c>max</c> của
            Đ5 (525.808 phút ≈ 365 ngày) và đã kéo lùi đồng hồ của bản phát lại ở giai đoạn D. Đây là
            <b>rác dữ liệu, không phải hành vi</b>; một bản ghi như thế lọt vào dãy là đủ để đẩy trung vị
            của một sale ít mẫu sang phía sai.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatFirstResponseProvider.ProviderCode">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatFirstResponseProvider.GetAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityWindow)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatFirstResponseProvider.GomKhoangCachMotHoiThoai(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatFirstResponseProvider.TinNhanToiThieu},Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityWindow,System.Collections.Generic.IReadOnlySet{System.Int32},System.Collections.Generic.Dictionary{System.Int32,System.Collections.Generic.List{System.Decimal}})">
            <summary>
            Duyệt một hội thoại theo thứ tự thời gian và gom khoảng cách của <b>từng lượt chờ</b>.
            </summary>
            <remarks>
            Một hội thoại sinh ra <b>nhiều</b> quan sát, không phải một: khách hỏi buổi sáng được trả
            lời, chiều hỏi tiếp lại được trả lời — đó là hai lượt chờ và cả hai đều nói lên chất lượng.
            Chỉ lấy lượt đầu tiên là vứt bỏ phần lớn dữ liệu của đúng những hội thoại dài nhất.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatFirstResponseProvider.TinNhanToiThieu">
            <summary>Bốn cột duy nhất phép đo cần — không kéo cả <c>Content</c> của hàng chục nghìn tin.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.IChatQualityQueryService">
            <summary>
            Đọc điểm chất lượng cho giao diện — trang <c>/diem-chat-cua-toi</c> và bảng điểm đội.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.IChatQualityQueryService.GetMyScoreAsync(System.Int32,System.DateTimeOffset)">
            <summary>
            Điểm của chính người đang đăng nhập. <b>Không đòi quyền gì</b> — xem điểm của mình thì ai
            cũng xem được (chốt CH-8).
            </summary>
            <param name="userId">Người đang đăng nhập</param>
            <param name="now">
            Mốc "hôm nay" để chặn dòng điểm mang ngày TƯƠNG LAI (sổ nợ PP-41). Truyền từ ngoài vào
            chứ không đọc đồng hồ trong thân hàm — cùng khuôn với
            <c>IChatQualityRecomputeService.RecomputeAsync</c>, và là điều kiện để có ca test.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.IChatQualityQueryService.GetTeamAsync(System.Int32)">
            <summary>
            Điểm của những người mà <paramref name="userId"/> được xem — đòi quyền
            <c>ChatQuality.ViewTeam</c> ở tầng controller, và thu hẹp phạm vi ở tầng này.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityQueryService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.IChatQualityQueryService"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityQueryService.GetMyScoreAsync(System.Int32,System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityQueryService.GetTeamAsync(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityQueryService.LayDiemTungTieuChiAsync(System.Int32,System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.SocialChat.ChatQualityCriterion},System.DateTimeOffset)">
            <summary>
            Điểm từng tiêu chí của lần chốt gần nhất — <b>không tính lần chốt mang ngày tương lai</b>.
            </summary>
            <remarks>
            <para>
            <b>Chặn trên là bản vá PP-41.</b> Không có nó thì một dòng <c>ChatQualityScore</c> mang
            ngày mai thắng phép sắp xếp và bảng điểm từng tiêu chí đọc theo lần chốt chưa từng xảy ra.
            Trên dev nguyên nhân là rác của <c>ChatQualitySqlTests</c> (đồng hồ dựng sẵn); trên
            production thì cần một máy lệch giờ hoặc một lượt chèn tay — xác suất thấp, nhưng chốt chặn
            rẻ đúng một điều kiện, và bước 8 bật <c>Chat.Quality.AffectsDistribution</c> là lúc bảng
            điểm bắt đầu <b>chia việc</b>, không còn chỉ để xem.
            </para>
            <para>
            Mốc chặn là <b>nửa đêm của hôm nay</b>, đúng biểu thức mà lượt tính dùng khi GHI
            (<c>ChatQualityRecomputeService</c>: <c>new DateTimeOffset(now.Year, now.Month, now.Day,
            0, 0, 0, now.Offset)</c>). Hai bên phải dùng chung một cách dựng mốc, nếu không dòng ghi
            lúc 00:00 hôm nay sẽ rơi vào hoặc ra khỏi phạm vi tuỳ theo giờ người dùng mở trang.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityQueryService.XepHangAsync(System.Int32,System.Decimal)">
            <summary>
            Thứ hạng trong nhóm người <b>cùng phụ trách ít nhất một kênh với mình</b>.
            </summary>
            <remarks>
            <para>
            Nhóm so sánh là đồng nghiệp cùng hộp thư, không phải toàn công ty: xếp một sale của kênh
            Zalo cạnh một sale của kênh Facebook là so hai khối lượng việc khác nhau.
            </para>
            <para>
            <b>Chỉ trả về THỨ HẠNG, không trả điểm của ai khác</b> — chốt CH-9. Người tạm tính không
            vào bảng xếp hạng: điểm của họ là điểm mặc định, và xếp một điểm mặc định cạnh những điểm
            đã đo là dựng ra một thứ hạng không có nghĩa.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityQueryService.DienXemDuocAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatVisibility)">
            <summary>Diện người mà <paramref name="userId"/> được xem điểm.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityRecomputeResult">
            <summary>Kết quả một lượt tính lại điểm — để job ghi log và để test đọc.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityRecomputeResult.StaffCount">
            <summary>Số sale đã chấm</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityRecomputeResult.ScoreRowCount">
            <summary>Số dòng <c>ChatQualityScore</c> đã ghi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityRecomputeResult.ProvisionalCount">
            <summary>Số sale ra kết quả tạm tính</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityRecomputeResult.ActiveCriteriaCount">
            <summary>Số tiêu chí đang bật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityRecomputeResult.FailedCriteria">
            <summary>
            Mã những tiêu chí <b>bị loại khỏi lượt này vì nguồn dữ liệu lỗi</b> — rỗng là lượt sạch.
            </summary>
            <remarks>
            Có mặt vì khối <c>catch</c> quanh mỗi provider là đúng nhưng nguy hiểm nếu im lặng: một
            nguồn hỏng rút hẳn một tiêu chí khỏi điểm của MỌI sale, mà lượt tính vẫn kết thúc "thành
            công" và Hangfire vẫn xanh. Với <c>chat.first-response</c> (trọng số 25) thì đó là một phần
            tư điểm biến mất mà không ai được báo.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityRecomputeResult.WindowFrom">
            <summary>Đầu cửa sổ trượt</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityRecomputeResult.WindowTo">
            <summary>Cuối cửa sổ trượt</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.IChatQualityRecomputeService">
            <summary>
            Tính lại điểm chất lượng chat cho toàn bộ sale đang phụ trách kênh (giai đoạn F).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.IChatQualityRecomputeService.RecomputeAsync(System.DateTimeOffset)">
            <summary>
            Chạy một lượt tính lại trên cửa sổ trượt kết thúc tại <paramref name="now"/>.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityRecomputeService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.IChatQualityRecomputeService"/>
            <remarks>
            <para>
            <b>Lượt tính này KHÔNG chạm đường phân phối.</b> Nó chỉ ghi hai bảng điểm; việc điểm có được
            dùng hay không nằm ở công tắc <c>Chat.Quality.AffectsDistribution</c> mà máy phân phối đọc.
            Tách như thế có chủ ý: điểm phải được tính và quan sát được <b>trước</b> khi nó có hiệu lực, nếu
            không thì không có cách nào đối chiếu trước lúc bật — đúng bài học của bước 5 trong trình tự lên
            production.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityRecomputeService.SoNgayCuaSo">
            <summary>Cửa sổ trượt — 30 ngày, theo §3.6</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityRecomputeService.RecomputeAsync(System.DateTimeOffset)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityRecomputeService.LaySoThoAsync(System.Collections.Generic.IReadOnlyCollection{Lada.Framework.Data.Domains.SocialChat.ChatQualityCriterion},System.Collections.Generic.IReadOnlyCollection{System.Int32},Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityWindow)">
            <summary>
            Gọi từng provider <b>một lần cho cả lô</b> và gom kết quả theo mã tiêu chí.
            </summary>
            <remarks>
            Provider hỏng <b>không được</b> làm hỏng cả lượt tính: một nguồn dữ liệu lỗi thì tiêu chí ấy
            thành "không chấm được" (cỡ mẫu 0) và bị loại khỏi điểm tổng, còn bốn tiêu chí kia vẫn ra
            điểm. Nuốt-và-ghi-log ở đây là đúng vì hậu quả của việc ném lên là <b>mọi</b> sale mất điểm
            vì một bảng lỗi — cùng lý lẽ với khối <c>catch</c> quanh máy phân phối trên đường tin đến.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityRecomputeService.GhiDiemTungTieuChiAsync(System.Int32,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityWindow,System.Collections.Generic.IReadOnlyCollection{Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityCriterionScore})">
            <summary>Ghi đè điểm của đúng ngày chốt ấy — job chạy lại trong ngày không cộng thêm dòng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityRecomputeService.GhiDiemTongAsync(System.Int32,System.DateTimeOffset,Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityWindow,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityOverall)">
            <summary>Một dòng tổng mỗi người — ghi đè, không thêm dòng.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatReclaimRateProvider">
            <summary>
            Tiêu chí <c>chat.reclaim-rate</c> — tỉ lệ phần trăm lượt phân công kết thúc vì <b>lỗi của người
            giữ</b>.
            </summary>
            <remarks>
            <para>
            <b>Ba lý do vào tử số, và ranh giới của chúng là một quyết định nghiệp vụ chứ không phải một
            danh sách tiện tay</b> — xem <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatReclaimRateProvider.LyDoTinhLaBiThuHoi"/>.
            </para>
            <para>
            Tiêu chí <b>duy nhất trong năm có mẫu thật</b> trên dev theo số đo F0-6: 10 dòng
            <c>ChatConversationAssignment</c>, <c>ReleaseReason</c> trải trên 4 giá trị. Vẫn là tài khoản
            thử, nhưng ít nhất phép tính chạy qua dữ liệu chứ không chạy qua một bảng rỗng.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatReclaimRateProvider.LyDoTinhLaBiThuHoi">
            <summary>
            Ba lý do nhả tính là "bị thu hồi" — và ba lý do <b>không</b> tính, quan trọng ngang nhau.
            </summary>
            <remarks>
            <para>
            <b>Tính:</b> <see cref="F:Lada.Framework.Data.Enums.ChatReleaseReason.QuaHanPhanHoi"/> (máy thu hồi vì để khách chờ
            quá hạn), <see cref="F:Lada.Framework.Data.Enums.ChatReleaseReason.KhachYeuCau"/> (khách đòi đổi người),
            <see cref="F:Lada.Framework.Data.Enums.ChatReleaseReason.ChatLuongKem"/> (quản lý chuyển đi vì chăm sóc kém). Đây đúng
            là ba lý do mà §6.2 đã tách riêng ra: hai trong ba cái đặt <c>KeepReadAccess = false</c>,
            tức chính hệ thống đã coi chúng là lỗi của người giữ.
            </para>
            <para>
            <b>Không tính:</b> <see cref="F:Lada.Framework.Data.Enums.ChatReleaseReason.TuNha"/> — và đây là chỗ dễ làm sai nhất.
            Tính cả tự nhả là phạt đúng hành vi mình muốn khuyến khích: sale biết mình không kịp chăm
            mà chủ động trả hội thoại về hàng chờ đang làm điều tốt cho khách. Phạt nó là dạy họ ôm
            hội thoại tới lúc bị máy thu hồi — tệ hơn cho khách, và vẫn tính vào tiêu chí này qua ngả
            <c>QuaHanPhanHoi</c>. Câu gợi ý của tiêu chí nói thẳng điều đó với người dùng.
            </para>
            <para>
            Cũng không tính: <see cref="F:Lada.Framework.Data.Enums.ChatReleaseReason.NguoiPhuTrachNghi"/>,
            <see cref="F:Lada.Framework.Data.Enums.ChatReleaseReason.ThoiPhuTrachKenh"/>,
            <see cref="F:Lada.Framework.Data.Enums.ChatReleaseReason.ChuyenVeSaleCuaKhach"/>,
            <see cref="F:Lada.Framework.Data.Enums.ChatReleaseReason.ChuyenNguoiKhac"/>, <see cref="F:Lada.Framework.Data.Enums.ChatReleaseReason.GoPhanCong"/>
            — đều là việc của tổ chức hoặc của luật CRM §3.4, không phải chất lượng chăm sóc.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatReclaimRateProvider.ProviderCode">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatReclaimRateProvider.GetAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityWindow)">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatSlaBreachRateProvider">
            <summary>
            Tiêu chí <c>chat.sla-breach-rate</c> — tỉ lệ phần trăm hội thoại từng vi phạm hạn phản hồi.
            </summary>
            <remarks>
            <para>
            Mẫu là <b>lượt phân công</b> (<c>ChatConversationAssignment</c>) chứ không phải hội thoại: một
            hội thoại đổi tay ba lần là ba phần việc của ba người, và tính nó một lần là bỏ sót hai.
            </para>
            <para>
            <b>Một xấp xỉ đã biết, ghi ra thay vì giấu.</b> <c>SlaBreachCount</c> nằm trên
            <c>ChatConversation</c>, tức nó là tổng của <b>mọi</b> người từng giữ hội thoại ấy — không có
            cột nào ghi "lượt vi phạm này thuộc về ai". Nên một sale vừa nhận một hội thoại đã có sẵn 2 lần
            vi phạm dưới tay người trước sẽ bị tính là "có vi phạm". Sai số này nghiêng về phía <b>khắt
            khe</b>, và nó chỉ chạm những hội thoại đã đổi tay sau khi quá hạn — mà đó đúng là diện giai
            đoạn E thu hồi. Đóng được bằng một cột <c>StaffId</c> trên một bảng nhật ký vi phạm riêng; ghi
            thành nợ <b>PP-33</b> thay vì dựng thêm một bảng cho một tiêu chí đang có <b>0 mẫu</b> (số đo
            F0-5: <c>SlaBreachCount</c> 63/63 = 0, và nó chỉ tăng khi <c>Chat.Sla.Enabled</c> bật thật).
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatSlaBreachRateProvider.ProviderCode">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatSlaBreachRateProvider.GetAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityWindow)">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityWindow">
            <summary>
            Cửa sổ thời gian mà một tiêu chí được tính trên đó, kèm cửa sổ giờ làm để lọc.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityWindow.From">
            <summary>Đầu cửa sổ trượt (bao gồm)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityWindow.To">
            <summary>Cuối cửa sổ trượt (không bao gồm)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityWindow.WorkingHours">
            <summary>
            Giờ làm việc <b>chung</b> (<c>Chat.WorkingHours.*</c>) — nay chỉ tiêu chí trả lời đầu tiên
            (<c>chat.first-response</c>) dùng để lọc theo cách đo (c) của Đ5.
            </summary>
            <remarks>
            Từ KC-18 cấu hình chung không còn áp cho ai (plan khoá học chat §8.7 câu 5). Tiêu chí tỉ lệ
            sẵn sàng (<c>chat.availability</c>) <b>không</b> đọc trường này mà đọc giờ riêng của từng
            người — người chưa đặt thì chưa có mẫu. Tiêu chí mới cần "giờ làm của một người" thì đọc
            <c>IChatStaffWorkingHoursProvider</c>, đừng đọc ở đây.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.IChatQualityCriterionProvider">
            <summary>
            Một tiêu chí điểm chất lượng biết tự đi lấy số thô của mình (giai đoạn F).
            </summary>
            <remarks>
            <para>
            <b>Nhận cả LÔ nhân viên, không nhận một người.</b> Đây là bài học gộp lô của giai đoạn D viết
            thẳng vào chữ ký: gọi bản một-người trong vòng lặp là nhân số truy vấn lên đúng bằng số sale, và
            với 40 sale × 5 tiêu chí thì đó là 200 lượt quét thay vì 5.
            </para>
            <para>
            <b>Trả kèm cỡ mẫu, luôn luôn.</b> <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRawValue.Sample"/> không phải trường tuỳ
            chọn — xem lý do ở chính nó. Người nào không có mặt trong từ điển trả về được hiểu là
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatQualityRawValue.KhongCoMau"/>.
            </para>
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.IChatQualityCriterionProvider.ProviderCode">
            <summary>
            Mã tiêu chí mà lớp này phục vụ — khớp <c>ChatQualityCriterion.ProviderCode</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.IChatQualityCriterionProvider.GetAsync(System.Collections.Generic.IReadOnlyCollection{System.Int32},Ladaer.BackEnd.Infrastructures.Services.SocialChat.Quality.ChatQualityWindow)">
            <summary>
            Lấy số thô của cả lô nhân viên trên một cửa sổ thời gian.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SignalRChatRealtimeNotifier">
            <summary>
            Bản đẩy realtime thật, thay cho <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.NoOpChatRealtimeNotifier"/> của giai đoạn A.
            <para>
            Chỉ đổi đăng ký DI là xong — tầng <c>SocialChatService</c> không biết gì về SignalR, đúng
            như thiết kế ban đầu.
            </para>
            <para>
            BẮT BUỘC đẩy DTO phẳng, không đẩy entity EF. Bộ tuần tự của SignalR là
            <c>System.Text.Json</c> và nó KHÔNG kế thừa <c>ReferenceLoopHandling.Ignore</c> mà tầng MVC
            cấu hình cho Newtonsoft — đẩy <c>ChatConversation</c> thẳng ra sẽ ném lỗi vòng tham chiếu
            qua navigation <c>ChatChannel</c>/<c>Customer</c>.
            </para>
            <para>
            Mọi lỗi đẩy tin đều bị nuốt sau khi ghi nhật ký: đây là đường thông báo, không phải đường
            dữ liệu. Redis backplane hỏng thì tin nhắn vẫn phải được lưu và webhook vẫn phải trả 200,
            nếu không Zalo sẽ gửi lại rồi vô hiệu hoá webhook.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SignalRChatRealtimeNotifier.ToItemAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.Nullable{Lada.Framework.Data.Enums.ChatAssignmentMode})">
            <summary>
            Dựng DTO hội thoại cho bản đẩy — kể cả tên nhân viên đang phân công.
            <para>
            Đường đẩy realtime PHẢI dựng DTO đầy đủ y như đường REST: phía trình duyệt thay nguyên
            dòng trong danh sách bằng bản vừa nhận, nên trường nào thiếu ở đây là trường đó biến
            mất khỏi màn hình ngay khi hội thoại có thay đổi. Đúng hình dạng lỗi đã cắn ở giai
            đoạn C với tên kênh và tên khách hàng.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SignalRChatRealtimeNotifier.ResolveChannelModeAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation)">
            <summary>
            Chế độ phân phối của kênh chứa hội thoại. <c>null</c> = không tra được kênh.
            <para>
            Hai chỗ cần đúng câu trả lời này trong cùng một lượt đẩy: nhóm nào được nhận
            (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatRealtimeAudience.Resolve(System.Nullable{Lada.Framework.Data.Enums.ChatAssignmentMode},System.Int32,System.Nullable{System.Int32})"/>) và cổng nhãn "Quá hạn" trong DTO (PP-34).
            Tra một lần rồi truyền đi — hỏi hai lần là mở đường cho hai câu trả lời khác nhau về
            cùng một hội thoại trong cùng một lượt.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SignalRChatRealtimeNotifier.SafeSendAsync(System.Func{System.Threading.Tasks.Task},System.String,System.Int32)">
            <summary>
            Gửi và nuốt lỗi. Xem ghi chú ở đầu lớp về lý do không được để lỗi đẩy tin nổi lên.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatRealtimeAudience">
            <summary>
            Luật "bản đẩy realtime của một hội thoại đi tới những nhóm nào".
            <para>
            Đây là mặt thứ hai của hàng rào quyền xem, và là mặt dễ quên: bản đẩy
            <c>ConversationUpdated</c> mang theo <c>LastMessage</c> — nguyên văn tin của khách. Chặn ở
            13 endpoint REST mà vẫn phát nội dung ấy vào nhóm phẳng là chặn cửa trước rồi mở cửa sau.
            </para>
            <para>
            Tách thành hàm thuần (không SignalR, không database) để kiểm được bằng test đơn giản —
            một luật quyết định ai đọc được tin của khách thì phải có ca test gọi thẳng vào nó.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatRealtimeAudience.Resolve(System.Nullable{Lada.Framework.Data.Enums.ChatAssignmentMode},System.Int32,System.Nullable{System.Int32})">
            <param name="mode">
            Chế độ phân phối của kênh; <c>null</c> nghĩa là <b>không tra được kênh</b> — khi đó coi
            như có hàng rào (fail-closed), vì đoán nhầm chiều còn lại là phát nội dung khách ra nhóm phẳng.
            </param>
            <param name="chatChannelId">Kênh của hội thoại</param>
            <param name="assignedStaffId">Người đang giữ hội thoại, <c>null</c> khi còn trong hàng chờ</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService">
            <summary>
            Lõi chat, dùng chung cho mọi nền tảng.
            <para>
            Lớp này KHÔNG BIẾT nó đang xử lý Zalo hay Facebook. Nếu thấy cần viết
            <c>if (platform == …)</c> ở đây thì logic đó đang nằm sai chỗ — nó thuộc về
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.IWebhookParser"/> (chiều nhận) hoặc <c>IPlatformMessenger</c> (chiều gửi).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.GetOrCreateConversationAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage)">
            <summary>
            Tìm hội thoại theo cặp (kênh, người dùng), chưa có thì tạo mới.
            Hội thoại đã đóng mà khách nhắn lại thì tự mở lại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.ReceiveExternalMessageAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage)">
            <summary>
            Lưu một tin nhắn khách gửi vào và cập nhật hội thoại tương ứng.
            Tin đã lưu rồi (nền tảng gửi lại webhook) thì bỏ qua, không tạo bản sao.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.UpdateDeliveryStatusAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,System.String,Lada.Framework.Data.Enums.ChatDeliveryStatus)">
            <summary>
            Cập nhật trạng thái giao nhận của một tin đã gửi đi trên MỘT kênh. Chỉ tiến, không lùi.
            <para>
            Bắt buộc truyền kênh: nếu tra tin theo mỗi định danh nền tảng thì một người ngoài
            chỉ cần đoán trúng định danh là đổi được trạng thái tin của kênh bất kỳ.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.UpdateDeliveryStatusByWatermarkAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,System.String,System.DateTimeOffset,Lada.Framework.Data.Enums.ChatDeliveryStatus)">
            <summary>
            Nâng trạng thái giao nhận theo MỐC THỜI GIAN: mọi tin chiều ra của hội thoại
            (kênh, người dùng) có <c>SentAt</c> trước hoặc bằng mốc lên trạng thái đích (SC-25 / SC-3).
            <para>
            Khác cập nhật đích danh ở một điểm cố ý: tin <c>Failed</c> KHÔNG được mốc nào cứu —
            tin gửi hỏng chưa bao giờ đi nên không mốc giao nhận nào xác nhận được nó. Cập nhật
            đích danh thì được phép (nền tảng gọi tên đúng tin đó là bằng chứng trực tiếp).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.ApplyReactionAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.MessageReactionUpdate)">
            <summary>
            Ghi nhận một lần thả/gỡ biểu tượng cảm xúc do nền tảng báo về (SC-29).
            <para>
            Cũng bắt buộc truyền kênh, cùng lý lẽ với <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.UpdateDeliveryStatusAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,System.String,Lada.Framework.Data.Enums.ChatDeliveryStatus)"/>: tra
            tin theo mỗi mã nền tảng là mở đường cho một payload đoán được mã gắn cảm xúc vào tin
            của kênh khác.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.SendReactionAsync(System.Int32,System.Int32,System.String,System.Int32,System.String)">
            <summary>
            Nhân viên thả hoặc gỡ một biểu tượng cảm xúc lên một tin nhắn.
            <para>
            Gọi nền tảng TRƯỚC rồi mới ghi — ngược hẳn thứ tự của <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.SendMessageAsync(Ladaer.BackEnd.Infrastructures.Services.SocialChat.SendChatMessageParam,System.Int32,System.String)"/>, và
            đó là chủ ý: một tin gửi hỏng vẫn phải để lại dấu vết đọc được trong khung chat, còn một
            cảm xúc thả hỏng thì không có gì để lưu lại cả. Ghi trước rồi nền tảng từ chối là màn
            hình hiện một cảm xúc mà khách không bao giờ thấy.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.ProcessWebhookAsync(Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.IWebhookParser,Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookRequestContext)">
            <summary>
            Luồng xử lý webhook dùng chung cho mọi nền tảng: đọc payload, tra kênh trong DB,
            lưu tin hoặc cập nhật trạng thái giao nhận.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.SendMessageAsync(Ladaer.BackEnd.Infrastructures.Services.SocialChat.SendChatMessageParam,System.Int32,System.String)">
            <summary>
            Nhân viên trả lời một hội thoại. Lưu tin trước rồi mới gọi nền tảng, để một lần gửi hỏng
            vẫn để lại dấu vết đọc được trong khung chat thay vì biến mất.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.SearchConversationsAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            Danh sách hội thoại cho cột trái của khung chat, <b>đã lọc theo phạm vi</b> của
            <paramref name="currentUserId"/>.
            <para>
            Kênh còn ở chế độ <c>Shared</c> thì không lọc gì cả — hành vi y hệt trước đợt phân phối
            (§6.3). Kênh đã bật hàng rào thì đi qua <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IChatVisibilityResolver"/>.
            </para>
            </summary>
            <param name="param">Tham số phân trang, sắp xếp, bộ lọc của client</param>
            <param name="currentUserId">
            Người đang đăng nhập. Bỏ trống (0) là luồng máy chạy và chỉ thấy kênh chưa bật hàng rào
            — thiếu tham số phải dẫn tới thấy ÍT hơn, không bao giờ nhiều hơn.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.GetConversationDetailAsync(System.Int32,System.Int32,System.Int32)">
            <summary>
            Chi tiết một hội thoại kèm <paramref name="messageLimit"/> tin gần nhất.
            Trả <c>null</c> khi hội thoại không tồn tại, đã xoá mềm, <b>hoặc nằm ngoài phạm vi</b>
            của <paramref name="currentUserId"/> — ba trường hợp trả về giống hệt nhau, cố ý:
            phân biệt được chúng là nói cho người dò biết hội thoại đó có tồn tại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.MarkConversationReadAsync(System.Int32,System.Int32,System.String)">
            <summary>Đưa số tin chưa đọc của một hội thoại về 0 và báo cho mọi màn hình đang mở</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.GetTotalUnreadAsync(System.Int32)">
            <summary>
            Tổng số tin chưa đọc <b>trong phạm vi của người đang đăng nhập</b> — badge trên thanh
            điều hướng.
            <para>
            Trước đợt này hàm cộng toàn bảng, tức một nhân viên đọc được tổng khối lượng việc của
            cả công ty. Đường này không nhận mã hội thoại nào nên rất dễ bị bỏ sót khi rà hàng rào.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.EnsureCanSendAsync(System.Int32,System.Int32)">
            <summary>
            Hỏi trước xem một hội thoại có gửi tin ra được không, KHÔNG gửi gì cả.
            <para>
            Dùng cho đường gửi ảnh: ở đó tệp phải nằm trên đĩa trước khi gọi
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.SendMessageAsync(Ladaer.BackEnd.Infrastructures.Services.SocialChat.SendChatMessageParam,System.Int32,System.String)"/> (nền tảng cần đường dẫn tệp), nên nếu không hỏi trước thì
            mỗi lần hội thoại đã xoá hay kênh đang tắt sẽ để lại một tệp ảnh không ai tham chiếu
            trên đĩa — và không có việc nào dọn nó.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.GetOlderMessagesAsync(System.Int32,System.Int32,System.Int32,System.Int32)">
            <summary>
            Nạp thêm tin CŨ HƠN một tin đã có trên màn hình (nút "xem thêm tin cũ").
            <para>
            Phân trang theo mốc chứ không theo số trang: hội thoại vẫn đang chạy, khách nhắn thêm
            giữa hai lần bấm là mọi số trang lệch đi một nhịp và nhân viên sẽ thấy tin lặp lại
            hoặc mất một khúc giữa.
            </para>
            </summary>
            <param name="conversationId">Hội thoại</param>
            <param name="beforeMessageId">Chỉ lấy tin có mã nhỏ hơn giá trị này; 0 nghĩa là lấy từ cuối</param>
            <param name="limit">Số tin lấy thêm; bỏ trống là 50, trần 200</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.LinkCustomerAsync(System.Int32,System.Int32,System.Boolean,System.Int32,System.String)">
            <summary>
            Gắn hội thoại với một khách hàng trong hệ thống.
            </summary>
            <param name="conversationId">Hội thoại</param>
            <param name="customerId">Khách hàng</param>
            <param name="writeContact">
            Có ghi thêm dấu vết liên hệ vào hồ sơ khách hàng không (ghi THÊM, không đè).
            </param>
            <param name="userId">Người thực hiện</param>
            <param name="userName">Tên người thực hiện, ghi vào cột audit</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.UnlinkCustomerAsync(System.Int32,System.Int32,System.String)">
            <summary>Gỡ liên kết khách hàng khỏi hội thoại (gắn nhầm người)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.AssignConversationAsync(System.Int32,System.Nullable{System.Int32},System.Int32,System.String)">
            <summary>
            Phân công hội thoại cho một nhân viên, hoặc gỡ phân công khi
            <paramref name="assignedStaffId"/> để trống.
            <para>
            Với kênh còn ở chế độ <c>Shared</c> đây vẫn CHỈ là nhãn để lọc. Với kênh đã bật hàng
            rào, phân công là thứ <b>quyết định ai đọc được hội thoại</b> — nên đường này siết hai
            đầu: chỉ gán được hội thoại trong phạm vi mình thấy, và chỉ gán cho người có tên trong
            <c>ChatChannelStaff</c> của chính kênh đó (§3.11).
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.ChangeStatusAsync(System.Int32,Lada.Framework.Data.Enums.ChatConversationStatus,System.Int32,System.String)">
            <summary>
            Đổi trạng thái vòng đời của hội thoại (đang xử lý / chờ khách / đóng / mở lại).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.ReleaseConversationAsync(System.Int32,Lada.Framework.Data.Enums.ChatReleaseReason,System.String,System.Int32,System.String)">
            <summary>
            <b>Nhả</b> hội thoại về hàng chờ — không giao cho ai.
            <para>
            Lý do bắt buộc, và nó không phải một dòng ghi chú: lý do quyết định người vừa nhả còn
            đọc được hội thoại nữa không (§6.2). Xem
            <see cref="M:Lada.Framework.Data.Enums.ChatReleaseReasonRules.KeepsReadAccess(System.Nullable{Lada.Framework.Data.Enums.ChatReleaseReason})"/>.
            </para>
            </summary>
            <param name="conversationId">Hội thoại</param>
            <param name="reason">Vì sao nhả — quyết định phạm vi dữ liệu của người cũ</param>
            <param name="note">Ghi chú bắt buộc; một mã lý do trơ trọi thì tháng sau không ai đọc lại được</param>
            <param name="userId">Người thực hiện</param>
            <param name="userName">Tên người thực hiện</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.TransferConversationAsync(System.Int32,System.Int32,Lada.Framework.Data.Enums.ChatReleaseReason,System.String,System.Int32,System.String)">
            <summary>
            <b>Chuyển</b> hội thoại sang một nhân viên khác.
            <para>
            Đường này không được trở thành đường đọc trộm ("chuyển về cho mình rồi đọc", §3.11).
            Ba lớp chặn: hội thoại phải nằm trong phạm vi <b>ghi</b> của người thực hiện (nên một
            sale chỉ chuyển được hội thoại mình đang cầm), người nhận phải nằm trong phạm vi nhân
            sự của người thực hiện (controller), và người nhận phải có tên trong danh sách phụ
            trách của chính kênh đó.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.GetAssignmentHistoryAsync(System.Int32,System.Int32)">
            <summary>
            Lịch sử phân công của một hội thoại — "ai từng cầm hội thoại này, vì sao thôi cầm".
            Trả danh sách rỗng khi hội thoại nằm ngoài phạm vi <b>đọc</b> của người hỏi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.RevokeReadAccessAsync(System.Int32,System.Int32,Lada.Framework.Data.Enums.ChatReleaseReason,System.String,System.Int32,System.String)">
            <summary>
            <b>Thu hồi quyền xem</b> của một người đã thôi giữ hội thoại.
            </summary>
            <remarks>
            Bịt khe hở mà chính người sắp bị cắt điều khiển được: cờ <c>KeepReadAccess</c> chỉ ghi
            lúc đóng một lượt đang mở, nên sale tự nhả trước với một lý do hành chính là lượt của
            họ đóng lại với cờ giữ quyền và quản lý không còn lượt nào để đóng. Đường này ghi thêm
            một dòng thu hồi, không sửa lịch sử cũ.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService.SearchQueueAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)">
            <summary>
            <b>Hàng chờ</b>: hội thoại chưa giao cho ai — màn điều phối (sổ nợ PP-14).
            <para>
            Tồn tại vì hàng rào §3.7 có một hệ quả cố ý: hội thoại chưa giao cho ai trên kênh đã
            bật hàng rào thì sale thường không thấy, nên trước giai đoạn B chỉ trưởng nhóm và người
            xem-tất-cả biết là có việc đang chờ. Đường này cho người điều phối nhìn thấy nó.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SendChatMessageParam">
            <summary>
            Tham số gửi một tin đi. Cố ý KHÔNG phải model bind thẳng từ request:
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SendChatMessageParam.LocalImagePath"/> là đường dẫn tệp trên máy chủ, để client tự đặt giá trị cho nó
            là mở đường đọc tệp bất kỳ của máy chủ rồi gửi ra ngoài.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SendChatMessageParam.Content">
            <summary>Nội dung văn bản, hoặc chú thích của ảnh</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SendChatMessageParam.LocalImagePath">
            <summary>Đường dẫn tệp ảnh trên đĩa máy chủ (nền tảng nào cần tải tệp lên thì dùng)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SendChatMessageParam.PublicUrl">
            <summary>Đường dẫn ảnh công khai (nền tảng nào nhận URL thì dùng)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SendChatMessageParam.ReplyToMessageId">
            <summary>
            Mã tin <b>trong LADA</b> mà tin này trả lời trích dẫn; <c>null</c> với tin thường.
            <para>
            Cố ý là mã nội bộ chứ không phải mã tin của nền tảng. Nhận mã nền tảng từ client thì
            không có cách nào kiểm nó thuộc hội thoại nào — và một chuỗi trích dẫn tin của khách
            khác sẽ đi thẳng ra ngoài. Máy chủ tra mã nền tảng từ mã này theo CẶP (tin, hội thoại),
            đúng cách <c>ChatQuoteResolver</c> đã cẩn thận làm ở chiều ngược lại.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ISocialChatService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.WebhookAuthorName">
            <summary>Tên ghi vào cột audit cho bản ghi do webhook tạo (không có người dùng đăng nhập)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.DefaultMessageLimit">
            <summary>Số tin nạp sẵn khi mở một hội thoại</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.MaxReactionEmojiLength">
            <summary>
            Độ dài tối đa của một biểu tượng cảm xúc, tính bằng đơn vị UTF-16 — khớp đúng bề rộng
            cột <c>ChatMessage.CustomerReactionEmoji</c> / <c>StaffReactionEmoji</c> (migration
            <c>M202608281500</c>). Đủ cho mọi chuỗi emoji ghép quan sát được.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.MaxMessageLimit">
            <summary>
            Trần số tin một lần gọi được phép lấy. Có trần vì tham số này đến từ client — không có
            nó thì một yêu cầu đủ lớn kéo cả hội thoại nghìn tin ra khỏi database.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.OutboundEchoWindow">
            <summary>
            Cửa sổ đối chiếu tin do OA gửi ra nhận lại qua webhook với tin LADA vừa gửi đi.
            <para>
            Cần vì tin nhân viên bấm gửi trong SPA cũng làm Zalo bắn <c>oa_send_*</c> về. Bình
            thường mã tin nền tảng trả về đã đủ để nhận ra bản trùng, nhưng có một khe hẹp: giữa
            lúc lưu tin và lúc ghi được mã đó xuống, webhook có thể đã về. Trong khe ấy phải nhận
            nhau bằng nội dung, nếu không mỗi câu trả lời hiện thành hai bong bóng.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.PhanPhoiNeuCanAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation)">
            <summary>
            Chạy máy phân phối cho hội thoại vừa nhận tin của khách — đúng thời điểm duy nhất mà
            §3.3 cho phép máy chạy (giai đoạn D).
            </summary>
            <remarks>
            <para>
            <b>Đặt ở đây chứ không sau bản đẩy realtime</b>: người vừa nhận hội thoại phải được vào
            phòng SignalR <i>trước</i> khi tin của khách được đẩy đi, nếu không họ nhận được hội
            thoại nhưng không nhận được chính tin đã sinh ra nó. Máy tự lo phần cấp phạm vi rồi đẩy
            cập nhật; lượt <c>ConversationUpdatedAsync</c> ngay sau đây là một bản đẩy trùng, và
            trùng là chiều an toàn — thiếu mới là chiều hỏng.
            </para>
            <para>
            <b>Nuốt mọi lỗi.</b> Tin của khách đã lưu xong trước khi hàm này chạy; một máy phân
            phối hỏng không được phép làm mất tin nhắn hay làm webhook trả lỗi cho nền tảng — Zalo
            sẽ gửi lại và sinh ra bản trùng. Máy hỏng thì hội thoại nằm hàng chờ, và job
            <c>chat-queue-sweep</c> hai phút sau thử lại.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.ResolveQuotedMessageAsync(Ladaer.BackEnd.Infrastructures.Services.SocialChat.SendChatMessageParam,Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger,Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.PlatformRecipient)">
            <summary>
            Đổi "trả lời tin số mấy trong LADA" thành mã tin phía nền tảng, và chặn mọi trường hợp
            không trích dẫn được. Trả <c>(null, null)</c> khi tin này không phải câu trả lời trích dẫn.
            <para>
            Mọi lỗi ở đây đều trả về một câu đọc được thay vì âm thầm bỏ phần trích dẫn: một câu trả
            lời mất ngữ cảnh trông y hệt một câu trả lời có ngữ cảnh ở phía nhân viên, nên hỏng im
            lặng ở đây là hỏng đúng chỗ không ai phát hiện được.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.MapPage(Lada.Framework.DTO.SmartTable.SmartTableResult{Lada.Framework.Data.Domains.SocialChat.ChatConversation},System.Func{Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem})">
            <summary>
            Map một trang thực thể đã phân trang sang DTO, giữ nguyên mọi con số phân trang.
            </summary>
            <remarks>
            Có mặt vì bối cảnh "chờ bao lâu" phải dựng từ chính các dòng của trang (KC-18): trước đó
            hai màn danh sách map ngay trong <c>ToSmartTableResultAsync</c>, lúc chưa có trang nào trong
            tay. Chép đủ sáu trường của <see cref="T:Lada.Framework.DTO.SmartTable.SmartTableResult`1"/> chứ không riêng ba trường mà
            hàm phân trang đang điền — thiếu trường nào là trường đó về 0 trên giao diện mà không ai báo.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.LoadConversationInScopeAsync(System.Int32,System.Int32,System.Boolean)">
            <summary>
            Nạp một hội thoại <b>trong phạm vi</b> của người đang thao tác, kèm hai navigation BẮT
            BUỘC cho bản đẩy realtime.
            <para>
            Đây là cửa duy nhất mà 11 trong 13 đường dùng để lấy một hội thoại theo mã. Trả
            <c>null</c> cho cả ba trường hợp "không tồn tại" / "đã xoá mềm" / "ngoài phạm vi" —
            người gọi không được phép phân biệt chúng, vì phân biệt được là trả lời hộ câu hỏi
            "hội thoại số N có tồn tại không".
            </para>
            <para>
            Về <c>Include</c>: xem ghi chú ở <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.SendMessageAsync(Ladaer.BackEnd.Infrastructures.Services.SocialChat.SendChatMessageParam,System.Int32,System.String)"/> — thiếu nó thì bản đẩy
            mang tên kênh / tên khách rỗng, và phía trình duyệt thay nguyên dòng bằng bản vừa nhận.
            </para>
            <para>
            <b><paramref name="forWrite"/> là ranh giới "còn xem chỉ đọc" của §6.2.</b> Từ giai
            đoạn B, phạm vi ĐỌC gồm cả hội thoại mình <i>từng</i> giữ (PP-10) — nhưng người từng
            giữ không được gửi tin cho khách của người đang giữ, không được gỡ khách hàng, không
            được phân công lại. Đường ghi nào cũng phải truyền <c>true</c>; quên một chỗ là chỗ đó
            nhận nguyên phạm vi đọc rộng hơn mà không ai định thế.
            </para>
            </summary>
            <param name="conversationId">Hội thoại cần nạp</param>
            <param name="currentUserId">Người đang thao tác; 0 = luồng máy chạy, chỉ thấy kênh chưa bật hàng rào</param>
            <param name="forWrite">
            <c>true</c> khi lời gọi sắp THAY ĐỔI hội thoại — bỏ nhánh "từng giữ" khỏi phạm vi.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.LoadWithVisibilityAsync(System.Int32,System.Int32,System.Boolean)">
            <summary>
            Như <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.LoadConversationInScopeAsync(System.Int32,System.Int32,System.Boolean)"/> nhưng trả kèm <b>đối tượng phạm vi</b>
            đã phân giải.
            </summary>
            <remarks>
            Tồn tại vì ba đường chi tiết cần chấm cờ chỉ-đọc <c>CanWrite</c> (sổ nợ PP-36) trên
            đúng hội thoại vừa nạp, và <b>phân giải phạm vi lần thứ hai</b> chỉ để hỏi lại là thêm
            một lượt đọc <c>ChatChannelStaff</c> + <c>ChatConversationAssignment</c> cho mỗi lần mở
            một hội thoại — mà tệ hơn thế, nó mở đường cho hai câu trả lời khác nhau về cùng một
            hội thoại trong cùng một request.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.ValidateReleaseInput(Lada.Framework.Data.Enums.ChatReleaseReason,System.String)">
            <summary>
            Chấm hai thứ mà cả ba đường đổi người đều đòi: lý do có thật, và ghi chú không rỗng.
            </summary>
            <remarks>
            <para>
            <c>Enum.IsDefined</c> không phải thủ tục hình thức. Lý do đến từ client, và nó là đầu
            vào của <see cref="M:Lada.Framework.Data.Enums.ChatReleaseReasonRules.KeepsReadAccess(System.Nullable{Lada.Framework.Data.Enums.ChatReleaseReason})"/> — một số lạ rơi vào nhánh
            <c>_ =&gt; true</c> của hàm đó, nghĩa là người gửi một giá trị ngoài enum tự chọn cho
            mình kết quả "vẫn còn quyền đọc". Chặn ở đây, không phải ở giao diện.
            </para>
            <para>
            Ghi chú bắt buộc vì §3.2 nói nhật ký phải <b>đọc được</b>: một bảng toàn mã lý do thì
            tháng sau không ai dựng lại được câu chuyện "vì sao khách này đổi người ba lần".
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.NotifyAssignmentChangedAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.Nullable{System.Int32},System.Nullable{System.Int32},System.Boolean)">
            <summary>
            Báo cho các màn hình đang mở sau một lần đổi người giữ hội thoại — <b>thu hồi trước,
            đẩy sau</b>.
            </summary>
            <remarks>
            <para>
            Thứ tự ở đây là một bản vá, không phải sở thích. Giai đoạn A đẩy
            <c>ConversationUpdated</c> trước rồi mới thu hồi phòng, nên người vừa bị cắt quyền xem
            còn nhận đúng một bản đẩy cuối cùng — kèm nguyên văn <c>LastMessage</c> của khách. Một
            bản đẩy vẫn là một bản đẩy: chuyển hội thoại vì khách phàn nàn (<c>KeepReadAccess =
            false</c>) mà người bị chuyển vẫn đọc được tin kế tiếp thì bản vá §6.2 chưa chạy.
            </para>
            <para>
            Thu hồi trước cũng đúng ở chiều mở rộng: <c>ScopeChangedAsync</c> cho người mới đưa họ
            vào phòng ngay, nên bản đẩy ngay sau đó tới được họ mà không phải đợi tải lại trang.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.LoadQueuedConversationAsync(System.Int32,System.Int32)">
            <summary>
            Nạp một hội thoại <b>đang ở hàng chờ</b> theo phạm vi ĐIỀU PHỐI — cửa thứ hai của
            đường phân công, chỉ mở cho người quản trị phân phối.
            </summary>
            <remarks>
            <para>
            Không có cửa này thì trang <c>/dieu-phoi-chat</c> vô dụng với đúng vai nó sinh ra để
            phục vụ: người có <c>ChatDistribution.Manage</c> mà không phụ trách kênh nào nhìn thấy
            hàng chờ (<see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.SearchQueueAsync(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Int32)"/> dùng <c>ResolveForQueueAsync</c>) nhưng mọi
            nút "Giao" đều trả "không tìm thấy hội thoại".
            </para>
            <para>
            Hai hàng rào giữ cho nó không thành một lỗ: điều kiện <c>AssignedStaffId == null</c>
            khoá cửa này vào ĐÚNG hàng chờ — hội thoại đã có người giữ không đi qua đây được, nên
            không ai giành được việc của người khác; và <c>ResolveForQueueAsync</c> chỉ nới phạm vi
            cho quyền quản trị phân phối, người khác nhận lại đúng phạm vi thường của họ.
            </para>
            <para>
            Đường này KHÔNG mở quyền đọc: phân công xong, người điều phối vẫn không xem được nội
            dung hội thoại vừa giao (phạm vi đọc của họ không đổi). Điều phối là quyền định đoạt
            hàng chờ, không phải quyền đọc tin của khách.
            </para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.GhiDoiNguoiAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.ChatAssignmentChange)">
             <summary>
             Ghi hội thoại và dòng nhật ký phân công trong <b>một</b> giao dịch, rồi mới báo realtime.
             </summary>
             <remarks>
             <para>
             Hai lượt ghi này không được rời nhau. Cập nhật <c>ChatConversation</c> xong mà ghi
             nhật ký hỏng thì lượt cũ của người phụ trách trước vẫn đang mở — và mức <c>Self</c>
             của hàng rào đọc chính cột đó, nên người vừa bị chuyển đi vì khách phàn nàn giữ quyền
             xem vĩnh viễn, không có đường nào phát hiện ra. Chiều ngược lại (nhật ký xong, hội
             thoại hỏng) thì lịch sử nói một chuyện mà dữ liệu nói chuyện khác.
             </para>
             <para>
             Bản đẩy realtime nằm NGOÀI giao dịch, và cố ý: gửi đi rồi rollback là báo cho mọi màn
             hình một sự thật chưa từng xảy ra.
             </para>
             </remarks>
             <remarks>
             Thân hàm chuyển hẳn về <c>IChatAssignmentJournal.ApplyChangeAsync</c> ở giai đoạn C,
             khi đường ghi thứ ba và thứ tư vào <c>AssignedStaffId</c> xuất hiện (uỷ quyền tạm khi
             nghỉ dài, và nhả hội thoại khi gỡ người khỏi kênh — sổ nợ PP-18) từ một service khác
             không inject được <c>ISocialChatService</c>. Giữ lại tên riêng ở đây vì nó được gọi từ
             bốn chỗ trong lớp này và cái tên nói đúng việc nó làm.
            
             Nhật ký vẫn ghi TRƯỚC mọi bản đẩy: cờ <c>KeepReadAccess</c> vừa ghi xuống chính là thứ
             <c>ChatVisibilityResolver</c> đọc để chấm lại phạm vi. Đảo thứ tự là thu hồi theo một
             phạm vi đã lỗi thời.
             </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.Stamp(Lada.Framework.Data.Domains.SocialChat.ChatConversation,System.Int32,System.String)">
            <summary>Ghi cột audit cho một thao tác do nhân viên thực hiện</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.NormalizeMessageLimit(System.Int32)">
            <summary>Ép số tin một lần nạp về khoảng cho phép — tham số này đến từ client</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.FillAssignedStaffNamesAsync(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.DTO.Items.SocialChat.ChatConversationItem})">
            <summary>
            Điền tên nhân viên phân công cho một trang danh sách bằng ĐÚNG MỘT lượt tra.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.ToMessageItemsAsync(System.Int32,System.Collections.Generic.List{Lada.Framework.Data.Domains.SocialChat.ChatMessage})">
            <summary>
            Chuyển một mẻ tin sang DTO, kèm khối trích dẫn tra sẵn bằng MỘT lời gọi database
            cho cả mẻ — tra từng dòng thì mở một hội thoại 50 tin là 50 lượt truy vấn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.ResolveSendableChannelAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation)">
            <summary>
            Tra kênh của một hội thoại và kiểm nó có gửi tin ra được không.
            Trả về kênh khi dùng được, hoặc lý do đọc được khi không — dùng chung cho
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.SendMessageAsync(Ladaer.BackEnd.Infrastructures.Services.SocialChat.SendChatMessageParam,System.Int32,System.String)"/> và <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.EnsureCanSendAsync(System.Int32,System.Int32)"/> để hai đường không
            bao giờ lệch luật.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.MaxLoggedPayloadLength">
            <summary>
            Ghi nhật ký một payload webhook bị bỏ qua, ở đúng mức ồn của nó.
            <para>
            Đây là bản vá của sổ nợ <c>SC-30</c>. Trước đó mọi trường hợp bỏ qua đều ghi
            <c>LogDebug</c>, mà <c>Logging:LogLevel:Default</c> của repo là <c>Information</c> —
            nên sự kiện nền tảng gửi mà LADA chưa hỗ trợ biến mất không để lại dấu vết. Hộp thư
            "Ẩn danh" của Zalo có hội thoại đều đặn cả tháng, LADA không nhận cái nào, và không
            một dòng nhật ký nào cho biết điều đó đang xảy ra.
            </para>
            <para>
            Bỏ CÓ CHỦ Ý (tiếng vọng của chính mình, <c>message_reads</c> theo §6.11, sự kiện ngoài
            phạm vi v1) vẫn giữ mức Debug — chúng xảy ra liên tục, nâng mức lên là làm ngập nhật ký
            rồi chẳng ai đọc nữa. Chỉ nhánh CHƯA HỖ TRỢ mới lên Warning, kèm tên sự kiện.
            </para>
            </summary>
            <summary>
            Số ký tự thân request in kèm cảnh báo sự kiện chưa hỗ trợ. Đủ cho một payload webhook
            thường (vài trăm ký tự) mà không biến nhật ký thành nơi đổ dữ liệu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.LogUnknownChannel(Lada.Framework.Data.Enums.SocialPlatform,System.String)">
            <summary>
            Payload trỏ tới một kênh không có trong DB hoặc đang tắt. Vẫn trả 200 cho nền tảng
            để nó không gửi lại vô hạn, nhưng phải để lại dấu vết vì đây cũng là hình dạng của
            một payload giả mạo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.ForgetFailedInsertAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation)">
            <summary>
            Gỡ một thực thể vừa chèn hụt ra khỏi ngữ cảnh đang theo dõi, để lần lưu sau không kéo nó theo.
            <para>
            Dùng <c>RemoveAsync</c> vì tầng service chỉ nhìn thấy <see cref="T:Lada.Framework.Data.Repositories.IRepository`1"/>:
            với thực thể đang ở trạng thái <c>Added</c>, <c>DbSet.Remove</c> của EF Core chuyển nó về
            <c>Detached</c> chứ không sinh lệnh DELETE nào, nên đây đúng là "quên bản ghi đó đi".
            </para>
            <para>
            Nuốt lỗi có chủ ý: đây đã là đường xử lý sự cố, việc gỡ thất bại không được che mất
            nguyên nhân gốc mà đường gọi đang xử lý.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.TryMatchOwnOutboundMessageAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage,System.String,System.DateTimeOffset)">
            <summary>
            Tin chiều ra vừa nhận qua webhook có phải là tiếng vọng của một tin CHÍNH LADA vừa gửi
            không. Đúng thì ghi bổ sung mã tin của nền tảng vào bản ghi đã có và trả <c>true</c>.
            <para>
            Đường bảo vệ thứ nhất là mã tin nền tảng (<c>IsMessageAlreadySavedAsync</c>). Đây là
            đường thứ hai, cho khe hẹp giữa lúc lưu tin và lúc ghi được mã ấy xuống: trong khe đó
            bản ghi của LADA chưa có mã nên đường thứ nhất không nhận ra, và nếu không có hàm này
            thì mỗi câu nhân viên gửi từ SPA sẽ hiện thành hai bong bóng.
            </para>
            <para>
            Chỉ nhận những bản ghi CHƯA từng gặp tiếng vọng (<c>PlatformEchoAt == null</c>): bản đã
            được một sự kiện OA-gửi khớp vào rồi mà nội dung lại trùng là một tin khác thật sự
            (nhân viên gõ lại đúng câu đó trong ứng dụng Zalo OA), không được nuốt.
            </para>
            <para>
            Dấu ấy KHÔNG thể thay bằng "bản ghi chưa có mã tin", dù nghe tương đương: Zalo cấp hai
            mã khác hệ cho cùng một tin — <c>data.message_id</c> trong phản hồi của API gửi tin, và
            <c>message.msg_id</c> trong webhook. Bản ghi của LADA có mã thứ nhất ngay khi gửi xong,
            nên nếu lấy "đã có mã" làm dấu thì mọi tiếng vọng đều bị coi là tin mới và mỗi câu nhân
            viên gửi hiện thành hai bong bóng — bản gốc kẹt ở "Đã gửi" vì không sự kiện giao nhận
            nào nhắc tới mã thứ nhất, bản sao mang nhãn "ngoài LADA" và nhận đủ "Đã nhận"/"Đã xem".
            Đó chính là lý do mã của webhook GHI ĐÈ mã của API bên dưới: chỉ mã webhook mới tra
            được, và nó cũng là mã mà Zalo đòi khi trích dẫn hay thả cảm xúc lên tin.
            </para>
            <para>
            Và cũng KHÔNG nhận bản ghi đã <c>Failed</c>, dù nó cũng không có mã tin: tin gửi hỏng
            từ SPA rồi nhân viên gõ lại đúng câu ấy trong ứng dụng Zalo OA là chuyện thường gặp.
            Nuốt nó thì khung chat chỉ còn một bong bóng đỏ "Thất bại" trong khi khách đã nhận
            được câu trả lời — sai lệch tệ hơn hẳn một bong bóng thừa.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.RefreshConversationProfileAsync(Lada.Framework.Data.Domains.SocialChat.ChatConversation,Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage)">
            <summary>
            Bổ sung tên và ảnh đại diện khi nền tảng gửi kèm mà hội thoại chưa có.
            Không ghi đè bằng giá trị rỗng — payload thiếu thông tin không được xoá thứ đang có.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.FillProfileFromPlatformAsync(Lada.Framework.Data.Domains.SocialChat.ChatChannel,Lada.Framework.Data.Domains.SocialChat.ChatConversation)">
            <summary>
            Hỏi nền tảng tên hiển thị của khách khi hội thoại còn thiếu.
            <para>
            Webhook của Zalo chỉ gửi định danh người gửi, không gửi tên (đo được ngày 2026-08-26),
            nên không có bước này thì cột tên trong danh sách hội thoại rỗng với MỌI hội thoại thật.
            </para>
            <para>
            Chỉ gọi khi đang thiếu tên: quota API hồ sơ của nền tảng có hạn, và tên khách hầu như
            không đổi. Lõi không biết nền tảng nào — nó hỏi qua <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.Messengers.IPlatformMessenger"/>,
            đúng điểm mở rộng mà Facebook ở giai đoạn E sẽ cắm vào.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.DeliveryRank(Lada.Framework.Data.Enums.ChatDeliveryStatus)">
            <summary>
            Thứ hạng trên thang tiến của trạng thái giao nhận.
            <see cref="F:Lada.Framework.Data.Enums.ChatDeliveryStatus.Failed"/> nằm NGOÀI thang (hạng 0) nên một báo nhận
            thật từ nền tảng vẫn sửa được tin từng bị đánh dấu thất bại.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.SocialChatService.Truncate(System.String,System.Int32)">
            <summary>
            Cắt chuỗi cho vừa độ dài cột. Dữ liệu do bên thứ ba gửi tới nên không được tin độ dài.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser">
            <summary>
            Đọc webhook của Facebook Messenger (Page).
            <para>
            Viết theo tài liệu Graph API đọc ngày 2026-08-27 tại <c>developers.facebook.com</c>
            (Messenger Platform → Webhooks, message_echoes, message_deliveries, message_reads).
            </para>
            <para>
            Toàn bộ hiểu biết riêng của Facebook dừng lại ở lớp này — lõi chat không biết Facebook là gì.
            Ba điểm khác Zalo phải nhớ, vì đọc nhầm là gắn hội thoại sai người:
            </para>
            <list type="number">
            <item>Chữ ký là <b>HMAC</b>-SHA256 trên thân thô với App Secret, header <c>X-Hub-Signature-256</c>,
            giá trị có tiền tố <c>sha256=</c> — không phải băm nối chuỗi như Zalo.</item>
            <item>Vai <c>sender</c>/<c>recipient</c> ở hai sự kiện giao nhận <b>ngược hẳn Zalo</b>:
            Facebook để người dùng ở <c>sender</c> và Page ở <c>recipient</c> cho cả
            <c>delivery</c> lẫn <c>read</c>; chỉ có <c>message_echoes</c> mới đảo vai.</item>
            <item>Có thêm bước bắt tay <b>GET</b> (<c>hub.challenge</c>) mà Zalo không có.</item>
            </list>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.SignatureHeader">
            <summary>Tên header mang chữ ký của Facebook</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.SignaturePrefix">
            <summary>Tiền tố bắt buộc của giá trị chữ ký</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.SubscribeMode">
            <summary>Giá trị <c>hub.mode</c> duy nhất Facebook gửi khi đăng ký webhook</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser._ownAppId">
            <summary>
            Định danh ứng dụng Facebook của LADA, dùng để nhận ra tiếng vọng của chính mình.
            Bỏ trống thì mọi tiếng vọng đều được lưu và việc chống trùng dồn hết cho lõi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.#ctor(System.String)">
            <param name="ownAppId">
            App ID của LADA (<c>SocialChat:Facebook:AppId</c>). Xem <see cref="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.ParseEcho(System.Text.Json.JsonElement,System.Text.Json.JsonElement,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.SkippedEvent})"/> để biết vì sao cần.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.VerifySignature(Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookRequestContext,System.String)">
            <summary>
            Kiểm chữ ký theo công thức Facebook công bố:
            <c>X-Hub-Signature-256: sha256=HMAC_SHA256(rawBody, AppSecret)</c>, chữ số hex viết thường.
            <para>
            Đây là HMAC thật, KHÔNG phải băm nối chuỗi như Zalo — đừng đem công thức bên kia sang dùng.
            Khoá ký là <b>App Secret</b> của ứng dụng Facebook, không phải Page Access Token.
            </para>
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.SkippedEvent">
            <summary>
            Một sự kiện bị bỏ qua trong lúc đọc payload, kèm lý do và <b>mức ồn</b> của nó.
            <para>
            Facebook gom nhiều sự kiện vào một request nên không thể trả kết quả ngay tại chỗ bỏ —
            phải nhớ lại rồi tổng hợp ở cuối. Trước bản vá SC-30 danh sách này chỉ là chuỗi lý do,
            nên "bỏ có chủ ý" và "chưa hỗ trợ" trộn làm một và cùng chìm ở mức Debug.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.SkippedEvent.#ctor(Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookIgnoreKind,System.String,System.String)">
            <summary>
            Một sự kiện bị bỏ qua trong lúc đọc payload, kèm lý do và <b>mức ồn</b> của nó.
            <para>
            Facebook gom nhiều sự kiện vào một request nên không thể trả kết quả ngay tại chỗ bỏ —
            phải nhớ lại rồi tổng hợp ở cuối. Trước bản vá SC-30 danh sách này chỉ là chuỗi lý do,
            nên "bỏ có chủ ý" và "chưa hỗ trợ" trộn làm một và cùng chìm ở mức Debug.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.SkippedEvent.ByDesign(System.String,System.String)">
            <summary>Bỏ vì đã quyết định như vậy — nhật ký mức Debug</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.SkippedEvent.Unsupported(System.String,System.String)">
            <summary>Bỏ vì chưa hỗ trợ hoặc payload lạ — nhật ký mức Warning</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.SummarizeSkipped(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.SkippedEvent})">
            <summary>
            Gộp danh sách bỏ qua thành một kết quả. Chỉ cần <b>một</b> sự kiện chưa hỗ trợ trong cả
            request là kết quả lên mức Warning — thà ồn một lần còn hơn để nó lẫn vào giữa những
            sự kiện bỏ có chủ ý rồi không ai thấy.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.IsValidVerifyRequest(System.String,System.String,System.String)">
            <summary>
            Kiểm bước bắt tay GET mà Facebook gọi đúng một lần lúc khai báo webhook trên cổng:
            <c>GET ?hub.mode=subscribe&amp;hub.verify_token=…&amp;hub.challenge=…</c>. Khớp thì phải
            trả về nguyên văn <c>hub.challenge</c> kèm HTTP 200, không khớp thì 403.
            <para>
            Zalo không có bước này. So sánh hằng thời gian vì <c>verify token</c> là một bí mật
            dùng lại nhiều lần — Facebook gọi lại bước này mỗi lần đổi URL webhook.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.ParseReaction(System.Text.Json.JsonElement,System.Text.Json.JsonElement,System.String,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.MessageReactionUpdate},System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.SkippedEvent})">
            <summary>
            Đọc một sự kiện thả/gỡ biểu tượng cảm xúc (field <c>message_reactions</c>, SC-29).
            <para>
            Vai sender/recipient giống hệt nhóm giao nhận: <b>khách ở <c>sender</c></b>, Page ở
            <c>recipient</c> — ngược với Zalo, nơi OA nằm ở <c>sender</c> của sự kiện tương ứng.
            </para>
            <para>
            Ưu tiên trường <c>emoji</c> hơn trường <c>reaction</c>: Messenger cho người dùng đổi bộ
            biểu tượng, và khi họ thả một biểu tượng ngoài bộ mặc định thì <c>reaction</c> chỉ còn
            là chuỗi <c>"other"</c> trong khi <c>emoji</c> vẫn mang đúng ký tự. Đọc theo
            <c>reaction</c> là dồn hết những lần thả ấy vào một nhánh sai.
            </para>
            <para>
            🔴 <b>Hai điều chưa đo.</b> (a) Field này CHƯA bật trên cổng App — đo
            <c>GET /{app-id}/subscriptions</c> ngày 2026-08-27 chỉ thấy 3 field, nên tới giờ chưa
            một sự kiện thật nào đi qua nhánh này; phải bật ở CẢ HAI tầng (subscription cấp App và
            <c>subscribed_apps</c> của từng Page) rồi mới có lưu lượng. (b) Tài liệu chỉ mô tả chiều
            "khách thả cảm xúc lên tin của Page"; khách thả lên tin của chính khách thì tài liệu im
            lặng — nhánh dưới xử lý được cả hai vì nó tra tin theo mã, nhưng đừng coi đó là bằng
            chứng nền tảng có gửi.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.ReadRepliedMessageId(System.Text.Json.JsonElement)">
            <summary>
            Mã tin gốc của một tin trả lời trích dẫn: Facebook để ở <c>message.reply_to.mid</c>,
            và cũng <b>chỉ gửi MÃ, không gửi nội dung</b> — cùng hình dạng với
            <c>quote_msg_id</c> của Zalo, nên một trường chuẩn hoá phủ được cả hai (SC-27).
            <para>
            Payload còn có <c>reply_to.is_self_reply</c> (khách trả lời chính tin của mình).
            Chưa đọc: chiều của tin gốc đã suy ra được từ bản ghi trong DB, thêm một trường nữa
            chỉ để nói lại điều đó là thừa.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.NoticeForEntryWithoutMessaging(System.Text.Json.JsonElement)">
            <summary>
            Ghi nhận một <c>entry</c> không mang mảng <c>messaging</c>, gọi đúng tên thứ nó mang.
            <c>changes</c> là field trang (feed/mention…) — ngoài phạm vi chat, bỏ có chủ ý;
            <c>standby</c> là hội thoại đang do ứng dụng khác cầm lái, LADA chưa hỗ trợ bàn giao.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.ParseUserMessage(System.Text.Json.JsonElement,System.Text.Json.JsonElement,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.SkippedEvent})">
            <summary>
            Khách nhắn vào Page: <c>sender</c> là người dùng (PSID), <c>recipient</c> là Page.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.ParseEcho(System.Text.Json.JsonElement,System.Text.Json.JsonElement,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.SkippedEvent})">
            <summary>
            Tiếng vọng của tin do Page gửi ra (<c>message_echoes</c>). Vai ĐẢO so với tin khách gửi:
            <c>sender</c> là Page, <c>recipient</c> là người dùng.
            <para>
            Facebook cho một thứ mà Zalo không có: trường <c>app_id</c> nói rõ tin đi ra từ ứng dụng
            nào. Tiếng vọng của chính LADA bị bỏ ngay tại đây, vì tin ấy đã nằm trong database từ lúc
            bấm gửi — giữ lại chỉ để lõi phải đối chiếu lại lần nữa, và đường đối chiếu theo nội dung
            có một khe hẹp không đóng được (chú thích ảnh của LADA đi thành một tin văn bản riêng,
            mang mã tin khác mã đã lưu, nên nó sẽ hiện thành bong bóng thứ hai).
            </para>
            <para>
            Tiếng vọng của ứng dụng KHÁC thì giữ — đó chính là câu trả lời nhân viên gõ trong hộp thư
            của Page (tài liệu ghi rõ: từ Graph API v12.0, tin gửi từ Page inbox mang
            <c>app_id = 26390203743090</c>). Không lưu chúng thì khung chat thiếu hẳn một nửa cuộc
            trò chuyện — đúng lý do sổ nợ SC-8 tồn tại.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.ParseDelivery(System.Text.Json.JsonElement,System.Text.Json.JsonElement,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryStatusUpdate},System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryWatermarkUpdate},System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.SkippedEvent})">
            <summary>
            Tin đã tới máy khách. Khác Zalo ở chỗ định danh kênh nằm ở <c>recipient.id</c>:
            Facebook giữ nguyên vai "người dùng là sender" cho cả sự kiện giao nhận.
            <para>
            <c>delivery.mids</c> là tuỳ chọn (tài liệu ghi "may not be present", và E3.1 đã bắt được
            gói thật chỉ mang <c>watermark</c> — tin rơi vào gói đó kẹt ở "Đã gửi" vĩnh viễn, SC-25).
            Vì vậy đọc CẢ HAI: cập nhật đích danh cho từng <c>mid</c> có mặt, và một mốc
            <c>watermark</c> quét những tin mà gói sự kiện không nêu tên.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.ParseRead(System.Text.Json.JsonElement,System.Text.Json.JsonElement,System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryWatermarkUpdate},System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.SkippedEvent})">
            <summary>
            Khách đã xem — <c>read.watermark</c>: mọi tin gửi trước mốc này đã được xem, không có
            danh sách mã tin nào (SC-3). Nhánh này chạy được nhưng field <c>message_reads</c> phải
            được bật ở CẢ HAI tầng đăng ký (App subscription lẫn <c>subscribed_apps</c> của từng
            Page) thì sự kiện mới về.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.TryReadWatermark(System.Text.Json.JsonElement,System.Text.Json.JsonElement,System.String,Lada.Framework.Data.Enums.ChatDeliveryStatus,Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryWatermarkUpdate@)">
            <summary>
            Dựng một cập nhật theo mốc từ khối <c>delivery</c>/<c>read</c>. Người dùng lấy từ
            <c>sender.id</c> — Facebook để NGƯỜI DÙNG ở <c>sender</c> cho cả hai sự kiện giao nhận
            (ngược hẳn Zalo, xem §7 mục 33 của plan). Thiếu người dùng hay thiếu mốc thì không dựng:
            một mốc không khoanh được hội thoại là một mốc nâng nhầm tin của khách khác.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.ResolveContentType(System.Text.Json.JsonElement,System.Text.Json.JsonElement)">
            <summary>
            Loại nội dung suy từ <c>attachments[0].type</c>; không có đính kèm thì là văn bản.
            <para>
            Nhãn dán của Facebook về dưới dạng đính kèm <c>image</c> kèm trường <c>sticker_id</c> —
            tên loại không phân biệt được, phải nhìn trường đó. <b>Nhưng lưu lượng thật đo được ngày
            2026-08-27 (Graph v26.0) đặt trường ấy ở chỗ khác tài liệu:</b> <c>sticker_id</c> nằm
            trong <c>attachments[0].payload</c>, còn cấp <c>message</c> thì KHÔNG có; kèm theo đó
            Facebook gửi thêm <c>attachments[1]</c> mang <c>type = "sticker"</c>. Vì vậy phải hỏi cả
            ba chỗ — hỏi mỗi cấp <c>message</c> là nhãn dán ra "Hình ảnh" một cách im lặng.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.HasStickerId(System.Text.Json.JsonElement)">
            <summary>
            Có trường <c>sticker_id</c> đọc được ở đối tượng này không. Facebook trả nó khi thì là số,
            khi thì là chuỗi, nên nhận cả hai kiểu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.ResolveContent(System.Text.Json.JsonElement,System.Text.Json.JsonElement)">
            <summary>
            Phần chữ hiển thị trên khung chat.
            <para>
            Quy ước phải giống hệt Zalo, vì giao diện chỉ có một cách vẽ: <b>chỉ trả về thứ đọc
            được như một câu</b>. Đường dẫn tệp đi ở <c>AttachmentUrl</c> chứ KHÔNG đi ở đây —
            đổ nó vào nội dung thì bong bóng ảnh mọc thêm một dòng URL fbcdn dài ngoằng bên dưới
            tấm ảnh, và cột xem trước ở danh sách hội thoại hiện nguyên đường dẫn thay vì
            "[Hình ảnh]" (nhãn đó do lõi tự đặt khi nội dung rỗng).
            </para>
            <para>
            Toạ độ trả về đúng định dạng <c>"vĩ độ,kinh độ"</c> mà giao diện đang dựng liên kết
            bản đồ — Facebook đặt tên trường là <c>lat</c>/<c>long</c> chứ không phải
            <c>latitude</c>/<c>longitude</c> như Zalo.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.ResolveAttachmentUrl(System.Text.Json.JsonElement)">
            <summary>
            Đường dẫn tệp do Facebook cung cấp. Đường dẫn này CÓ THỜI HẠN (sổ nợ SC-9),
            giai đoạn này vẫn chỉ lưu lại chứ chưa tải tệp về máy chủ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.ReadTimestamp(System.Text.Json.JsonElement)">
            <summary>
            Facebook gửi <c>timestamp</c> dạng số mili giây ở cấp sự kiện. Không đọc được thì lấy
            giờ hiện tại để tin nhắn vẫn vào đúng chỗ thay vì rơi về năm 1970.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.FacebookWebhookParser.GetString(System.Text.Json.JsonElement,System.String)">
            <summary>
            Đọc một trường dạng chuỗi, chấp nhận cả số: Facebook trả <c>app_id</c> và
            <c>sticker_id</c> lúc là số lúc là chuỗi tuỳ phiên bản Graph API.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage">
            <summary>
            Tin nhắn đã được chuẩn hoá về một dạng chung, không còn dấu vết của nền tảng gốc.
            Đây là ranh giới giữa phần đặc thù nền tảng (parser) và lõi chat.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.Platform">
            <summary>Nền tảng gửi tin</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.ExternalChannelId">
            <summary>
            Định danh kênh phía nền tảng (OA id / Page id) lấy từ payload.
            Đây CHỈ là gợi ý để tra kênh trong DB — không bao giờ dùng làm căn cứ tin cậy.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.ExternalUserId">
            <summary>Định danh người dùng phía nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.Direction">
            <summary>
            Chiều của tin so với hệ thống. Mặc định là <see cref="F:Lada.Framework.Data.Enums.ChatMessageDirection.Inbound"/> —
            khách gửi vào.
            <para>
            Có chiều <see cref="F:Lada.Framework.Data.Enums.ChatMessageDirection.Outbound"/> ở đây vì một lý do rất thật: nhân
            viên vẫn trả lời khách từ CHÍNH ứng dụng Zalo OA trên điện thoại, và nền tảng báo việc
            đó về bằng sự kiện <c>oa_send_*</c>. Không lưu chúng thì khung chat hiện một cuộc trò
            chuyện thiếu hẳn một nửa — câu hỏi của khách có, câu trả lời không.
            </para>
            <para>
            Parser là nơi biết sự kiện nào thuộc chiều nào; lõi chỉ đọc trường này. Đừng suy chiều
            từ việc so <c>ExternalUserId</c> với định danh kênh trong lõi — đó là kiến thức nền tảng.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.ExternalUserName">
            <summary>Tên người dùng nếu payload có mang theo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.AvatarUrl">
            <summary>Ảnh đại diện người dùng nếu payload có mang theo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.ContentType">
            <summary>Loại nội dung</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.Content">
            <summary>Nội dung văn bản hoặc mô tả của tin đa phương tiện</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.AttachmentUrl">
            <summary>Đường dẫn tệp đính kèm do nền tảng cung cấp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.ExternalMessageId">
            <summary>Định danh tin nhắn phía nền tảng — dùng chống lưu trùng khi webhook được gửi lại</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.ReplyToExternalMessageId">
            <summary>
            Mã tin gốc mà tin này trả lời trích dẫn, nếu payload có mang.
            Zalo đặt ở <c>message.quote_msg_id</c>, Facebook ở <c>message.reply_to.mid</c> —
            hai chỗ khác nhau, cùng một ý nghĩa, nên chuẩn hoá về đúng một trường (SC-27).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.ExternalConversationId">
            <summary>
            Định danh hội thoại phía nền tảng, chỉ điền khi nền tảng đòi HAI mã để gửi tin ngược lại.
            <para>
            Parser là nơi biết điều đó; lõi chỉ chép xuống <c>ChatConversation</c> rồi chuyển tiếp
            lại cho tầng nền tảng khi gửi. Nền tảng nào chỉ cần một mã thì để trống (SC-28).
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.IsAnonymous">
            <summary>
            Người gửi là khách ẩn danh — nền tảng không cấp định danh bền vững cho họ.
            <para>
            Parser đặt cờ này vì chỉ parser biết sự kiện nào thuộc luồng ẩn danh. Lõi dùng nó để
            đánh dấu hội thoại, và giao diện dựa vào đó để không mời gắn khách hàng.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.ExternalAdminId">
            <summary>
            Định danh admin của nền tảng đã gõ tin, khi tin chiều ra được gõ từ ứng dụng quản trị
            của nền tảng chứ không qua LADA (SC-26).
            <para>
            Zalo đặt <c>sender.admin_id</c> trong sự kiện <c>oa_send_*</c> CHỈ khi tin gõ tay từ
            cửa sổ chat OA Admin — tin LADA gửi qua Open API không có trường này, và nhánh ẩn danh
            (<c>oa_send_anonymous_*</c>) cũng không (đo thật 2026-08-27). Facebook không có gì
            tương đương, để trống.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.Timestamp">
            <summary>Thời điểm nền tảng ghi nhận tin nhắn</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryStatusUpdate">
            <summary>
            Một cập nhật trạng thái giao nhận do nền tảng báo về (đã nhận / đã xem).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryStatusUpdate.ExternalChannelId">
            <summary>
            Định danh kênh phía nền tảng mà cập nhật này thuộc về.
            <para>
            Cũng chỉ là gợi ý như <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage.ExternalChannelId"/>: lõi vẫn phải
            tra kênh trong DB. Bắt buộc có để cập nhật giao nhận đi qua đúng cổng kiểm tra như
            tin nhắn — thiếu nó thì ai cũng đổi được trạng thái tin của kênh bất kỳ.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryStatusUpdate.ExternalMessageId">
            <summary>Định danh tin nhắn phía nền tảng cần cập nhật</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryStatusUpdate.Status">
            <summary>Trạng thái mới</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryWatermarkUpdate">
            <summary>
            Một cập nhật giao nhận theo MỐC THỜI GIAN: mọi tin chiều ra của hội thoại gửi trước mốc
            này đã đạt <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryWatermarkUpdate.Status"/>. Đây là hình dạng mà <c>watermark</c> của Facebook diễn đạt
            (<c>message_deliveries</c> có thể về KHÔNG kèm <c>mids</c>, <c>message_reads</c> thì không
            bao giờ có mã tin) — sổ nợ SC-25 / SC-3, quyết định nới lõi ghi ở §6.11 của plan.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryWatermarkUpdate.ExternalChannelId">
            <summary>
            Định danh kênh phía nền tảng — cùng vai trò gợi-ý-phải-tra-lại như
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryStatusUpdate.ExternalChannelId"/>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryWatermarkUpdate.ExternalUserId">
            <summary>
            Định danh người dùng phía nền tảng, để khoanh đúng MỘT hội thoại. Một mốc thời gian
            không có phạm vi hội thoại là một mốc nâng nhầm tin của khách khác.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryWatermarkUpdate.Watermark">
            <summary>Mốc thời gian: tin chiều ra gửi TRƯỚC HOẶC BẰNG mốc này đã đạt trạng thái đích</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryWatermarkUpdate.Status">
            <summary>Trạng thái đích (Delivered với delivery, Read với read)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.MessageReactionUpdate">
            <summary>
            Một lần thả (hoặc gỡ) biểu tượng cảm xúc lên một tin nhắn đã có.
            <para>
            Đi thành một hợp đồng riêng chứ không thành <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage"/>: thả cảm xúc là
            <b>thuộc tính của một tin đã có</b>, không phải tin mới. Ép nó thành tin thì mỗi lần khách
            thả một trái tim sẽ mọc thêm một bong bóng rác giữa cuộc trò chuyện và cột xem trước của
            danh sách hội thoại hiện "[Tin nhắn]" — lý lẽ này ghi ở §4 GĐ F1 từ hồi mục SC-29 còn mang
            quyết định "không làm", và nó vẫn đúng nguyên sau khi quyết định đảo chiều.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.MessageReactionUpdate.ExternalChannelId">
            <summary>
            Định danh kênh phía nền tảng — cùng vai trò gợi-ý-phải-tra-lại như ở
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryStatusUpdate.ExternalChannelId"/>. Bắt buộc có để cập nhật cảm xúc đi
            qua đúng cổng kiểm kênh như tin nhắn và giao nhận.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.MessageReactionUpdate.ExternalUserId">
            <summary>
            Định danh người dùng phía nền tảng, để khoanh đúng MỘT hội thoại. Không có nó thì một mã
            tin trùng sẽ gắn cảm xúc vào tin của khách khác.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.MessageReactionUpdate.ExternalMessageId">
            <summary>Định danh tin nhắn được thả cảm xúc, phía nền tảng</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.MessageReactionUpdate.Emoji">
            <summary>
            Biểu tượng cảm xúc dạng <b>ký tự emoji thật</b>, đã được tầng nền tảng dịch từ mã riêng
            của nó. <c>null</c> khi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.MessageReactionUpdate.IsRemoved"/> bật.
            <para>
            Parser nào không dịch được mã của mình sang emoji thì <b>không được</b> dựng bản ghi này
            — hãy ghi nhật ký kèm chính mã đó. Để mã thô đi tiếp là nó chảy vào database rồi ra tới
            màn hình dưới dạng chữ, đúng bẫy SC-34.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.MessageReactionUpdate.IsRemoved">
            <summary>Người dùng GỠ cảm xúc đã thả, thay vì thả một cái mới</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.MessageReactionUpdate.ByChannelOwner">
            <summary>
            Cảm xúc này do <b>phía OA/Page</b> thả (Zalo <c>oa_reacted_message</c>), chứ không phải
            khách. Quyết định cảm xúc rơi vào cột nào của tin.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookIgnoreKind">
            <summary>
            Vì sao một payload webhook bị bỏ qua. Phân biệt hai loại này là toàn bộ giá trị của
            <c>SC-30</c>: gộp chung một mức nhật ký thì mọi sự kiện nền tảng gửi mà LADA chưa hỗ trợ
            đều biến mất không để lại dấu vết, và hệ thống hỏng CÂM trên production.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookIgnoreKind.ByDesign">
            <summary>
            Bỏ có chủ ý: hệ thống BIẾT sự kiện này và đã quyết định không xử lý — tiếng vọng của
            chính LADA, <c>message_reads</c> theo §6.11, sự kiện nằm ngoài phạm vi phiên bản 1.
            Ghi nhật ký mức Debug là đủ.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookIgnoreKind.Unsupported">
            <summary>
            Sự kiện nền tảng gửi mà LADA CHƯA hỗ trợ, hoặc payload có hình dạng lạ. Đây là thứ
            phải nhìn thấy được từ nhật ký production — nâng lên mức Warning.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult">
            <summary>
            Kết quả đọc một payload webhook. Một payload rơi vào đúng một trong ba trường hợp:
            mang tin nhắn mới, mang cập nhật trạng thái giao nhận, hoặc là sự kiện hệ thống chưa hỗ trợ.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult.Messages">
            <summary>Danh sách tin nhắn đọc được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult.DeliveryUpdates">
            <summary>Danh sách cập nhật trạng thái giao nhận đọc được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult.WatermarkUpdates">
            <summary>
            Danh sách cập nhật giao nhận theo mốc thời gian (SC-25 / SC-3). Đi song song với
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult.DeliveryUpdates"/>: một sự kiện delivery của Facebook có thể sinh CẢ HAI —
            cập nhật đích danh cho các <c>mids</c> có mặt, và một mốc quét cho những tin mà gói
            sự kiện không nêu tên.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult.ReactionUpdates">
            <summary>
            Danh sách lần thả/gỡ biểu tượng cảm xúc đọc được. Cũng đi song song với các danh sách
            trên vì Facebook gom nhiều sự kiện vào một request.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult.IsIgnored">
            <summary>
            Payload hợp lệ nhưng hệ thống cố ý không xử lý (ví dụ sự kiện quan tâm/bỏ quan tâm OA).
            Đây KHÔNG phải lỗi — webhook vẫn trả 200.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult.IgnoreReason">
            <summary>Lý do bỏ qua, để ghi nhật ký</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult.IgnoreKind">
            <summary>
            Loại bỏ qua — quyết định mức nhật ký ở lõi. Mặc định là <see cref="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookIgnoreKind.ByDesign"/>
            để một nhánh bỏ qua viết thiếu suy nghĩ vẫn im lặng; nhánh nào muốn ồn phải nói ra.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult.EventName">
            <summary>
            Tên sự kiện đọc được từ payload, để nhật ký gọi đúng tên thứ đang rơi.
            Không đọc được thì để trống.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult.UnsupportedNotices">
            <summary>
            Sự kiện chưa hỗ trợ nằm LẪN trong một payload mà phần còn lại đọc được bình thường.
            <para>
            Cần vì Facebook gom nhiều sự kiện vào một request: chỉ báo động khi cả payload không
            đọc được gì là bỏ sót đúng đường thường gặp nhất — một tin khách bình thường đi kèm
            một sự kiện lạ thì sự kiện lạ đó biến mất không dấu vết. Lõi ghi Warning cho từng mục
            ở đây, độc lập với <see cref="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult.IsIgnored"/>.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult.Ok(Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.NormalizedMessage[])">
            <summary>Payload mang tin nhắn mới</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult.Delivery(Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.DeliveryStatusUpdate[])">
            <summary>Payload mang cập nhật trạng thái giao nhận</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult.Ignore(System.String,System.String)">
            <summary>
            Payload hệ thống BIẾT và cố ý không xử lý. Nhật ký mức Debug.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookParseResult.Unsupported(System.String,System.String)">
            <summary>
            Payload mang sự kiện chưa hỗ trợ hoặc có hình dạng lạ. Nhật ký mức Warning, kèm tên
            sự kiện — đây là đường duy nhất để biết nền tảng đang gửi thứ gì mà LADA đang bỏ rơi.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookRequestContext">
            <summary>
            Toàn bộ dữ liệu thô của một request webhook, đủ để mọi nền tảng tự kiểm chữ ký theo cách riêng.
            <para>
            Mang cả header vì mỗi nền tảng cần thứ khác nhau: Zalo cần <c>X-ZEvent-Signature</c>
            (chữ ký nối chuỗi kèm dấu thời gian nằm trong thân), Facebook cần <c>X-Hub-Signature-256</c>
            (HMAC). Giữ nguyên hình dạng này để thêm nền tảng mới không phải đổi giao diện.
            </para>
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookRequestContext.RawBody">
            <summary>Thân request nguyên văn — chữ ký tính trên chuỗi này, không phải trên object đã parse</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookRequestContext.Headers">
            <summary>Toàn bộ header của request, tra không phân biệt hoa thường</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookRequestContext.Header(System.String)">
            <summary>Lấy một header, trả chuỗi rỗng nếu không có</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.IWebhookParser">
            <summary>
            Điểm mở rộng chiều NHẬN TIN. Mỗi nền tảng hiện thực đúng một lớp này.
            Thêm nền tảng mới = thêm một lớp, KHÔNG sửa lõi.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.IWebhookParser.Platform">
            <summary>Nền tảng mà parser này phụ trách</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.IWebhookParser.Parse(System.String)">
            <summary>Đọc payload thô thành kết quả chuẩn hoá</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.IWebhookParser.VerifySignature(Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookRequestContext,System.String)">
            <summary>
            Kiểm chữ ký của request theo đúng công thức nền tảng quy định.
            Không bao giờ được trả <c>true</c> vô điều kiện.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser">
            <summary>
            Đọc webhook của Zalo Official Account.
            <para>
            Viết theo tài liệu chính thức đọc ngày 2026-08-26 tại
            <c>developers.zalo.me/docs/official-account/webhook/…</c> (nội dung thật nằm ở
            <c>stc-developers.zdn.vn/docs/v2/…/index.html</c>).
            </para>
            <para>
            Toàn bộ hiểu biết riêng của Zalo dừng lại ở lớp này — lõi chat không biết Zalo là gì.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser.SignatureHeader">
            <summary>Tên header mang chữ ký của Zalo</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser.RetryHeader">
            <summary>Tên header Zalo dùng để báo đây là lần gửi lại thứ mấy</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser.KnownOutOfScopeEvents">
            <summary>
            Sự kiện Zalo có gửi mà LADA <b>cố ý</b> chưa xử lý ở phiên bản 1. Danh sách này tồn tại
            để tách khỏi nhánh "chưa từng lường tới": tên nằm trong đây thì nhật ký im ở mức Debug,
            tên lạ thì lên mức Warning (sổ nợ SC-30).
            <para>
            Thêm tên vào đây là một <b>quyết định</b>, không phải thao tác dọn nhật ký. Chỉ thêm khi
            đã đối chiếu danh sách sự kiện trên cổng nhà phát triển và kết luận rằng LADA không cần
            sự kiện đó — kèm lý do trong sổ nợ.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser.VerifySignature(Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.WebhookRequestContext,System.String)">
            <summary>
            Kiểm chữ ký theo công thức Zalo công bố:
            <c>mac = sha256(appId + data + timeStamp + OASecretKey)</c>, trong đó <c>data</c> là
            nguyên văn chuỗi JSON của thân request, còn <c>appId</c> và <c>timeStamp</c> lấy từ
            chính thân request đó.
            <para>
            Đây là băm nối chuỗi, KHÔNG phải HMAC — đừng đem công thức của Facebook sang dùng.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser.ParseMessage(System.Text.Json.JsonElement,System.String,System.Boolean,System.Boolean)">
            <summary>
            Đọc một sự kiện mang tin nhắn. Bốn luồng của Zalo dùng chung hàm này vì chúng chỉ khác
            nhau ở hai chỗ: <b>ai đứng ở vai <c>sender</c></b> và <b>khách có ẩn danh hay không</b>.
            </summary>
            <param name="oaIsSender">
            <c>true</c> với sự kiện <c>oa_send_*</c>: vai <c>sender</c>/<c>recipient</c> ĐẢO so với
            sự kiện khách gửi — OA là bên gửi, người dùng là bên nhận, giống hệt hai sự kiện giao
            nhận. Lấy nhầm chiều là gắn hội thoại vào định danh của chính OA (§7 mục 33).
            <para>
            Sự kiện <c>oa_send_*</c> về webhook cả khi tin đi từ LADA lẫn khi nhân viên trả lời từ
            chính ứng dụng Zalo OA — nhánh thứ hai là lý do phải xử lý (sổ nợ SC-8): không có nó
            thì khung chat thiếu hẳn những câu trả lời gõ ngoài SPA.
            </para>
            </param>
            <param name="isAnonymous">
            <c>true</c> với luồng ẩn danh (<c>anonymous_send_*</c> và <c>oa_send_anonymous_*</c>).
            Khi đó payload mang thêm <c>message.conversation_id</c>, và API gửi tin đòi CẢ HAI mã.
            <c>user_id_by_app</c> cũng có trong payload nhưng đo thật thấy nó ĐỔI giữa hai phiên
            widget nên không dùng làm khoá hội thoại được.
            </param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser.ReadQuotedMessageId(System.Text.Json.JsonElement,System.Text.Json.JsonElement)">
            <summary>
            Mã tin gốc của một tin trả lời trích dẫn. Zalo <b>chỉ gửi MÃ, không gửi nội dung</b> —
            nội dung được tra ngược ở tầng dịch vụ theo cặp (hội thoại, mã tin).
            <para>
            Hỏi CẢ HAI cấp có chủ ý: sổ nợ SC-27 ghi trường này nằm ở <c>message.quote_msg_id</c>,
            còn tài liệu Zalo đọc lại 2026-08-27 nói *"trong data có thêm quote_msg_id"* — tức cấp
            gốc payload. Hai nguồn không khớp nhau và chưa có payload thật để phân xử, nên hỏi cả
            hai chỗ; đúng bài học §7 mục 36 của nhãn dán Facebook (tài liệu chỉ một chỗ, lưu lượng
            thật lại đặt ở chỗ khác). Tin thường không có trường này ở đâu cả, trả về <c>null</c>.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser.ParseReaction(System.Text.Json.JsonElement,System.String,System.Boolean)">
            <summary>
            Đọc một sự kiện thả biểu tượng cảm xúc (<c>user_reacted_message</c> /
            <c>oa_reacted_message</c>). Payload mang <c>message.msg_id</c> và <c>message.react_icon</c>.
            <para>
            🔴 <b>Giới hạn của chính nền tảng, phải nhớ khi đọc số liệu:</b> tài liệu Zalo ghi nguyên
            văn rằng sự kiện này <b>chỉ được gửi về khi người dùng nhận tin trên Zalo Mobile</b>.
            Khách thả cảm xúc trên Zalo PC/Web thì OA không nhận được gì. Vì thế cột cảm xúc của
            kênh Zalo <b>không</b> phản ánh đầy đủ những gì khách đã thả — đừng đọc nó như một phép
            đếm.
            </para>
            <para>
            Tài liệu không mô tả riêng chiều GỠ, nhưng mã <c>/-remove</c> là mã Zalo dùng cho việc
            gỡ ở chiều gửi nên nhánh này nhận nó thành <c>IsRemoved</c> — thiếu thì mọi lần khách gỡ
            cảm xúc rơi vào "mã lạ" và huy hiệu cũ nằm lại màn hình vĩnh viễn.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser.ReadDeliveryChannelId(System.Text.Json.JsonElement)">
            <summary>
            Định danh kênh của hai sự kiện giao nhận nằm ở <c>sender.id</c> — ở các sự kiện này
            OA là bên GỬI còn người dùng là bên NHẬN, ngược hẳn với sự kiện khách gửi tin.
            Lấy nhầm sang <c>recipient.id</c> là tra ra định danh người dùng chứ không phải kênh.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser.ResolveContentType(System.String,System.Text.Json.JsonElement)">
            <summary>
            Loại nội dung ưu tiên lấy theo <c>attachments[0].type</c> vì tên sự kiện không đủ chi tiết
            (ảnh GIF cũng về bằng <c>user_send_image</c>), chỉ khi không có đính kèm mới suy từ tên sự kiện.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser.ResolveContent(System.Text.Json.JsonElement,System.Text.Json.JsonElement)">
            <summary>
            Phần chữ hiển thị trên khung chat. Tin văn bản lấy <c>message.text</c>;
            tin đa phương tiện lấy thứ mô tả được nó (tên tệp, mô tả liên kết, toạ độ).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser.ResolveAttachmentUrl(System.Text.Json.JsonElement)">
            <summary>
            Đường dẫn tệp gốc do Zalo cung cấp. Giai đoạn A chỉ lưu lại đường dẫn,
            chưa tải tệp về máy chủ (đường dẫn của Zalo có thể hết hạn — nợ kỹ thuật đã ghi).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser.ReadSignatureFields(System.String)">
            <summary>
            Lấy <c>app_id</c> và <c>timestamp</c> phục vụ tính chữ ký. Payload thiếu trường nào
            thì phần đó là chuỗi rỗng — chữ ký sẽ không khớp, đúng như mong muốn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser.NormalizeSignature(System.String)">
            <summary>
            Bỏ tiền tố <c>mac=</c> nếu Zalo gửi kèm, và chuẩn hoá về chữ thường.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser.ReadTimestamp(System.Text.Json.JsonElement)">
            <summary>
            Zalo gửi <c>timestamp</c> dạng chuỗi mili giây. Không đọc được thì lấy giờ hiện tại
            để tin nhắn vẫn vào đúng chỗ thay vì rơi về năm 1970.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.WebhookParsers.ZaloWebhookParser.GetString(System.Text.Json.JsonElement,System.String)">
            <summary>
            Đọc một trường dạng chuỗi. Zalo trả <c>timestamp</c> lúc là chuỗi lúc là số
            tuỳ sự kiện, nên chấp nhận cả hai thay vì ném lỗi.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IZaloApiService">
            <summary>
            Lớp duy nhất trong hệ thống biết giao thức của Zalo Official Account API.
            <para>
            Mọi số liệu dưới đây lấy nguyên văn từ tài liệu thật ngày 2026-08-26
            (<c>https://stc-developers.zdn.vn/docs/v2/&lt;đường-dẫn&gt;/index.html</c> — thiếu
            <c>/index.html</c> là nhận vỏ SPA kèm HTTP 200 chứ không phải 404).
            </para>
            <para>
            Lớp này KHÔNG chạm tới database và KHÔNG biết gì về <c>ChatChannel</c>: nó nhận
            access token đã giải mã sẵn và trả về kết quả thô. Việc lấy/lưu token là của
            <c>ChatChannelService</c>, việc ghép vào lõi chat là của <c>ZaloMessenger</c>.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IZaloApiService.BuildAuthorizationLink(System.String)">
            <summary>
            Dựng đường dẫn để admin của OA bấm vào và cấp quyền cho ứng dụng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IZaloApiService.ExchangeCodeAsync(System.String,System.Threading.CancellationToken)">
            <summary>
            Đổi authorization code (hiệu lực 10 phút, dùng một lần) lấy cặp access + refresh token.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IZaloApiService.RefreshAccessTokenAsync(System.String,System.Threading.CancellationToken)">
            <summary>
            Làm mới access token bằng refresh token.
            <para>
            Refresh token của Zalo <b>chỉ dùng được một lần</b>: gọi thành công là bản cũ chết ngay,
            và access token cũ cũng hết hiệu lực lập tức. Mất cặp mới trả về là kênh chết im lặng.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IZaloApiService.SendTextAsync(System.String,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Gửi tin tư vấn dạng văn bản.
            <para>
            <paramref name="quoteMessageId"/> là mã tin nhắn phía Zalo mà tin này TRẢ LỜI TRÍCH DẪN,
            bỏ trống thì gửi tin thường. Tên trường trong thân request là <c>message.quote_message_id</c>
            — <b>không</b> trùng tên với <c>message.quote_msg_id</c> mà webhook gửi về ở chiều ngược
            lại (tài liệu "Gửi tin tư vấn trích dẫn", đọc 2026-08-28). Hai chiều lệch tên nhau là chỗ
            dễ chép nhầm nhất của tính năng này.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IZaloApiService.UploadImageAsync(System.String,System.String,System.Threading.CancellationToken)">
            <summary>Tải một tệp ảnh lên máy chủ Zalo để lấy <c>attachment_id</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IZaloApiService.SendImageAsync(System.String,System.String,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Gửi tin tư vấn đính kèm ảnh. Truyền một trong hai: <paramref name="attachmentId"/>
            (đã tải lên) hoặc <paramref name="imageUrl"/> (đường dẫn công khai).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IZaloApiService.SendAnonymousTextAsync(System.String,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Gửi tin văn bản cho một người dùng ẩn danh. Đòi CẢ HAI mã: <paramref name="anonymousId"/>
            và <paramref name="conversationId"/> — thiếu một là Zalo từ chối.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IZaloApiService.SendAnonymousImageAsync(System.String,System.String,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Gửi ảnh cho một người dùng ẩn danh.
            <para>
            Thân request KHÔNG có chỗ cho chú thích: tài liệu luồng ẩn danh chỉ có
            <c>message.attachment</c>, không có <c>message.text</c> đi kèm. Caller muốn kèm chú thích
            thì phải gửi thành một tin văn bản riêng.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IZaloApiService.SendReactionAsync(System.String,System.String,System.String,System.String,System.Boolean,System.Threading.CancellationToken)">
            <summary>
            Thả (hoặc gỡ) một biểu tượng cảm xúc lên tin nhắn của khách.
            <para>
            Nhận <b>emoji thật</b> chứ không nhận mã Zalo: việc dịch sang <c>react_icon</c> nằm ở
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloReactionCatalog"/>, để mã riêng của Zalo không rò ra khỏi tầng này.
            Emoji ngoài bảng sáu mã của Zalo bị từ chối tại chỗ với một câu đọc được.
            </para>
            <para>
            Đặt <paramref name="isRemove"/> để gỡ biểu tượng đã thả — Zalo không có endpoint xoá
            riêng, gỡ là gửi lại chính lời gọi này với mã <c>/-remove</c>.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IZaloApiService.GetUserProfileAsync(System.String,System.String,System.Threading.CancellationToken)">
            <summary>Lấy tên và ảnh đại diện của một người dùng đã tương tác với OA.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IZaloApiService.GetOaInfoAsync(System.String,System.Threading.CancellationToken)">
            <summary>Lấy thông tin OA đang gắn với access token — dùng để đặt tên kênh sau khi cấp quyền.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.IZaloApiService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.HttpClientName">
            <summary>Tên HttpClient đã đăng ký sẵn ở <c>DependencyRegister</c></summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.SendAnonymousMessageEndpoint">
            <summary>
            Endpoint gửi tin cho người dùng ẩn danh (khách nhắn từ widget web, chưa đăng nhập Zalo).
            <para>
            Vẫn là <b>v2.0</b> có chủ ý: đọc lại tài liệu ngày 2026-08-27 thì Zalo KHÔNG cung cấp bản
            v3 nào cho luồng ẩn danh — <c>/v3.0/oa/message/cs</c> chỉ nhận <c>user_id</c>, không nhận
            <c>anonymous_id</c>. Bảng mã lỗi có <c>-240 "MessageV2 API has been shut down"</c>, nên
            nếu Zalo trả mã đó ở đây thì luồng ẩn danh coi như bị khai tử và KHÔNG có đường vòng;
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloErrorCatalog"/> phải nói được điều đó cho nhân viên đọc.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.ReactionEndpoint">
            <summary>
            Endpoint thả biểu tượng cảm xúc. <b>Trùng URL với đường ẩn danh ở trên là đúng, không
            phải chép nhầm</b> — Zalo gom cả nhóm "các loại tin khác" vào <c>v2.0/oa/message</c> và
            phân biệt bằng thân request (<c>sender_action</c> thay cho <c>message</c>). Khai riêng
            một hằng số để chỗ dùng đọc được ý, và để ngày Zalo tách endpoint thì chỉ sửa một dòng.
            <para>
            🔴 <b>Chưa đo bằng lưu lượng thật.</b> Tài liệu xếp trang này trong nhánh v3 hiện hành
            nhưng vẫn ghi URL v2.0, trong khi bảng mã lỗi có <c>-240 "MessageV2 API has been shut
            down"</c>. Cùng một mâu thuẫn với luồng ẩn danh (§6.12) — và ở đó thì v2.0 gọi thật đã
            thành công. Nhận <c>-240</c> ở đây thì chiều nhân viên thả cảm xúc coi như bị Zalo khai
            tử; chiều NHẬN cảm xúc của khách vẫn chạy vì nó đi bằng webhook.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.MaxTextLength">
            <summary>Giới hạn tài liệu ghi cho nội dung tin tư vấn dạng văn bản</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.MaxImageBytes">
            <summary>Giới hạn tài liệu ghi cho ảnh tải lên: 1 MB, chỉ jpg và png</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.AppSecret">
            <summary>Khoá bí mật của ỨNG DỤNG — gửi ở header <c>secret_key</c> của luồng OAuth.
            Không phải khoá ký webhook (khoá đó là OA Secret Key).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.RedirectUri">
            <summary>Đường dẫn công khai Zalo chuyển hướng về sau khi admin OA đồng ý cấp quyền</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.CodeVerifier">
            <summary>
            Code verifier của PKCE. Zalo giữ code challenge ở cấu hình ứng dụng trên cổng nhà phát triển
            (không truyền theo từng request), nên phía LADA phải giữ đúng một verifier cố định khớp với nó.
            Bỏ trống = cổng không cấu hình code challenge, luồng đổi token không gửi <c>code_verifier</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.BuildAuthorizationLink(System.String)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.ComputeCodeChallenge(System.String,System.Boolean)">
            <summary>
            Tính code challenge từ code verifier: <c>Base64(SHA-256(ASCII(code_verifier)))</c>, bỏ ký tự đệm.
            <para>
            Trả về hai biến thể vì tài liệu Zalo và chuẩn PKCE nói khác nhau ở đúng một chỗ:
            tài liệu ghi "encode Base64 (without Padding)" (bảng chữ cái có <c>+</c> và <c>/</c>),
            còn RFC 7636 quy định base64url (<c>-</c> và <c>_</c>). Chỉ khác nhau khi mã băm sinh ra
            hai ký tự đó, tức là phần lớn trường hợp. Không có cách nào phân xử trên giấy — chủ dự án
            dán giá trị vào cổng nhà phát triển rồi chạy thử là biết ngay cái nào đúng.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.ExchangeCodeAsync(System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.RefreshAccessTokenAsync(System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.PostTokenRequestAsync(System.Collections.Generic.Dictionary{System.String,System.String},System.String,System.Threading.CancellationToken)">
            <summary>
            Gửi một request tới endpoint OAuth và đọc cặp token trong phản hồi.
            Không bao giờ đưa nội dung form (chứa code/refresh token) vào nhật ký hay thông điệp lỗi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.DescribeOAuthError(System.Text.Json.JsonElement,System.Net.HttpStatusCode)">
            <summary>
            Endpoint OAuth không dùng chung khuôn <c>{ data, error, message }</c> với OpenAPI, và tài liệu
            không mô tả hình dạng phản hồi lỗi. Gom mọi tên trường lỗi hay gặp rồi mới lùi về mã HTTP.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.SendTextAsync(System.String,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.SendImageAsync(System.String,System.String,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.SendAnonymousTextAsync(System.String,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.SendAnonymousImageAsync(System.String,System.String,System.String,System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.SendReactionAsync(System.String,System.String,System.String,System.String,System.Boolean,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.ValidateAnonymousRecipient(System.String,System.String)">
            <summary>
            Cả hai mã của người ẩn danh đều bắt buộc. Kiểm ở đây để lỗi nói đúng chuyện đang xảy ra,
            thay vì để Zalo trả một mã lỗi chung rồi nhân viên đọc không hiểu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.PostMessageAsync(System.String,System.Object,System.String,System.Threading.CancellationToken)">
            <summary>
            Gửi một thân request tới endpoint gửi tin. Endpoint là tham số vì luồng ẩn danh dùng
            một đường khác hẳn (v2.0), và phản hồi của nó KHÔNG có <c>quota</c> lẫn <c>sent_time</c> —
            hàm này chỉ đọc <c>data.message_id</c> nên chịu được cả hai hình dạng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.UploadImageAsync(System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.GetUserProfileAsync(System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.GetOaInfoAsync(System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloApiService.GetJsonAsync(System.String,System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Gọi một API đọc của Zalo OpenAPI và trả về phần tử gốc của JSON, hoặc null nếu hỏng.
            Đây là đường phụ trợ (làm giàu hồ sơ, đặt tên kênh) nên hỏng thì chỉ ghi nhật ký chứ không ném.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloAuthorizationLink">
            <summary>Đường dẫn cấp quyền kèm những gì admin cần để khai báo trên cổng nhà phát triển.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloAuthorizationLink.RedirectUri">
            <summary>Đường dẫn callback đã kèm state — phải khai đúng chuỗi này ở mục Callback URL trên cổng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloAuthorizationLink.HasCodeVerifier">
            <summary>Đã cấu hình <c>SocialChat:Zalo:CodeVerifier</c> hay chưa</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloAuthorizationLink.CodeChallengeBase64Url">
            <summary>Code challenge theo chuẩn PKCE (base64url, bỏ ký tự đệm)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloAuthorizationLink.CodeChallengeBase64">
            <summary>Code challenge theo đúng chữ nghĩa tài liệu Zalo (base64 thường, bỏ ký tự đệm)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloTokenResult">
            <summary>Cặp token Zalo trả về sau khi đổi code hoặc làm mới.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloSendResult">
            <summary>Kết quả một lần gửi tin.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloUploadResult">
            <summary>Kết quả tải ảnh lên máy chủ Zalo.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloUserProfile">
            <summary>Hồ sơ rút gọn của một người dùng Zalo.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloOaInfo">
            <summary>Thông tin rút gọn của một Official Account.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloErrorCatalog">
            <summary>
            Dịch mã lỗi của Zalo Official Account API ra tiếng người.
            <para>
            Nội dung lấy từ trang "Mã lỗi Official Account API" đọc ngày 2026-08-26. Chỉ giữ những mã
            một nhân viên chăm sóc khách hàng có thể gặp khi gửi tin — mã lạ thì trả nguyên văn thông
            điệp của Zalo kèm số hiệu, tuyệt đối không nuốt.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloErrorCatalog.Describe(System.Int32,System.String)">
            <summary>
            Trả về mô tả tiếng Việt của một mã lỗi Zalo, kèm số hiệu để tra cứu lại tài liệu.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloReactionCatalog">
            <summary>
            Bảng đổi qua lại giữa <b>biểu tượng cảm xúc</b> mà LADA dùng và <b>mã cảm xúc</b> của Zalo.
            <para>
            Lõi chat nói chuyện bằng emoji thật (ký tự Unicode), tầng nền tảng tự dịch — nếu không thì
            chuỗi <c>"/-strong"</c> sẽ chảy vào DTO rồi ra thẳng màn hình, đúng cái bẫy <b>SC-34</b> đã
            cắn một lần: mã biểu tượng của Zalo lọt vào LADA dưới dạng chữ thô và nhân viên đọc được
            <c>:b:-h</c> thay vì thấy một hình.
            </para>
            <para>
            Bảng này CỐ Ý chỉ có <b>sáu</b> mã — đúng sáu mã mà tài liệu Zalo mô tả kèm ý nghĩa rõ ràng
            (đọc 2026-08-28, trang "Thả biểu tượng cảm xúc vào tin nhắn"). Tài liệu còn nhắc một mã thứ
            bảy là <c>:-h</c> trong ví dụ webhook nhưng <b>hai nguồn mô tả nó khác nhau</b> ("ngại" và
            "vẫy tay"), nên nó KHÔNG có ở đây: đoán sai nghĩa rồi vẽ nhầm một cảm xúc lên màn hình còn
            tệ hơn không vẽ gì. Mã lạ đi vào đường nhận sẽ được ghi nhật ký kèm chính mã đó (sổ nợ
            SC-36), quan sát được lưu lượng thật thì bổ sung vào đây.
            </para>
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloReactionCatalog.RemoveIcon">
            <summary>
            Mã đặc biệt để <b>gỡ</b> biểu tượng cảm xúc đã thả. Zalo không có endpoint xoá riêng —
            gỡ là gửi lại chính lời gọi thả với mã này.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloReactionCatalog.IconByEmoji">
            <summary>Bảng tra emoji → mã Zalo. So khớp theo thứ tự byte, không theo văn hoá.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloReactionCatalog.EmojiByIcon">
            <summary>Bảng tra ngược, dựng từ đúng bảng trên để hai chiều không bao giờ lệch nhau.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloReactionCatalog.SupportedEmojis">
            <summary>
            Sáu biểu tượng nhân viên được phép thả trên một hội thoại Zalo, theo đúng thứ tự hiển thị.
            Giao diện lấy danh sách này từ máy chủ chứ không tự chép lại — chép lại là hai bảng song
            song rồi sẽ lệch, và cái lệch chỉ lộ ra khi Zalo trả lỗi cho một biểu tượng đã bấm được.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloReactionCatalog.ToZaloIcon(System.String)">
            <summary>
            Đổi emoji sang mã Zalo. Trả <c>null</c> khi Zalo không có mã tương ứng — caller phải
            từ chối bằng một câu đọc được, đừng gửi đi một mã bịa.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.SocialChat.ZaloReactionCatalog.ToEmoji(System.String)">
            <summary>
            Đổi mã Zalo sang emoji để hiển thị. Trả <c>null</c> với mã chưa có trong bảng — đường
            nhận webhook phải ghi nhật ký rồi bỏ qua, tuyệt đối không lưu mã thô xuống database.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Training.ICourseService">
            <summary>
            Dịch vụ quản lý khóa học đào tạo.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ICourseService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm khóa học.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ICourseService.GetAll(System.Int32)">
            <summary>
            Lấy tất cả khóa học đang hoạt động (có filter theo quyền user).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ICourseService.GetById(System.Int32)">
            <summary>
            Lấy chi tiết khóa học (bao gồm sections).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ICourseService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Training.CourseModel)">
            <summary>
            Tạo hoặc cập nhật khóa học.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ICourseService.Delete(System.Int32)">
            <summary>
            Xóa khóa học.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ICourseService.GetCoursePermissions(System.Int32)">
            <summary>
            Lấy danh sách PermissionIds được gán cho khóa học.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ICourseService.UpdateCoursePermissions(System.Int32,System.Collections.Generic.List{System.Int32})">
            <summary>
            Cập nhật danh sách Permission cho khóa học.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Training.ILessonService">
            <summary>
            Dịch vụ quản lý bài giảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ILessonService.GetBySectionId(System.Int32)">
            <summary>Lấy danh sách bài giảng của section.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ILessonService.GetByCourseId(System.Int32)">
            <summary>Lấy tất cả bài giảng của khóa học (theo GlobalOrder).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ILessonService.GetStandaloneByCourseId(System.Int32)">
            <summary>Lấy bài giảng độc lập (không thuộc chương nào) của khóa học.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ILessonService.GetLessonItemsByCourseId(System.Int32)">
            <summary>Lấy tất cả LessonItem (lightweight projection) của khóa học - dùng cho Curriculum.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ILessonService.GetById(System.Int32)">
            <summary>Lấy chi tiết bài giảng (bao gồm media).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ILessonService.GetDetailById(System.Int32)">
            <summary>Lấy chi tiết bài giảng kèm media items (cho learner view).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ILessonService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Training.LessonModel)">
            <summary>Tạo hoặc cập nhật bài giảng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ILessonService.Delete(System.Int32)">
            <summary>Xóa bài giảng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ILessonService.Reorder(System.Int32,System.Collections.Generic.List{System.Int32})">
            <summary>Sắp xếp lại thứ tự bài giảng trong section.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ILessonService.ReorderGlobal(System.Int32,System.Collections.Generic.List{System.Int32})">
            <summary>Sắp xếp lại thứ tự toàn bộ bài giảng (GlobalOrder) trong khóa học.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Training.IMediaStorageService">
            <summary>
            Dịch vụ lưu trữ media - thiết kế linh hoạt để mở rộng Cloud Storage sau này.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.IMediaStorageService.UploadMedia(System.Int32,Microsoft.AspNetCore.Http.IFormFile,System.String,System.Int32)">
            <summary>
            Upload file media cho bài giảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.IMediaStorageService.GetByLessonId(System.Int32)">
            <summary>
            Lấy danh sách media của bài giảng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.IMediaStorageService.DeleteMedia(System.Int32)">
            <summary>
            Xóa media.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.IMediaStorageService.ReorderMedia(System.Int32,System.Collections.Generic.List{System.Int32})">
            <summary>
            Sắp xếp lại thứ tự media.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Training.LocalMediaStorageService">
            <summary>
            Lưu trữ media trên local storage (wwwroot/training-media/).
            Khi cần mở rộng sang Cloud Storage, chỉ cần tạo thêm CloudMediaStorageService
            implement IMediaStorageService và thay DI registration.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Training.ISectionService">
            <summary>
            Dịch vụ quản lý section trong khóa học.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ISectionService.GetByCourseId(System.Int32)">
            <summary>
            Lấy danh sách sections của khóa học.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ISectionService.GetById(System.Int32)">
            <summary>
            Lấy chi tiết section.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ISectionService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Training.SectionModel)">
            <summary>
            Tạo hoặc cập nhật section.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ISectionService.Delete(System.Int32)">
            <summary>
            Xóa section.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Training.ISectionService.Reorder(System.Int32,System.Collections.Generic.List{System.Int32})">
            <summary>
            Sắp xếp lại thứ tự sections.
            </summary>
        </member>
        <!-- Badly formed XML comment ignored for member "M:Ladaer.BackEnd.Infrastructures.Services.Training.ISectionService.UpdateGlobalOrder(System.Int32,System.Int32)" -->
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput">
            <summary>
            Đầu vào tính tình trạng một bộ phận — đã gom đủ mọi thứ engine cần, không tra thêm DB.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput.InstalledDate">
            <summary>Ngày lắp bộ phận (mốc tính tuổi thọ theo thời gian)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput.InstalledOdo">
            <summary>ODO của xe lúc lắp; <c>null</c> khi lắp lúc xe chưa có chuỗi ODO nào</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput.EffectiveLifespanKm">
            <summary>Tuổi thọ hiệu lực theo km = <c>LifespanKmOverride ?? loại.DefaultLifespanKm</c></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput.EffectiveLifespanMonths">
            <summary>Tuổi thọ hiệu lực theo tháng = <c>LifespanMonthsOverride ?? loại.DefaultLifespanMonths</c></summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput.WarnBeforeKm">
            <summary>Ngưỡng báo trước theo km — loại bộ phận ghi đè, thiếu thì lấy ngưỡng toàn cục</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput.WarnBeforeDays">
            <summary>Ngưỡng báo trước theo ngày — loại bộ phận ghi đè, thiếu thì lấy ngưỡng toàn cục</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput.StaleOdoDays">
            <summary>Số ngày sau đó coi chuỗi ODO của xe là quá cũ</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput.IsTruckRunning">
            <summary>
            Xe đang chạy hay không (<c>OperatingStatus.Running</c>).
            </summary>
            <remarks>
            Quyết định duy nhất phụ thuộc trường này là có bắn <see cref="F:Lada.Framework.Data.Enums.ComponentAlertLevel.StaleOdo"/>
            hay không — số đo Việc 0 (plan §5.1): 11/16 xe <c>Stop</c> có ODO cũ hơn 30 ngày, bắn cảnh
            báo cho chúng là tạo 11 cảnh báo rác ngay ngày đầu.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput.Odo">
            <summary>ODO hiện tại của xe theo hàm chuẩn <c>ITruckOdoService</c></summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput.From(Lada.Framework.Data.Domains.Trucks.TruckComponent,Lada.Framework.Data.Domains.Trucks.TruckComponentType,Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckOdoInfo,Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceThresholds,System.Boolean)">
            <summary>
            Dựng đầu vào từ bộ phận + loại của nó — <b>nơi duy nhất</b> diễn giải "tuổi thọ hiệu lực"
            và "ngưỡng hiệu lực".
            </summary>
            <remarks>
            Quy tắc giống hệt <c>TruckComponentItem.EffectiveLifespanKm/Months</c> của GĐ A: giá trị
            riêng của bộ phận thắng, thiếu thì lấy mặc định của loại. Ngưỡng cảnh báo cũng vậy: loại
            khai <c>WarnBeforeKm/Days</c> thì dùng của loại, không thì dùng ngưỡng toàn cục AppConfig.
            Cả API tình trạng lẫn job quét đều đi qua đây để hai bên không bao giờ ra số khác nhau.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult">
            <summary>
            Tình trạng tính được của một bộ phận tại một thời điểm.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult.Level">
            <summary>Mức cảnh báo; <c>null</c> nghĩa là chưa cần cảnh báo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult.HasCriteria">
            <summary>Loại bộ phận có khai ít nhất một tiêu chí tuổi thọ (km hoặc tháng)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult.KmTrackable">
            <summary>Tính được tiêu hao theo km hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult.TimeTrackable">
            <summary>Tính được tiêu hao theo thời gian hay không</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult.KmUsed">
            <summary>Số km đã dùng từ lúc lắp; <c>null</c> khi không tính được</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult.KmRemaining">
            <summary>Số km còn lại trước khi hết tuổi thọ; âm nghĩa là đã vượt</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult.DaysUsed">
            <summary>Số ngày đã dùng từ lúc lắp</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult.DaysRemaining">
            <summary>Số ngày còn lại trước khi hết tuổi thọ; âm nghĩa là đã vượt</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult.DueDate">
            <summary>Hạn theo thời gian (ngày lắp + tuổi thọ tháng)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult.KmPercent">
            <summary>Tỷ lệ tiêu hao theo km (%)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult.TimePercent">
            <summary>Tỷ lệ tiêu hao theo thời gian (%)</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult.UsagePercent">
            <summary>
            Tỷ lệ tiêu hao dùng để hiển thị = lớn hơn trong hai tiêu chí tính được.
            </summary>
            <remarks>Đúng luật §3.3: tiêu chí nào đến trước thì tính tiêu chí đó.</remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult.Note">
            <summary>Lý do khi một tiêu chí không tính được — hiển thị cho người dùng, tiếng Việt</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IComponentConditionEvaluator">
            <summary>
            Tính tình trạng tuổi thọ của một bộ phận theo luật §3.3 của plan bảo dưỡng xe tải.
            </summary>
            <remarks>
            <b>Thuần tính toán, không chạm DB</b> — mọi dữ liệu vào qua <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput"/>.
            Tách như vậy để phủ được đủ ca biên (ODO âm, thiếu mốc lắp, chỉ một tiêu chí) bằng test đơn vị
            không cần fixture, vì đây là chỗ sai một lần thì cảnh báo sai hàng loạt.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IComponentConditionEvaluator.Evaluate(Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput,System.DateTimeOffset)">
            <summary>Tính tình trạng một bộ phận tại thời điểm <paramref name="asOf"/></summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionEvaluator">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IComponentConditionEvaluator" />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionEvaluator.EvaluateTime(Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput,System.DateTimeOffset,System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult)">
            <summary>
            Nhánh thời gian: hạn = ngày lắp + số tháng tuổi thọ.
            </summary>
            <remarks>
            Cộng tháng bằng <c>AddMonths</c> chứ không quy ra 30 ngày — bộ phận lắp 31/1 với tuổi thọ
            1 tháng phải đến hạn 28/2, quy đổi 30 ngày sẽ lệch sang tháng 3.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionEvaluator.EvaluateKm(Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput,System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult)">
            <summary>
            Nhánh km. Trả về <c>true</c> khi chuỗi ODO của xe quá cũ để tin.
            </summary>
            <remarks>
            Ba trường hợp không tính được theo km, mỗi trường hợp là một sự thật đo được ở Việc 0:
            thiếu mốc <c>InstalledOdo</c> (GĐ A cố ý để null thay vì gán 0), xe chưa có ODO nào, và
            <b>km đã dùng ra số âm</b> — xe <c>29H78282</c> thay đồng hồ nên ODO hiện tại nhỏ hơn ODO
            lúc lắp. Cả ba đều rơi về tiêu chí thời gian, tuyệt đối không được lặng lẽ thành "còn mới".
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionEvaluator.DecideLevel(Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionInput,Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentConditionResult,System.Boolean)">
            <summary>
            Chọn mức cảnh báo — nặng hơn thắng: Overdue &gt; DueSoon &gt; StaleOdo.
            </summary>
            <remarks>
            <c>StaleOdo</c> chỉ có nghĩa với bộ phận tính theo km và <b>chỉ với xe đang chạy</b>: xe đỗ
            bãi không có ODO mới là chuyện bình thường (plan §5.1 giả định 1).
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IComponentMaintenanceSyncService">
            <summary>
            Áp luật §3.3 của phân hệ bảo dưỡng lên bộ phận xe sau khi một lần bảo dưỡng được lưu:
            thay mới thì reset mốc, đảo thì hoán vị trí, sửa/xoá dòng cũ thì tính lại mốc.
            </summary>
            <remarks>
            <b>Phải chạy trong cùng transaction với lệnh lưu bản ghi bảo dưỡng.</b> Mốc lắp là gốc để tính
            tuổi thọ; lưu được dòng công việc mà không cập nhật được mốc là lịch sử bộ phận hỏng âm thầm —
            rủi ro lớn nhất của giai đoạn này theo plan §5.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IComponentMaintenanceSyncService.SyncAsync(Lada.Framework.Data.Domains.Trucks.TruckMaintenance,System.Collections.Generic.List{Lada.Framework.Data.Domains.Trucks.TruckMaintLink},System.Collections.Generic.IEnumerable{System.Int32},System.Int32,System.String)">
            <summary>
            Đồng bộ bộ phận sau khi các dòng công việc của một lần bảo dưỡng đã được ghi.
            </summary>
            <param name="maintenance">Bản ghi bảo dưỡng vừa lưu</param>
            <param name="newRotateLinks">
            Các dòng "Đảo vị trí" <b>vừa được tạo trong lần lưu này</b>. Chỉ dòng mới mới được hoán vị:
            bấm Lưu lần thứ hai trên cùng bản ghi mà hoán lại là hai lốp quay về đúng chỗ cũ.
            </param>
            <param name="touchedComponentIds">Mọi bộ phận có dòng công việc bị thêm/sửa/xoá trong lần lưu này</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IComponentMaintenanceSyncService.RecalculateInstallationAsync(System.Int32,System.Int32,System.Int32,System.String)">
            <summary>
            Tính lại mốc lắp của một bộ phận theo dòng "Thay mới" gần nhất còn lại; không còn dòng nào
            thì quay về nguyên bản nhà máy. Gọi được độc lập khi xoá cả một lần bảo dưỡng.
            </summary>
            <param name="expectedTruckId">
            Xe mà bộ phận phải thuộc về. Khác thì bỏ qua, không ghi gì — chốt phòng thủ chiều sâu cho
            trường hợp id bộ phận đến từ payload client lọt qua được tầng kiểm tra phía trên.
            </param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentMaintenanceSyncService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IComponentMaintenanceSyncService" />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentMaintenanceSyncService.ApplyRotationsAsync(Lada.Framework.Data.Domains.Trucks.TruckMaintenance,System.Collections.Generic.List{Lada.Framework.Data.Domains.Trucks.TruckMaintLink},System.Int32,System.String)">
            <summary>
            Đảo vị trí: hoán <see cref="P:Lada.Framework.Data.Domains.Trucks.TruckComponent.Position"/> của hai bộ phận cùng loại trên cùng
            xe, giữ nguyên mốc lắp của từng cái (lốp mang theo tuổi thọ của nó khi đổi chỗ).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentMaintenanceSyncService.SwapPositionsAsync(Lada.Framework.Data.Domains.Trucks.TruckComponent,Lada.Framework.Data.Domains.Trucks.TruckComponent,System.Int32,System.String)">
            <summary>
            Hoán vị trí qua ba bước, đi vòng qua <see cref="F:Lada.Framework.Data.Enums.ComponentPosition.None"/>.
            </summary>
            <remarks>
            Unique index <c>IX_TruckComponent_TruckId_ComponentTypeId_Position</c> lọc
            <c>IsActive = 1 AND Position &lt;&gt; 0</c> và được SQL Server kiểm ngay sau <b>từng</b> lệnh
            UPDATE, không đợi hết transaction. Gán thẳng A←B rồi B←A là ở bước giữa hai bản ghi cùng
            vị trí ⇒ lỗi 2601. Đỗ tạm ở <c>None</c> nằm ngoài bộ lọc index nên không đụng ai.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentMaintenanceSyncService.ResolveOpenAlertsAsync(System.Int32,System.Int32,System.String)">
            <summary>Đóng mọi cảnh báo đang mở của một bộ phận (đánh dấu đã xử lý, không xoá mềm)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IComponentTypeAliasService">
            <summary>
            Tên gọi khác của loại bộ phận K200 (plan bảo dưỡng đợt 3 §3.4). Đường ghi DUY NHẤT là người dùng bấm "Ghi nhớ"
            trên một gợi ý — LLM chỉ đề xuất. Danh mục dùng chung toàn công ty nên alias không gác chi nhánh, nhưng role là
            <c>Truck.ComponentTypeManage</c> (chặt hơn role đọc gợi ý).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IComponentTypeAliasService.GetAll(System.Nullable{System.Int32})">
            <summary>Các alias đang dùng; <paramref name="componentTypeId"/> &gt; 0 thì chỉ của loại đó.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IComponentTypeAliasService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeAliasModel,System.Int32,System.String)">
            <summary>Ghi nhớ một alias. Cùng tên đã trỏ về đúng loại đó → thành công, không tạo trùng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IComponentTypeAliasService.Delete(System.Int32,System.Int32,System.String)">
            <summary>Gỡ một alias (xoá mềm).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentTypeAliasService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IComponentTypeAliasService"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentTypeAliasService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckComponentTypeAlias},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckComponentType})">
            <summary>Khởi tạo dịch vụ alias loại bộ phận.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentTypeAliasService.GetAll(System.Nullable{System.Int32})">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentTypeAliasService.Create(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeAliasModel,System.Int32,System.String)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ComponentTypeAliasService.Delete(System.Int32,System.Int32,System.String)">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IGarageService">
            <summary>
            Dịch vụ danh mục garage. Danh mục dùng chung toàn công ty — không gác phạm vi chi nhánh
            (quyết định Q5, plan §7.1).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IGarageService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm garage có phân trang.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IGarageService.GetAll(System.Boolean)">
            <summary>
            Lấy danh sách garage đang bật để đổ vào ô chọn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IGarageService.GetById(System.Int32)">
            <summary>
            Lấy garage theo ID.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IGarageService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.GarageModel)">
            <summary>
            Tạo mới hoặc cập nhật garage.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IGarageService.Delete(System.Int32,System.Int32,System.String)">
            <summary>
            Xoá mềm garage. Từ chối khi garage đang được bản ghi bảo dưỡng tham chiếu.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.GarageService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IGarageService"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.GarageService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.Garage},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintenance})">
            <summary>
            Khởi tạo dịch vụ garage.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.GarageService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.GarageService.GetAll(System.Boolean)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.GarageService.GetById(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.GarageService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.GarageModel)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.GarageService.Delete(System.Int32,System.Int32,System.String)">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope">
             <summary>
             Phạm vi chi nhánh mà một người dùng được nhìn thấy trong phân hệ bảo dưỡng xe tải.
            
             <para><b>Vì sao là một kiểu riêng chứ không phải <c>List&lt;int&gt;</c></b>: pattern cũ trong
             <c>TruckService.Search</c> quy ước "danh sách null = không lọc = thấy tất". Quy ước đó gộp hai
             tình huống trái ngược nhau vào cùng một giá trị — <i>Founder xem toàn hệ thống</i> và
             <i>người dùng không xác định được đơn vị</i> — nên quên một nhánh là mở toang dữ liệu cả công ty.
             Đây đúng là loại lỗ IDOR mà audit 2026-07-11 chỉ ra. Kiểu này bắt nơi gọi nói rõ ý định:
             <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope.Unrestricted"/> hay <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope.None"/>, không có giá trị nào mang nghĩa nước đôi.</para>
             </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope.IsUnrestricted">
            <summary>
            Không giới hạn chi nhánh (Founder).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope.AgencyIds">
            <summary>
            Danh sách chi nhánh được phép. Rỗng khi <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope.IsUnrestricted"/> = true (không dùng tới)
            hoặc khi người dùng không được xem gì.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope.SeesNothing">
            <summary>
            Người dùng không được xem bản ghi nào.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope.Unrestricted">
            <summary>
            Phạm vi toàn hệ thống — chỉ dành cho Founder.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope.Of(System.Collections.Generic.List{System.Int32})">
            <summary>
            Phạm vi giới hạn theo danh sách chi nhánh (chi nhánh của người dùng + các chi nhánh con).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope.None">
            <summary>
            Không có phạm vi nào — người dùng không thuộc đơn vị nào.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceAgencyScopeResolver">
            <summary>
            Dựng phạm vi chi nhánh của người dùng hiện tại cho phân hệ bảo dưỡng.
            </summary>
            <remarks>
            Tách khỏi controller vì đã có <b>hai</b> controller cần đúng luật này
            (<c>TruckMaintenanceController</c> và <c>TruckController</c> ở nhóm bảo dưỡng). Hai bản sao của
            một luật phân quyền là hai chỗ để quên sửa một chỗ.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceAgencyScopeResolver.ResolveAsync(System.Int32)">
            <summary>
            Phạm vi của một người dùng: Founder không giới hạn, người thường giới hạn theo chi nhánh của
            họ và các chi nhánh con, người không xác định được đơn vị thì không thấy gì (fail-closed).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScopeResolver">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceAgencyScopeResolver" />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiPermissions">
            <summary>
            Cờ hiển thị của phần "Đọc phiếu bằng AI" trên form bảo dưỡng (plan bảo dưỡng đợt 3 §3.6, rule
            <c>quyen-hien-thi</c>). Mỗi cờ đọc ĐÚNG bó role trên <c>[Authorize]</c> của endpoint nó gác — test reflection
            <c>MaintenanceAiPermissionsTests</c> khoá điều đó, đổi role ở controller mà quên ở đây là test đỏ.
            </summary>
            <remarks>
            Cờ không phải hàng rào: <c>[Authorize]</c> + phạm vi chi nhánh ở service vẫn gác như cũ. <c>Founder</c> được
            cộng vào vì vai đó bỏ qua mọi kiểm role ở máy chủ — ẩn nút của Founder là dựng một hàng rào không tồn tại.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiPermissions.MaintCreateOrUpdate">
            <summary>Gác <c>SlipRead</c>, <c>SlipReadUpload</c>, <c>SlipReading/{id}/Rematch</c>, <c>SlipReading/{id}/Attach</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiPermissions.ComponentTypeManage">
            <summary>Gác <c>ComponentTypeAlias*</c> và form tạo/sửa danh mục K200 hiện có.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiPermissions.MaintAttrCreateOrUpdate">
            <summary>Gác <c>TruckController.TruckMaintAttrCreateOrUpdate</c> (form hạng mục hiện có).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiPermissions.ComponentManage">
            <summary>Gác <c>ComponentCreateOrUpdate</c> / <c>ComponentInitForTruck</c> (gắn bộ phận lên xe).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiPermissions.Resolve(System.Collections.Generic.IReadOnlyCollection{System.String},System.Boolean)">
            <param name="roles">Role của người dùng (qua <c>IUserRoleResolver</c>, không qua JWT).</param>
            <param name="aiReady">Công tắc bật + provider đã chọn còn dùng được + có model — máy chủ tính trước.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiFlags">
            <summary>Cờ trả cho giao diện; FE đọc từng cờ bằng <c>=== true</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiFlags.#ctor(System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.Boolean,System.String)">
            <summary>Cờ trả cho giao diện; FE đọc từng cờ bằng <c>=== true</c>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiConfigKeys">
            <summary>Khoá AppConfig của đọc phiếu bảo dưỡng bằng AI — seed mặc định TẮT ở migration 202610271410.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiSettings">
            <summary>
            Cấu hình đọc phiếu bảo dưỡng bằng AI đã chuẩn hoá (plan bảo dưỡng đợt 3 §3.5). Giá trị lạ không bao giờ thành
            "bật": <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiSettings.Enabled"/> chỉ true với đúng chuỗi <c>true</c>, số hỏng lấy mặc định của QĐ3-8.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiSettings.#ctor(System.Boolean,System.Nullable{System.Int32},System.String,System.Int32,System.Int32,System.Int32)">
            <summary>
            Cấu hình đọc phiếu bảo dưỡng bằng AI đã chuẩn hoá (plan bảo dưỡng đợt 3 §3.5). Giá trị lạ không bao giờ thành
            "bật": <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiSettings.Enabled"/> chỉ true với đúng chuỗi <c>true</c>, số hỏng lấy mặc định của QĐ3-8.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiSettings.MinImageEdge">
            <summary>Dưới mức này chữ trên phiếu không còn đọc được; trên 8000 px Anthropic từ chối.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiSettings.IsConfigured">
            <summary>Đủ cấu hình để gọi được (công tắc bật, có provider, có model) — chưa xét provider còn dùng được.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiSettings.LoadAsync(Lada.Framework.Infrastructures.Services.IAppConfigService)">
            <summary>Đọc 6 khoá qua <c>IAppConfigService</c> CỦA FRAMEWORK (ghi rõ namespace: repo có hai interface trùng tên) — cache 60 giây, nhóm công tắc an toàn.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceInvoiceReaderService">
            <summary>
            Đọc một hoá đơn bảo dưỡng <b>đã đính kèm</b> (PDF hoặc ảnh) và gợi ý số tiền / ngày / biển số cho form.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceInvoiceReaderService.ReadAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Threading.CancellationToken)">
            <summary>
            Đọc tệp đính kèm <paramref name="mediaLinkId"/> (<c>TruckMaintenanceMedia.Id</c>, loại hoá đơn) của một
            lần bảo dưỡng trong phạm vi chi nhánh <paramref name="scope"/>. Chạy trong request: một hoá đơn 1–2 trang
            mất ~0,3 giây (PDF lớp text) tới ~2,5 giây (ảnh OCR). Không ném với lỗi dữ liệu.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceInvoiceReaderService.ReadBytesAsync(System.Byte[],System.String,System.String,System.Threading.CancellationToken)">
            <summary>
            Cùng đường đọc như <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceInvoiceReaderService.ReadAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Threading.CancellationToken)"/> nhưng trên tệp đã nằm trong bộ nhớ — đường dự phòng khi đọc phiếu
            bằng AI lỗi (plan bảo dưỡng đợt 3 QĐ3-6). Nơi gọi CHỊU TRÁCH NHIỆM đã kiểm phạm vi chi nhánh của xe.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceInvoiceReaderService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceInvoiceReaderService"/>
            <remarks>
            <para><b>Không móc vào đường upload</b> (nguyên tắc số 1 của đợt trích-xuất-văn-bản): tệp đã nằm trên đĩa,
            dịch vụ này chỉ đọc lại theo <c>Media.SystemPath</c> qua <see cref="T:Lada.Framework.Infrastructures.Services.IMediaFileReader"/> — có chốt "phải nằm
            dưới thư mục media" nên DB bị sửa cũng không đọc được file tuỳ ý trên máy chủ.</para>
            <para>Phạm vi chi nhánh tính theo xe đang gắn với bản ghi bảo dưỡng, qua <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceScopeQuery"/>
            dùng chung với <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService"/>; ngoài phạm vi trả cùng thông điệp "không tìm thấy"
            để không lộ sự tồn tại của bản ghi chi nhánh khác.</para>
            <para>Ảnh đính kèm đã bị <c>ImageService</c> nén sang WebP rộng ≤ 1200 px trước khi lưu. Đo 2026-08-21 trên
            14 ảnh thật: bản WebP đọc <b>không kém</b> ảnh gốc (số tiền 9/14 so với 8/14) nên không cần giữ bản gốc.</para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceInvoiceReaderService.MaxInvoicePages">
            <summary>Hoá đơn, báo giá sửa chữa dài nhất gặp là 2–3 trang; trần này giữ request không kéo dài vô hạn.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceInvoiceReaderService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintenanceMedia},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Medias.Media},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintenance},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.Truck},Lada.Framework.Infrastructures.Services.IMediaFileReader,Lada.Framework.Infrastructures.Services.TextExtraction.IDocumentTextExtractor,Microsoft.Extensions.Options.IOptions{Lada.Framework.Infrastructures.AppSettings.TextExtractionSettings})">
            <summary>Khởi tạo dịch vụ đọc hoá đơn bảo dưỡng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceInvoiceReaderService.ReadAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Threading.CancellationToken)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceInvoiceReaderService.ReadBytesAsync(System.Byte[],System.String,System.String,System.Threading.CancellationToken)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceInvoiceReaderService.ComparePlate(Lada.Framework.DTO.TextExtraction.VehicleInvoiceFields,System.String,Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceInvoiceReadResult)">
            <summary>
            Chốt an toàn rẻ nhất của cả tính năng: biển số đọc đúng 100% (GĐ B) nên so được với xe của bản ghi;
            lệch là dấu hiệu người dùng đính nhầm hoá đơn của xe khác.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MatchCatalogType">
            <summary>Một loại bộ phận K200 đang dùng, kèm các tên gọi khác đã ghi nhớ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MatchCatalogType.#ctor(System.Int32,System.String,System.String,Lada.Framework.Data.Enums.TruckComponentGroup,System.Collections.Generic.IReadOnlyList{System.String})">
            <summary>Một loại bộ phận K200 đang dùng, kèm các tên gọi khác đã ghi nhớ.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MatchCatalog">
            <summary>Danh mục đích so khớp — chỉ mục đang dùng (K200 <c>IsActive</c>, chưa xoá).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceLineMatcher">
            <summary>
            So khớp dòng phiếu với danh mục, hai tầng (plan bảo dưỡng đợt 3 §3.4). Tầng 2a thuần, tất định, chạy trước —
            dòng khớp ở đây không tốn lời gọi LLM nào. Tầng 2b gửi phần còn lại cho LLM; hàm ở đây chỉ dựng câu hỏi và KIỂM
            câu trả lời (mã phải có trong danh mục, nhóm phải hợp lệ) — lời gọi nằm ở <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService"/>.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceLineMatcher.FuzzyThreshold">
            <summary>Ngưỡng Jaccard trên tập từ cho khớp mờ (§3.4 mục 3).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceLineMatcher.MaxFreeText">
            <summary>Trần độ dài chữ tự do LLM được trả (<c>reason</c>, <c>note</c>, <c>name</c>) — §3.11.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceLineMatcher.Normalize(System.String)">
            <summary>
            Khoá so khớp: chữ thường, tách từ theo ký tự không phải chữ/số, bỏ từ dừng, bỏ dấu (đ → d), một khoảng trắng
            giữa các từ. <c>"Thay  Lọc DẦU (mới)"</c> → <c>"loc dau"</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceLineMatcher.MatchDeterministic(Ladaer.BackEnd.Infrastructures.Services.Trucks.SlipLine,Ladaer.BackEnd.Infrastructures.Services.Trucks.MatchCatalog)">
            <summary>
            Tầng 2a cho một dòng: khớp chính xác theo thứ tự alias → mã → tên K200 (tên đầy đủ, phần trước ngoặc, phần
            trong ngoặc, từng vế nối bằng "+" hay ",") → tên hạng mục; rồi khớp mờ. Khoá trỏ về ≥ 2 mục thì coi như không
            khớp — để LLM phân xử, không đoán. Không khớp → <c>Decision = unmatched</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceLineMatcher.BuildMatchSystem(Ladaer.BackEnd.Infrastructures.Services.Trucks.MatchCatalog)">
            <summary>System prompt bước 2b: luật cố định + bảng danh mục (đổi ít → adapter Anthropic cache được).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceLineMatcher.BuildMatchUserPrompt(System.Collections.Generic.IEnumerable{Ladaer.BackEnd.Infrastructures.Services.Trucks.SlipLine})">
            <summary>Lượt user bước 2b: chỉ các dòng 2a chưa khớp — không có ảnh.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceLineMatcher.ApplyLlmMatches(System.Collections.Generic.IReadOnlyCollection{Ladaer.BackEnd.Infrastructures.Services.Trucks.SlipLine},Ladaer.BackEnd.Infrastructures.Services.Trucks.LineMatchResponse,Ladaer.BackEnd.Infrastructures.Services.Trucks.MatchCatalog)">
            <summary>
            Kiểm câu trả lời bước 2b rồi đổi thành gợi ý — KHÔNG tin LLM ở bất kỳ mã/tên nào: <c>code</c> không có trong
            danh mục thì hạ thành <c>new</c> kèm cảnh báo, hạng mục không tồn tại thì thành đề xuất tạo hạng mục, nhóm lạ
            thì bỏ, chữ tự do cắt ở 300 ký tự. Dòng không được hỏi hoặc trả trùng thì bỏ qua; dòng được hỏi mà LLM không trả
            thì giữ <c>unmatched</c>.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceLineMatcher.NameKeys(System.String)">
            <summary>
            Các khoá tên của một mục danh mục: tên đầy đủ, phần ngoài ngoặc, từng vế của phần ngoài ngoặc (tách theo
            "+ , ; —"), và phần trong ngoặc GIỮ NGUYÊN. Không tách trong ngoặc: ngoặc thường là lời chú thích ("Dây curoa
            (máy phát, điều hòa)"), tách ra thì dòng "Điều hòa" khớp nhầm sang dây curoa.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceLineMatcher.Index">
            <summary>Chỉ mục tra cứu dựng từ danh mục — khoá chuẩn hoá → tập Id.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceInScopeRow">
            <summary>
            Một bản ghi bảo dưỡng đã qua lọc phạm vi chi nhánh, kèm thông tin xe mà nơi gọi hay cần.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceInScopeRow.Maintenance">
            <summary>Bản ghi bảo dưỡng.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceInScopeRow.AgencyId">
            <summary>Chi nhánh của <b>xe</b> đang gắn với bản ghi — đây mới là chi nhánh dùng để xét phạm vi.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceInScopeRow.TruckLicensePlate">
            <summary>Biển số xe, nguyên văn trong DB (lưu lẫn có/không dấu gạch).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceScopeQuery">
            <summary>
            Luật "bản ghi bảo dưỡng nào nằm trong phạm vi chi nhánh của người dùng" — <b>một bản duy nhất</b> cho cả miền.
            </summary>
            <remarks>
            Trước đây luật này được chép ở mỗi service chạm tới bản ghi bảo dưỡng. Đó đúng là "hai chỗ để quên sửa một
            chỗ": ai siết luật ở một service sẽ để service kia lặng lẽ giữ luật cũ lỏng hơn, và lỗi loại đó không nổi lên
            ở build cũng chẳng nổi ở test của service bị bỏ quên. Phạm vi tính theo <b>chi nhánh của xe</b>, không theo
            <c>TruckMaintenance.AgencyId</c> và càng không theo tham số client gửi (nợ BD-11).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceScopeQuery.FindAsync(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintenance},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.Truck},System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Threading.CancellationToken)">
            <summary>
            Nạp bản ghi bảo dưỡng kèm chi nhánh và biển số xe nếu xe nằm trong <paramref name="scope"/>; null nếu
            không tìm thấy <b>hoặc</b> nằm ngoài phạm vi — nơi gọi phải trả cùng một thông điệp cho hai ca này để
            không lộ sự tồn tại của bản ghi chi nhánh khác.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.SlipFileParts">
            <summary>Phần nội dung gửi LLM cho một tệp phiếu; <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.SlipFileParts.Error"/> khác null là tệp bị từ chối (không gọi AI).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.SlipFileParts.#ctor(System.Collections.Generic.IReadOnlyList{Lada.Framework.Infrastructures.Services.Ai.LlmContentPart},System.Collections.Generic.IReadOnlyList{System.String},System.String)">
            <summary>Phần nội dung gửi LLM cho một tệp phiếu; <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.SlipFileParts.Error"/> khác null là tệp bị từ chối (không gọi AI).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipFiles">
            <summary>
            Tệp phiếu → phần nội dung gửi LLM (plan bảo dưỡng đợt 3 §3.1 bước 1, prompt GĐ B mục 4). Phân nhánh theo NỘI DUNG
            tệp, không theo đuôi hay content-type client khai: PDF → Anthropic nhận khối <c>document</c>, OpenAI nhận ảnh
            render từng trang (PDF-qua-part-<c>file</c> chưa kiểm, nợ BD3-8); ảnh → <see cref="T:Lada.Framework.Infrastructures.Services.Ai.LlmImagePreparer"/> (xoá metadata,
            thu cạnh); HEIC iPhone → Magick.NET đổi JPEG trước vì ImageSharp không đọc HEIC.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipFiles.MaxPdfPages">
            <summary>Phiếu dài nhất gặp là 2–3 trang (đo đợt OCR); quá thì chỉ đọc chừng này trang đầu.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipFiles.PdfRenderDpi">
            <summary>Độ phân giải render trang PDF cho đường ảnh — A4 ở 200 dpi ≈ 1654×2339, sau đó vẫn qua trần cạnh.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipFiles.Sha256Hex(System.Byte[])">
            <summary>SHA-256 hex thường của tệp gốc — khoá bộ nhớ đệm.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipFiles.Build(System.Byte[],System.String,System.Int32,Lada.Framework.Infrastructures.Services.TextExtraction.IPdfRenderer)">
            <summary>
            Dựng phần nội dung cho <paramref name="providerType"/>. Không ném với tệp hỏng — trả
            <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.SlipFileParts.Rejected(System.String)"/> kèm câu tiếng Việt cố định.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipFiles.HeicToJpeg(System.Byte[])">
            <summary>HEIC → JPEG chất lượng cao (metadata xoá ở bước <see cref="T:Lada.Framework.Infrastructures.Services.Ai.LlmImagePreparer"/> sau đó); null nếu không đọc được.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceSlipReaderService">
            <summary>
            Đọc phiếu / hoá đơn bảo dưỡng bằng LLM đa phương thức rồi so khớp từng dòng với danh mục K200 + hạng mục
            (plan bảo dưỡng đợt 3 §3.1). Mọi kết quả là GỢI Ý — không hàm nào ở đây ghi <see cref="T:Lada.Framework.Data.Domains.Trucks.TruckMaintLink"/>,
            <see cref="T:Lada.Framework.Data.Domains.Trucks.TruckComponentType"/> hay <see cref="T:Lada.Framework.Data.Domains.Trucks.TruckMaintAttribute"/> (Nguyên tắc số 1).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceSlipReaderService.GetFlagsAsync(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <summary>Cờ hiển thị cho người có <paramref name="roles"/> — tính cả công tắc + provider còn dùng được.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceSlipReaderService.ReadMediaAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>Đọc một tệp hoá đơn/phiếu đã đính kèm (chế độ sửa). Phạm vi theo xe gắn với bản ghi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceSlipReaderService.ReadUploadAsync(System.Byte[],System.String,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>Đọc tệp tải thẳng lúc tạo mới (QĐ3-3) — tệp KHÔNG được lưu làm media ở bước này.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceSlipReaderService.RematchAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Int32,System.String,System.Threading.CancellationToken)">
            <summary>Chạy lại so khớp (2a + 2b) trên kết quả đã đọc — không gửi lại ảnh. Có trần số lần.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceSlipReaderService.GetReadingAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Threading.CancellationToken)">
            <summary>Mở lại gợi ý của một lượt đọc trong phạm vi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceSlipReaderService.AttachAsync(System.Int32,System.Int32,System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Int32,System.String)">
            <summary>Gắn lượt đọc lúc tạo mới vào bản ghi vừa lưu (và dòng media vừa tải lên, nếu có).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceSlipReaderService"/>
            <remarks>
            <para><b>Thứ tự kiểm</b>: phạm vi chi nhánh → cấu hình/provider → bộ nhớ đệm → trần lượt/ngày → tệp → gọi AI.
            Phạm vi luôn đứng đầu và mọi ca "không thấy / ngoài phạm vi" trả CÙNG một câu (không lộ bản ghi chi nhánh khác).</para>
            <para><b>AI lỗi</b> (timeout, 429, 5xx, JSON hỏng, key sai): ghi dòng <c>Failed</c> rồi chạy OCR cũ cho 3 trường
            tiền/ngày/biển số, trả <c>Mode = Offline</c> (QĐ3-6). Log chỉ ghi loại lỗi + 200 ký tự đầu câu trả lời đã che
            base64 — không bao giờ ghi tệp, thân request hay key.</para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.MaxFileBytes">
            <summary>Trần tệp đọc — khớp <c>[RequestSizeLimit]</c> của endpoint tải thẳng (§3.11).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.CacheDays">
            <summary>Kết quả cũ cùng tệp + cùng model được dùng lại trong chừng này ngày (QĐ3-7).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.MaxRematch">
            <summary>Số lần "Khớp lại" (bước 2b) tối đa cho một lượt đọc.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.ExtractionMaxTokens">
            <summary>Phiếu dài 40 dòng ≈ 3.000 token JSON (§3.2) — để dư cho phiếu dài hơn.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.MaxLines">
            <summary>Số dòng tối đa giữ lại từ một phiếu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintenanceSlipReading},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintenanceMedia},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Medias.Media},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintenance},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.Truck},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckComponentType},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckComponentTypeAlias},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintAttribute},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.AI.AiProvider},Lada.Framework.Infrastructures.Services.IMediaFileReader,Lada.Framework.Infrastructures.Services.TextExtraction.IPdfRenderer,Lada.Framework.Infrastructures.Services.Ai.ILlmClientFactory,Lada.Framework.Infrastructures.Services.ISecretProtector,Lada.Framework.Infrastructures.Services.IAppConfigService,Ladaer.BackEnd.Infrastructures.Services.Trucks.IMaintenanceInvoiceReaderService,Microsoft.Extensions.Logging.ILogger{Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService})">
            <summary>Khởi tạo dịch vụ đọc phiếu bảo dưỡng bằng AI.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.GetFlagsAsync(System.Collections.Generic.IReadOnlyCollection{System.String})">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.ReadMediaAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.ReadUploadAsync(System.Byte[],System.String,System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.RematchAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Int32,System.String,System.Threading.CancellationToken)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.GetReadingAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Threading.CancellationToken)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.AttachAsync(System.Int32,System.Int32,System.Nullable{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Int32,System.String)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.ReadReservedAsync(Lada.Framework.Data.Domains.Trucks.TruckMaintenanceSlipReading,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.SlipSource,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiSettings,Lada.Framework.Infrastructures.Services.Ai.LlmEndpoint,System.Threading.CancellationToken)">
            <summary>Phần đọc sau khi đã giữ chỗ: chuẩn bị tệp → bước 1 → kiểm → so khớp → cập nhật dòng giữ chỗ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.MatchAsync(System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.Services.Trucks.SlipLine},Ladaer.BackEnd.Infrastructures.Services.Trucks.MatchCatalog,Lada.Framework.Infrastructures.Services.Ai.LlmEndpoint,System.String,System.Threading.CancellationToken)">
            <summary>Tầng 2a cho mọi dòng, tầng 2b cho phần còn lại; 2b lỗi thì giữ dòng "chưa khớp" kèm cảnh báo, không làm hỏng lượt đọc.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.CheckDailyLimitsAsync(Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAiSettings,System.Int32,System.DateTimeOffset,System.Threading.CancellationToken)">
            <summary>Trần đếm lượt THẬT gọi AI hôm nay (Succeeded + Failed, không tính lượt lấy lại kết quả cũ hay bị từ chối).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.LimitGate">
            <summary>Cổng khoá cho phép "đếm trần rồi giữ chỗ" và "trừ quỹ khớp lại" — giữ vài mili giây, không bao lời gọi AI.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.RunningWindow">
            <summary>Dòng "đang đọc" cũ hơn mức này coi như tiến trình đã chết — không chặn đọc lại cùng tệp.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.RematchUsedAsync(Lada.Framework.Data.Domains.Trucks.TruckMaintenanceSlipReading,System.Threading.CancellationToken)">
            <summary>Số lần đã khớp lại tính trên dòng gốc (lượt lấy từ bộ nhớ đệm dùng chung quỹ với dòng gốc).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipReaderService.BuildResult(Lada.Framework.Data.Domains.Trucks.TruckMaintenanceSlipReading,Ladaer.BackEnd.Infrastructures.Services.Trucks.SlipExtraction,System.Collections.Generic.IReadOnlyList{Ladaer.BackEnd.Infrastructures.DTO.Results.Trucks.MaintenanceSlipLineMatchItem},System.String,System.Int32)">
            <summary>
            Kết quả trả client từ extraction ĐÃ KIỂM + gợi ý khớp. Cảnh báo số (thành tiền lệch, tổng lệch, ngày tương lai)
            và đối chiếu biển số tính lại mỗi lần — biển số so với xe của NGƯỜI GỌI, kể cả khi kết quả lấy từ bộ nhớ đệm.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipValidator">
            <summary>
            Kiểm tra máy chủ trên kết quả bước 1 (plan §3.3 cuối): JSON của LLM không bao giờ tới client nguyên văn — chuỗi bị
            cắt độ dài, giá trị enum lạ quy về mặc định, số âm/vô lý bị bỏ, dòng đánh lại số thứ tự. Các cảnh báo về SỐ (thành
            tiền lệch đơn giá × số lượng, tổng lệch, ngày tương lai) là thuần, tính lại mỗi lần dựng kết quả.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipValidator.MaxAmount">
            <summary>10 tỉ đồng — một phiếu sửa xe tải vượt mức này là đọc nhầm (gộp số, đọc cả mã số thuế).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipValidator.LineWarnings(Ladaer.BackEnd.Infrastructures.Services.Trucks.SlipLine)">
            <summary>Thành tiền lệch số lượng × đơn giá quá 5 %.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipValidator.DocumentWarnings(Ladaer.BackEnd.Infrastructures.Services.Trucks.SlipExtraction,System.DateTimeOffset)">
            <summary>Tổng phiếu lệch tổng các dòng (quá 1 % và quá 1.000 đ); ngày chứng từ ở tương lai.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipSchemas">
            <summary>
            Nguồn sự thật của hai schema structured output đọc phiếu bảo dưỡng (plan bảo dưỡng đợt 3 §3.3, §3.4) và system
            prompt đi kèm. Test <c>MaintenanceSlipSchemasTests</c> khoá chuỗi schema: sửa schema là đổi hợp đồng với nhà cung
            cấp (mất cache biên dịch 24 h) nên phải sửa cả test, có chủ ý.
            </summary>
            <remarks>
            Viết theo phần GIAO của hai provider: mọi object <c>additionalProperties: false</c>, MỌI thuộc tính nằm trong
            <c>required</c> (OpenAI strict đòi). Không dùng <c>minimum</c>/<c>maxLength</c>/<c>minItems</c> — structured output
            của Claude không nhận; trần độ dài và khoảng số do máy chủ kiểm sau khi parse.
            <para><b>Trần 16 tham số union mỗi schema</b> (Anthropic, đo gọi thật 2026-10-27: 17 <c>anyOf</c> → 400 "Schemas
            contains too many parameters with union types"). Vì vậy ô CHỮ có thể trống viết chuỗi rỗng <c>""</c> (máy chủ đổi
            thành null), hành động không rõ là <c>"none"</c>; chỉ ô SỐ dùng <c>anyOf [number, null]</c> vì 0 đ là giá trị thật.
            Test <c>MaintenanceSlipSchemasTests</c> đếm union.</para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipSchemas.ExtractionSystemPrompt">
            <summary>
            System prompt bước 1 — cố định (không chứa thứ đổi theo lượt) để adapter Anthropic cache được khi đủ dài.
            Nội dung phiếu là DỮ LIỆU KHÔNG TIN CẬY (§3.11): prompt nói rõ chữ trong ảnh không phải chỉ dẫn.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipSchemas.MatchSystemRules">
            <summary>Phần luật của system prompt bước 2b; bảng danh mục nối sau (đổi ít — breakpoint cache nằm cuối system).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceSlipSchemas.StorageOptions">
            <summary>Tuỳ chọn ghi/đọc JSON đã kiểm vào <c>TruckMaintenanceSlipReading</c> — camelCase như hợp đồng với LLM.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckActivityService">
            <summary>
            Giao diện cho dịch vụ quản lý hoạt động xe tải.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckActivityService.GetByIds(Ladaer.BackEnd.Infrastructures.DTO.Models.KeyModels{System.Int32})">
            <summary>
            Lấy thông tin hoạt động xe tải theo danh sách ID.
            </summary>
            <param name="param">Danh sách ID của hoạt động xe tải.</param>
            <returns>Kết quả chứa thông tin hoạt động xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckActivityService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckActivityModel)">
            <summary>
            Tạo mới hoặc cập nhật thông tin hoạt động xe tải.
            </summary>
            <param name="param">Thông tin hoạt động xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckActivityService.Delete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel)">
            <summary>
            Xóa thông tin hoạt động xe tải.
            </summary>
            <param name="param">Thông tin hoạt động xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckActivityService.CheckInTruck(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckCheckInOutModel)">
            <summary>
            Nhận xe (Check-in) với upload hình ảnh
            </summary>
            <param name="model">Thông tin nhận xe</param>
            <returns>Kết quả nhận xe</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckActivityService.CheckOutTruck(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckCheckInOutModel)">
            <summary>
            Trả xe (Check-out) với upload hình ảnh
            </summary>
            <param name="model">Thông tin trả xe</param>
            <returns>Kết quả trả xe</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckActivityService.FuelRefillTruck(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckFuelRefillModel)">
            <summary>
            Đổ dầu cho xe với upload hình ảnh và thông tin ODO
            </summary>
            <param name="model">Thông tin đổ dầu</param>
            <returns>Kết quả đổ dầu</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckActivityService.GetAvailableTrucks(System.Int32)">
            <summary>
            Lấy danh sách xe có thể nhận (chưa có người phụ trách)
            </summary>
            <param name="agencyId">ID đại lý</param>
            <returns>Danh sách xe có thể nhận</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckActivityService.GetCurrentUserTruck(System.Int32)">
            <summary>
            Lấy xe hiện tại của người dùng
            </summary>
            <param name="userId">ID người dùng</param>
            <returns>Thông tin xe hiện tại</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckActivityService">
            <summary>
            Triển khai dịch vụ quản lý hoạt động xe tải.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckActivityService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.Truck},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckActivity},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckActivityMedia},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Medias.Media},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckAsset},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckSpecAttribute},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintAttribute},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintenance},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckSpecification},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Categories.Agency},Lada.Framework.Data.Repositories.IUserRepository{Lada.Framework.Data.Domains.Identity.User},Lada.Framework.Infrastructures.Services.IUnifiedMediaService)">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckActivityService"/>.
            </summary>
            <param name="truckRepository">Đối tượng IRepository của Truck.</param>
            <param name="truckActivityRepository">Đối tượng IRepository của TruckActivity.</param>
            <param name="truckAssetRepository">Đối tượng IRepository của TruckAsset.</param>
            <param name="truckSpecAttributeRepository">Đối tượng IRepository của TruckSpecAttribute.</param>
            <param name="truckMaintAttributeRepository">Đối tượng IRepository của TruckMaintAttribute.</param>
            <param name="truckMaintenanceRepository">Đối tượng IRepository của TruckMaintenance.</param>
            <param name="truckSpecificationRepository">Đối tượng IRepository của TruckSpecification.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckActivityService.GetByIds(Ladaer.BackEnd.Infrastructures.DTO.Models.KeyModels{System.Int32})">
            <summary>
            Lấy thông tin hoạt động xe tải theo danh sách ID.
            </summary>
            <param name="param">Danh sách ID của hoạt động xe tải.</param>
            <returns>Kết quả chứa thông tin hoạt động xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckActivityService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckActivityModel)">
            <summary>
            Tạo mới hoặc cập nhật thông tin hoạt động xe tải.
            </summary>
            <param name="param">Thông tin hoạt động xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckActivityService.Delete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel)">
            <summary>
            Xóa thông tin hoạt động xe tải.
            </summary>
            <param name="param">Thông tin hoạt động xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckActivityService.GetUserCurrentTruckAsync(System.Int32)">
            <summary>
            Kiểm tra xem người dùng có đang phụ trách xe nào không
            </summary>
            <param name="userId">ID người dùng</param>
            <returns>Thông tin xe đang phụ trách (nếu có)</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckActivityService.ProcessAndSaveListMediaAsync(System.Collections.Generic.List{Microsoft.AspNetCore.Http.IFormFile})">
            <summary>
            Xử lý và lưu nhiều file media cùng lúc
            </summary>
            <param name="files">Danh sách file media</param>
            <returns>Danh sách kết quả xử lý</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckAssetService">
            <summary>
            Giao diện cho dịch vụ quản lý tài sản xe tải.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckAssetService.GetByIds(Ladaer.BackEnd.Infrastructures.DTO.Models.KeyModels{System.Int32})">
            <summary>
            Lấy thông tin tài sản xe tải theo danh sách ID.
            </summary>
            <param name="param">Danh sách ID của tài sản xe tải.</param>
            <returns>Kết quả chứa thông tin tài sản xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckAssetService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckAssetModel)">
            <summary>
            Tạo mới hoặc cập nhật thông tin tài sản xe tải.
            </summary>
            <param name="param">Thông tin tài sản xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckAssetService.Delete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel)">
            <summary>
            Xóa thông tin tài sản xe tải.
            </summary>
            <param name="param">Thông tin tài sản xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckAssetService">
            <summary>
            Triển khai dịch vụ quản lý tài sản xe tải.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckAssetService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.Truck},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckActivity},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckAsset},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckSpecAttribute},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintAttribute},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintenance},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckSpecification})">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckAssetService"/>.
            </summary>
            <param name="truckRepository">Đối tượng IRepository của Truck.</param>
            <param name="truckActivityRepository">Đối tượng IRepository của TruckActivity.</param>
            <param name="truckAssetRepository">Đối tượng IRepository của TruckAsset.</param>
            <param name="truckSpecAttributeRepository">Đối tượng IRepository của TruckSpecAttribute.</param>
            <param name="truckMaintAttributeRepository">Đối tượng IRepository của TruckMaintAttribute.</param>
            <param name="truckMaintenanceRepository">Đối tượng IRepository của TruckMaintenance.</param>
            <param name="truckSpecificationRepository">Đối tượng IRepository của TruckSpecification.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckAssetService.GetByIds(Ladaer.BackEnd.Infrastructures.DTO.Models.KeyModels{System.Int32})">
            <summary>
            Lấy thông tin tài sản xe tải theo danh sách ID.
            </summary>
            <param name="param">Danh sách ID của tài sản xe tải.</param>
            <returns>Kết quả chứa thông tin tài sản xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckAssetService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckAssetModel)">
            <summary>
            Tạo mới hoặc cập nhật thông tin tài sản xe tải.
            </summary>
            <param name="param">Thông tin tài sản xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckAssetService.Delete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel)">
            <summary>
            Xóa thông tin tài sản xe tải.
            </summary>
            <param name="param">Thông tin tài sản xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentAlertService">
            <summary>
            Tra cứu cảnh báo tuổi thọ bộ phận do job nền sinh.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentAlertService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>Tìm kiếm cảnh báo trong phạm vi chi nhánh của người dùng</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentAlertService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentAlertService" />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentService">
             <summary>
             Dịch vụ quản lý bộ phận lắp trên xe.
            
             <para><b>Phạm vi chi nhánh ép ở tầng này, không tin client.</b> Mọi phương thức đọc/ghi đều nhận
             <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope"/> do controller dựng: Founder thì không giới hạn, người dùng
             thường thì giới hạn theo chi nhánh của họ cùng các chi nhánh con, còn người không xác định được
             đơn vị thì <b>không xem được gì</b> (fail-closed). Không có giá trị nào mang nghĩa nước đôi —
             đây là trọng tâm IDOR của audit 2026-07-11.</para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Tìm kiếm bộ phận trên xe có phân trang, trong phạm vi chi nhánh cho phép.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentService.GetByTruck(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Boolean)">
            <summary>
            Lấy toàn bộ bộ phận của một xe, trong phạm vi chi nhánh cho phép.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentService.GetById(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Lấy một bộ phận theo ID, trong phạm vi chi nhánh cho phép.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentModel,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Gắn mới hoặc sửa bộ phận trên xe.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentService.InitForTruck(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentInitModel,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Khởi tạo hàng loạt bộ phận cho một xe từ danh mục đang bật.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentService.Delete(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Int32,System.String)">
            <summary>
            Xoá mềm bộ phận. Từ chối khi bộ phận đã có lịch sử bảo dưỡng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentService.IsTruckInScope(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Xe có nằm trong phạm vi chi nhánh cho phép hay không. Dùng để chặn trước khi trả
            bất kỳ dữ liệu vận hành nào của xe (kể cả chỉ số ODO).
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentService"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckComponent},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckComponentType},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.Truck},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintLink},Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckOdoService)">
            <summary>
            Khởi tạo dịch vụ bộ phận trên xe.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService.GetByTruck(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Boolean)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService.GetById(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentModel,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService.InitForTruck(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentInitModel,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService.Delete(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Int32,System.String)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService.IsTruckInScope(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService.BuildScopedQuery(Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Truy vấn bộ phận đã ghép xe + loại và ĐÃ lọc theo phạm vi chi nhánh.
            Mọi phương thức đọc/ghi đều đi qua đây để không bỏ sót bộ lọc.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService.GetTruckInScope(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Lấy xe nếu nó nằm trong phạm vi cho phép, null nếu không.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService.ValidatePosition(Lada.Framework.Data.Domains.Trucks.TruckComponentType,Lada.Framework.Data.Enums.ComponentPosition,System.Int32,System.Int32)">
            <summary>
            Kiểm tra ràng buộc vị trí của bộ phận. Trả null khi hợp lệ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService.ToItem(Lada.Framework.Data.Domains.Trucks.TruckComponent,System.String,System.String,System.Nullable{System.Int32},System.Nullable{System.Int32})">
            <summary>
            Dựng DTO hiển thị từ entity kèm dữ liệu ghép.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService.ReadInt(System.Object)">
            <summary>
            Đọc số nguyên từ một giá trị filter động. Trả 0 khi thiếu hoặc không đọc được —
            nơi gọi hiểu 0 là "không lọc theo trường này".
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService.ReadBool(System.Object)">
            <summary>
            Đọc giá trị logic từ một giá trị filter động. Trả null khi thiếu hoặc không đọc được.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentService.ScopedComponent">
            <summary>
            Kết quả ghép bộ phận với xe và loại bộ phận.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentTypeService">
            <summary>
            Dịch vụ danh mục loại bộ phận xe. Danh mục dùng chung toàn công ty, không gác phạm vi chi nhánh.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentTypeService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm loại bộ phận có phân trang.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentTypeService.GetAll(System.Boolean)">
            <summary>
            Lấy danh sách loại bộ phận để đổ vào ô chọn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentTypeService.GetById(System.Int32)">
            <summary>
            Lấy loại bộ phận theo ID.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentTypeService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel)">
            <summary>
            Tạo mới hoặc cập nhật loại bộ phận.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentTypeService.Delete(System.Int32,System.Int32,System.String)">
            <summary>
            Xoá mềm loại bộ phận. Từ chối khi đang có bộ phận trên xe thuộc loại này.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentTypeService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckComponentTypeService"/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentTypeService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckComponentType},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckComponent})">
            <summary>
            Khởi tạo dịch vụ danh mục loại bộ phận.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentTypeService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentTypeService.GetAll(System.Boolean)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentTypeService.GetById(System.Int32)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentTypeService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentTypeService.Delete(System.Int32,System.Int32,System.String)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckComponentTypeService.Validate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckComponentTypeModel)">
            <summary>
            Kiểm tra dữ liệu đầu vào. Trả null khi hợp lệ.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckConditionService">
            <summary>
            Tình trạng bảo dưỡng theo xe: màn đội xe, hồ sơ một xe, lịch sử một bộ phận.
            </summary>
            <remarks>
            Mọi truy vấn đều lọc theo <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope"/> ép ở tầng service — không tin
            tham số <c>truckId</c> hay <c>agencyId</c> client gửi lên (trọng tâm IDOR của audit 2026-07-11).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckConditionService.SearchFleet(Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>Danh sách xe kèm ODO hiện tại và số bộ phận đang có vấn đề</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckConditionService.GetTruckProfile(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>Hồ sơ tình trạng một xe; <c>null</c> khi xe nằm ngoài phạm vi</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckConditionService.GetComponentHistory(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>Lịch sử các lần bảo dưỡng đã chạm tới một bộ phận</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckConditionService.GetConditionForDriver(System.Int32)">
            <summary>
            Tình trạng xe mà một lái xe đang nhận; <c>null</c> khi người đó chưa nhận xe nào.
            </summary>
            <remarks>
            <b>Không có tham số <c>truckId</c> — và sẽ không bao giờ có.</b> Xe suy ra từ
            <c>Truck.CurrentDriverId</c> khớp với người dùng trong token; nhận id từ client là mở đường
            cho một tài xế xem xe của người khác (§3.4, trọng tâm IDOR của audit 2026-07-11).
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckConditionService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckConditionService" />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckConditionService.FillConditionAsync(System.Collections.Generic.List{Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem})">
            <summary>
            Đắp ODO và số đếm cảnh báo cho một trang xe.
            </summary>
            <remarks>
            <b>Một lượt truy vấn cho cả trang</b>: ODO lấy bằng bản nhận nhiều xe của
            <c>ITruckOdoService</c>, bộ phận và loại bộ phận mỗi thứ một truy vấn. Gọi trong vòng lặp
            từng xe là N+1 truy vấn trên màn dùng hằng ngày.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckConditionService.GetLastReplacementsAsync(System.Collections.Generic.List{System.Int32})">
            <summary>Lần thay gần nhất của từng bộ phận — một truy vấn cho cả lưới</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckConditionService.CountLevel(Ladaer.BackEnd.Infrastructures.DTO.Items.Trucks.TruckConditionItem,System.Nullable{Lada.Framework.Data.Enums.ComponentAlertLevel})">
            <summary>Cộng dồn số đếm và giữ mức nặng nhất của xe</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceBackgroundService">
            <summary>
            Chạy job quét cảnh báo bảo dưỡng mỗi ngày một lần.
            </summary>
            <remarks>
            Theo mẫu <c>PromotionBackgroundService</c>: vòng lặp tự quản chu kỳ bằng <c>Task.Delay</c>, mỗi
            lượt một scope DI riêng, lỗi một lượt không giết cả dịch vụ. Quét lại nhiều lần vô hại — job
            chống trùng theo cặp (bộ phận, mức) và chỉ gửi thông báo cho cảnh báo chưa gửi.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceBackgroundService.ScanInterval">
            <summary>Chu kỳ quét — mỗi ngày một lần theo §3.3 của plan</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceBackgroundService.RetryDelay">
            <summary>Chờ trước khi thử lại khi một lượt lỗi</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckMaintenanceMediaService">
            <summary>
            Tệp đính kèm (hoá đơn, ảnh hiện trạng) của một lần bảo dưỡng — đóng nợ BD-4.
            </summary>
            <remarks>
            <para>Đi qua bảng liên kết <see cref="T:Lada.Framework.Data.Domains.Trucks.TruckMaintenanceMedia"/> + bảng <see cref="T:Lada.Framework.Data.Domains.Medias.Media"/> dùng chung,
            theo đúng mẫu <c>FuelRefillMedia</c>. Trường chuỗi <c>TruckMaintenance.InvoiceUrl</c> cũ được
            giữ để hiển thị bản ghi lịch sử, không ghi mới (plan §3.11).</para>
            <para>Phạm vi chi nhánh tính theo <b>xe đang gắn với bản ghi bảo dưỡng</b>, không theo tham số
            client gửi — cùng luật với <c>TruckMaintCreateOrUpdate</c> (nợ BD-11).</para>
            <para>Tải hoá đơn lên thì bật luôn <c>HasInvoice</c> của bản ghi để cột "có hoá đơn" ở lịch sử
            bộ phận (<c>ComponentHistoryItem.HasInvoice</c>) không nói dối; xoá hoá đơn cuối cùng thì hạ cờ
            nếu bản ghi cũng không còn <c>InvoiceUrl</c> cũ.</para>
            <para>Nhận hai loại tệp, <b>phân nhánh theo nội dung file</b> chứ không theo đuôi hay content-type
            client khai: ảnh đi đường <c>ProcessImageAsync</c> (convert WebP) như cũ, tệp bắt đầu bằng
            <c>%PDF</c> đi <c>IDocumentService</c>. PDF chỉ nhận cho <see cref="F:Lada.Framework.Data.Enums.TruckMaintenanceMediaType.Invoice"/>
            và tối đa 10 MB mỗi tệp; tên file lưu xuống đĩa do server sinh, tên gốc người dùng chỉ giữ ở
            <c>Media.Caption</c> để hiển thị (plan đợt 2 §3.3).</para>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckMaintenanceMediaService.GetByMaintenance(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>Danh sách tệp của một lần bảo dưỡng trong phạm vi; rỗng khi ngoài phạm vi.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckMaintenanceMediaService.Upload(System.Int32,System.Collections.Generic.List{Microsoft.AspNetCore.Http.IFormFile},Lada.Framework.Data.Enums.TruckMaintenanceMediaType,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Int32,System.String)">
            <summary>Tải một hoặc nhiều tệp lên và gắn vào lần bảo dưỡng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckMaintenanceMediaService.Delete(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Int32,System.String)">
            <summary>Gỡ một tệp (xoá mềm dòng liên kết).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckMaintenanceMediaService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService.MaxPdfBytes">
            <summary>Trần dung lượng một tệp PDF (10 MB) — <c>DocumentService</c> không tự giới hạn,
            còn <c>[RequestSizeLimit]</c> ở controller chỉ chặn tổng cả request.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService.PdfExtension">
            <summary>Đuôi tệp duy nhất chấp nhận cho nhánh tài liệu.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService.PdfSignature">
            <summary>Chữ ký đầu tệp PDF: <c>%PDF</c>.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintenanceMedia},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Medias.Media},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintenance},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.Truck},Lada.Framework.Infrastructures.Services.IUnifiedMediaService,Lada.Framework.Infrastructures.Services.IDocumentService)">
            <summary>Khởi tạo dịch vụ tệp đính kèm bảo dưỡng.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService.GetByMaintenance(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService.Upload(System.Int32,System.Collections.Generic.List{Microsoft.AspNetCore.Http.IFormFile},Lada.Framework.Data.Enums.TruckMaintenanceMediaType,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Int32,System.String)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService.Delete(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope,System.Int32,System.String)">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService.IsPdfContentAsync(Microsoft.AspNetCore.Http.IFormFile)">
            <summary>
            Tệp có phải PDF không — đọc 4 byte đầu, <b>không</b> tin phần mở rộng hay content-type client khai.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService.ValidatePdfRules(Microsoft.AspNetCore.Http.IFormFile,Lada.Framework.Data.Enums.TruckMaintenanceMediaType,System.Boolean)">
            <summary>
            Luật nhận PDF (§3.3): chỉ dành cho hoá đơn, phải có đuôi .pdf, tối đa 10 MB.
            Trả về lý do từ chối, hoặc null nếu hợp lệ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService.ProcessPdfAsync(Microsoft.AspNetCore.Http.IFormFile,System.Int32)">
            <summary>
            Lưu PDF qua <see cref="T:Lada.Framework.Infrastructures.Services.IDocumentService"/> với <b>tên tệp do server sinh</b>.
            </summary>
            <remarks>
            <c>DocumentService.GenerateFileName</c> ghép tên gốc người dùng vào đường dẫn lưu; hoá đơn nằm
            sau URL media <b>không xác thực</b> nên tên phải khó đoán và không do người dùng đặt. Vì vậy
            nội dung được nạp lại vào một <see cref="T:Microsoft.AspNetCore.Http.FormFile"/> mang tên server sinh trước khi đưa xuống.
            Nạp vào bộ nhớ an toàn vì luật 10 MB đã chặn trước đó.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService.SafeDisplayName(System.String)">
            <summary>
            Tên tệp an toàn để hiển thị/ghi chú: bỏ mọi thành phần thư mục và ký tự điều khiển, cắt ngắn.
            </summary>
            <remarks>
            Bỏ luôn ký tự định dạng Unicode (nhóm <c>Cf</c>, ví dụ U+202E đảo chiều đọc) — chúng vô hình
            nhưng đủ để một tên tệp trông như <c>bao-gia.pdf</c> trong khi thật ra là tên khác; hoá đơn
            là chứng từ kế toán nên tên hiển thị không được đánh lừa người xem.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService.PdfDisplayName(System.String,System.String)">
            <summary>
            Tên hiển thị của một tệp PDF đã lưu: tên gốc ghi ở <c>Media.Caption</c>, không có thì lấy tên trên đĩa.
            </summary>
            <remarks>Tên gốc quá dài bị cắt còn 200 ký tự nên có thể mất đuôi <c>.pdf</c>; khi đó hàm rơi về
            tên tệp server sinh — xấu nhưng vẫn là tên thật của tệp, hơn là hiện một chuỗi cụt.</remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService.SafeFailureMessage(Lada.Framework.DTO.Result,System.String,System.String)">
            <summary>
            Thông báo lỗi trả về client: chỉ chuyển tiếp message của tầng media khi đó là lỗi <b>luật</b>.
            Lỗi hệ thống mang theo <c>ex.Message</c> (đường dẫn ổ đĩa, chuỗi kết nối...) nên phải nuốt (bẫy BD-24).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceMediaService.GetMaintenanceInScopeAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Nạp bản ghi bảo dưỡng nếu xe đang gắn với nó nằm trong phạm vi; null nếu không.
            Luật phạm vi nằm ở <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceScopeQuery"/> — một bản duy nhất cho cả miền.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAlertNotice">
            <summary>
            Mô tả một cảnh báo đủ để dựng nội dung thông báo, không cần tra thêm DB.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAlertNotice.TruckId">
            <summary>Xe</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAlertNotice.LicensePlate">
            <summary>Biển số</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAlertNotice.AgencyId">
            <summary>Chi nhánh quản lý xe tại thời điểm gửi</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAlertNotice.CurrentDriverId">
            <summary>Lái xe đang nhận xe; 0 = xe chưa có ai nhận</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAlertNotice.ComponentName">
            <summary>Tên bộ phận kèm vị trí, đã ghép sẵn để hiển thị</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAlertNotice.Level">
            <summary>Mức cảnh báo</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAlertNotice.RemainingText">
            <summary>Phần "còn bao nhiêu" hoặc "quá bao nhiêu", đã diễn giải sang tiếng Việt</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckMaintenanceNotifier">
            <summary>
            Gửi thông báo cảnh báo bảo dưỡng cho đúng người: lái xe đang nhận xe và quản lý của chi nhánh
            đang quản lý xe.
            </summary>
            <remarks>
            <b>Không dùng <c>SendToRoleAsync</c></b>: hàm đó gửi cho mọi user có role trên toàn hệ thống,
            tức quản lý chi nhánh này nhận cảnh báo xe của chi nhánh khác (Q8 đã chốt lọc phạm vi trước).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckMaintenanceNotifier.ResolveRecipientsAsync(System.Int32,System.Int32)">
            <summary>Danh sách người nhận thông báo cho một xe, đã lọc theo phạm vi chi nhánh của xe</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckMaintenanceNotifier.NotifyAsync(Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAlertNotice)">
            <summary>Gửi thông báo cho một cảnh báo; trả về số người đã gửi</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceNotifier">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckMaintenanceNotifier" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceNotifier.ManagerRole">
            <summary>Role quyết định ai là "quản lý" nhận cảnh báo (Q8)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceNotifier.GetManagerUserIdsAsync(System.Int32)">
            <summary>
            User có role quản lý cảnh báo và thuộc chi nhánh quản lý xe (hoặc chi nhánh cha).
            </summary>
            <remarks>
            Role trong hệ thống này đến từ <b>hai</b> nguồn: gán trực tiếp qua <c>UserRole</c> và gán
            theo nhóm quyền qua <c>Permission.PermissionRoles</c> — <c>IUserRoleResolver</c> gộp cả hai.
            Chiều ngược lại chưa có hàm dùng chung nào gộp đủ: <c>SendToRoleAsync</c> chỉ đọc
            <c>UserRole</c>, còn <c>SugUser</c> chỉ đọc <c>PermissionRoles</c>. Lấy thiếu một nguồn là
            im lặng bỏ sót đúng người cần biết xe sắp hỏng, nên ở đây hợp cả hai.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceConfigKeys">
            <summary>
            Tên khoá <c>AppConfig</c> của phân hệ bảo dưỡng xe tải — seed bằng migration
            <c>M202608151003</c>, không hardcode giá trị ở nơi khác.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceConfigKeys.NotificationEnabled">
            <summary>Công tắc gửi thông báo cảnh báo bảo dưỡng (plan §3.3.5, mặc định TẮT)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceConfigKeys.WarnBeforeKm">
            <summary>Ngưỡng cảnh báo trước theo số km còn lại (Q3: 1.000 km)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceConfigKeys.WarnBeforeDays">
            <summary>Ngưỡng cảnh báo trước theo số ngày còn lại (Q3: 15 ngày)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceConfigKeys.StaleOdoDays">
            <summary>Số ngày không có ODO mới thì coi dữ liệu km của xe là quá cũ (Q4: 30 ngày)</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceThresholds">
            <summary>
            Bộ ngưỡng cảnh báo toàn cục, đọc một lần rồi dùng cho cả lượt quét.
            </summary>
            <remarks>
            Job quét vài trăm bộ phận mỗi lượt; đọc <c>AppConfig</c> cho từng bộ phận là ba lần tra cache
            nhân số bộ phận. Gói thành một bản ghi để lấy một lần ở đầu lượt.
            </remarks>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceThresholds.WarnBeforeKm">
            <summary>Ngưỡng cảnh báo trước theo km — cấp toàn cục, loại bộ phận có thể ghi đè</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceThresholds.WarnBeforeDays">
            <summary>Ngưỡng cảnh báo trước theo ngày — cấp toàn cục, loại bộ phận có thể ghi đè</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceThresholds.StaleOdoDays">
            <summary>Số ngày sau đó coi chuỗi ODO của xe là quá cũ để tính km</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckMaintenanceSettings">
            <summary>
            Đọc 4 khoá cấu hình của phân hệ bảo dưỡng và diễn giải chúng thành bool/số.
            </summary>
            <remarks>
            Tách riêng để test được engine mà không dựng cả job, và để chỉ có <b>một</b> nơi diễn giải
            chuỗi cấu hình — mỗi nơi tự parse một kiểu là mỗi nơi sai một kiểu (bài học phân hệ KPI).
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckMaintenanceSettings.IsNotificationEnabledAsync">
            <summary>
            Có được phép gửi thông báo cảnh báo hay không.
            </summary>
            <remarks>
            <b>Fail-closed</b>: khoá thiếu, rỗng hay ghi sai đều trả <c>false</c>. Nhầm về phía "không
            gửi" chỉ làm job chạy chế độ ghi nhận (đúng bước 4 của §5.2); nhầm về phía "gửi" là hàng
            loạt lái xe nhận thông báo trước khi ai kịp đối chiếu danh sách cảnh báo.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckMaintenanceSettings.GetThresholdsAsync">
            <summary>Bộ ngưỡng toàn cục; khoá thiếu/sai rơi về mặc định đã chốt ở Q3/Q4</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceSettings">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckMaintenanceSettings" />
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceSettings.DefaultWarnBeforeKm">
            <summary>Ngưỡng km mặc định khi cấu hình thiếu hoặc ghi sai (Q3)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceSettings.DefaultWarnBeforeDays">
            <summary>Ngưỡng ngày mặc định khi cấu hình thiếu hoặc ghi sai (Q3)</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceSettings.DefaultStaleOdoDays">
            <summary>Số ngày ODO quá cũ mặc định khi cấu hình thiếu hoặc ghi sai (Q4)</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckMaintenanceSettings.ReadPositiveIntAsync(System.String,System.Int32)">
            <summary>
            Đọc một khoá số nguyên dương; thiếu, sai định dạng hay ≤ 0 đều rơi về mặc định.
            </summary>
            <remarks>
            Ép <see cref="P:System.Globalization.CultureInfo.InvariantCulture"/>: máy chủ chạy văn hoá vi-VN, để
            <c>int.Parse</c> tự đoán là mở đường cho dấu phân cách nghìn diễn giải khác nhau giữa máy.
            </remarks>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckOdoInfo">
            <summary>
            Chỉ số ODO hiện tại của một xe kèm thời điểm ghi nhận và nguồn lấy được.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckOdoInfo.Odo">
            <summary>
            Chỉ số ODO (km). Null khi xe chưa có dữ liệu ODO nào.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckOdoInfo.RecordedAt">
            <summary>
            Thời điểm ghi nhận chỉ số này. Null khi không có dữ liệu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckOdoInfo.Source">
            <summary>
            Nguồn lấy được: FuelRefill / TruckActivity / LastRefillOdo / None
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckOdoInfo.AgeInDays">
            <summary>
            Số ngày kể từ lần ghi nhận gần nhất tới thời điểm đối chiếu. Null khi không có dữ liệu.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckOdoInfo.HasData">
            <summary>
            Có dữ liệu ODO hay không
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckOdoService">
            <summary>
            Nguồn sự thật duy nhất về chỉ số ODO hiện tại của xe.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckOdoService.GetCurrentOdoAsync(System.Int32,System.Nullable{System.DateTimeOffset})">
            <summary>
            Lấy chỉ số ODO hiện tại của một xe kèm thời điểm ghi nhận.
            </summary>
            <param name="truckId">ID xe</param>
            <param name="asOf">Mốc thời gian đối chiếu để tính tuổi dữ liệu (mặc định: hiện tại)</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckOdoService.GetCurrentOdoAsync(System.Collections.Generic.IEnumerable{System.Int32},System.Nullable{System.DateTimeOffset})">
            <summary>
            Lấy ODO hiện tại cho nhiều xe một lượt — dùng cho màn tình trạng đội xe và job quét,
            tránh N+1 truy vấn.
            </summary>
            <param name="truckIds">Danh sách ID xe</param>
            <param name="asOf">Mốc thời gian đối chiếu để tính tuổi dữ liệu (mặc định: hiện tại)</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckOdoService">
             <summary>
             Triển khai nguồn ODO chuẩn.
            
             <para><b>Luật chống nhiễu — thiết kế theo số đo thật ngày 2026-08-15 (plan §5.1), không đoán:</b></para>
             <list type="number">
             <item><description><b>Bỏ phiếu đổ dầu đã bị từ chối</b> (<c>FuelRefillStatus.Rejected</c>). Đo được:
             3 trong 5 cặp ODO giảm ngược của toàn bộ chuỗi là do phiếu nhập sai đã bị người duyệt bác;
             lọc chúng đi thì tỷ lệ nhiễu còn 0,14%.</description></item>
             <item><description><b>Lấy bản ghi MỚI NHẤT theo thời gian, tuyệt đối không lấy MAX(Odo).</b>
             Xe 29H78282 có phiếu ODO 97.772 (đã bị từ chối) rồi đồng hồ được thay và chuỗi thật bắt đầu
             lại từ 275. Lấy max cho ra 97.772 — sai gấp 15 lần. Đồng hồ ODO bị thay là chuyện có thật
             nên "ODO chỉ tăng" không phải bất biến đúng.</description></item>
             <item><description><b><c>TruckActivity.CurrentOdo</c> chỉ là nguồn dự phòng</b>: toàn bộ 658 bản ghi
             check-in/check-out trên dữ liệu thật đều có ODO = 0 (trường có nhưng chưa bao giờ được nhập).
             Vẫn đọc để phòng khi luồng nhập được bật, nhưng lọc <c>&gt; 0</c>.</description></item>
             <item><description><b><c>Truck.LastRefillOdo</c> là nguồn cuối cùng, không dùng để đối chiếu đúng-sai</b>:
             đo được lệch tới 21.140 km so với phiếu đổ dầu mới nhất, và 5 xe có phiếu nhưng trường này NULL —
             nó bị cập nhật thiếu nhịp. Chỉ dùng khi xe không có phiếu đổ dầu và không có hoạt động nào.</description></item>
             </list>
            
             <para>Dịch vụ này <b>chỉ đọc</b> — không bao giờ UPDATE <c>TruckActivity</c>, <c>FuelRefills</c>
             hay <c>Trucks</c> (plan §3.11: chuỗi ODO lịch sử là dữ liệu chỉ đọc với phân hệ bảo dưỡng).</para>
             </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckOdoService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.FuelRefill},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckActivity},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.Truck})">
            <summary>
            Khởi tạo dịch vụ ODO.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckOdoService.GetCurrentOdoAsync(System.Int32,System.Nullable{System.DateTimeOffset})">
            <inheritdoc/>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckOdoService.GetCurrentOdoAsync(System.Collections.Generic.IEnumerable{System.Int32},System.Nullable{System.DateTimeOffset})">
            <inheritdoc/>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService">
            <summary>
            Giao diện cho dịch vụ quản lý xe tải.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel)">
            <summary>
            Tạo mới hoặc cập nhật thông tin xe tải.
            </summary>
            <param name="param">Thông tin xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.GetTruckMediaAsync(System.Int32)">
            <summary>
            Lấy danh sách media (ảnh đăng ký, đăng kiểm) của xe tải.
            </summary>
            <param name="truckId">ID xe tải.</param>
            <returns>Danh sách media items.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.Delete(System.Int32)">
            <summary>
            Xóa thông tin xe tải.
            </summary>
            <param name="id">ID xe tải cần xóa.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.GetByIds(Ladaer.BackEnd.Infrastructures.DTO.Models.KeyModels{System.Int32})">
            <summary>
            Lấy thông tin xe tải theo danh sách ID.
            </summary>
            <param name="param">Danh sách ID của xe tải.</param>
            <returns>Kết quả chứa thông tin xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.GetTruckByAgencyId(System.Int32)">
            <summary>
            Lấy thông tin xe tải theo ID của đại lý.
            </summary>
            <param name="param">ID của đại lý.</param>
            <returns>Kết quả chứa thông tin xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.GetTruckByAgencyIds(System.Collections.Generic.List{System.Int32})">
            <summary>
            Lấy thông tin xe tải theo danh sách ID đơn vị (bao gồm chi nhánh con).
            </summary>
            <param name="agencyIds">Danh sách ID đơn vị.</param>
            <returns>Kết quả chứa thông tin xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Collections.Generic.List{System.Int32})">
            <summary>
            Tìm kiếm thông tin xe tải.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.GetTruckActivityHistory(System.Int32)">
            <summary>
            Lấy lịch sử giao nhận xe tải theo ID xe
            </summary>
            <param name="truckId">ID xe tải</param>
            <returns>Danh sách lịch sử giao nhận xe với thông tin ODO, ghi chú và ảnh</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.UpdateLastRefillOdo(System.Int32,System.Int32)">
            <summary>
            Cập nhật giá trị ODO đổ dầu gần nhất của xe tải
            </summary>
            <param name="truckId">ID xe tải</param>
            <param name="odoValue">Giá trị ODO</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.GetById(System.Int32)">
            <summary>
            Lấy thông tin xe tải theo ID.
            </summary>
            <param name="truckId">ID của xe tải.</param>
            <returns>Thông tin xe tải kèm danh sách ảnh.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckSpecByIds(Ladaer.BackEnd.Infrastructures.DTO.Models.KeyModels{System.Int32})">
            <summary>
            Lấy thông số kỹ thuật của xe tải theo danh sách ID.
            </summary>
            <param name="param">Danh sách ID của thông số kỹ thuật.</param>
            <returns>Kết quả chứa thông số kỹ thuật của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckSpecCreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecificationModel)">
            <summary>
            Tạo mới hoặc cập nhật thông số kỹ thuật của xe tải.
            </summary>
            <param name="param">Thông số kỹ thuật của xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckSpecDelete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecificationModel)">
            <summary>
            Xóa thông số kỹ thuật của xe tải.
            </summary>
            <param name="param">Thông số kỹ thuật của xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckSpecSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm thông số kỹ thuật của xe tải.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm thông số kỹ thuật của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckSpecGetAll(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecificationModel)">
            <summary>
            Lấy tất cả thông số kỹ thuật của xe tải.
            </summary>
            <param name="param">Thông số kỹ thuật của xe tải.</param>
            <returns>Kết quả chứa tất cả thông số kỹ thuật của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckSpecAttrGetAll">
            <summary>
            Lấy tất cả thuộc tính kỹ thuật của xe tải.
            </summary>
            <returns>Kết quả chứa tất cả thuộc tính kỹ thuật của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckSpecAttrSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm thuộc tính kỹ thuật của xe tải.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm thuộc tính kỹ thuật của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckSpecAttrCreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecAttributeModel)">
            <summary>
            Tạo mới hoặc cập nhật thuộc tính kỹ thuật của xe tải.
            </summary>
            <param name="param">Thuộc tính kỹ thuật của xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckSpecAttrDelete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecAttributeModel)">
            <summary>
            Xóa thuộc tính kỹ thuật của xe tải.
            </summary>
            <param name="param">Thuộc tính kỹ thuật của xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckMaintByIds(Ladaer.BackEnd.Infrastructures.DTO.Models.KeyModels{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Lấy thông tin bảo dưỡng xe tải theo danh sách ID.
            </summary>
            <param name="param">Danh sách ID của thông tin bảo dưỡng.</param>
            <returns>Kết quả chứa thông tin bảo dưỡng xe tải.</returns>
            <remarks>Lọc theo phạm vi chi nhánh của xe đang gắn với bản ghi (nợ BD-12) — cùng luật với TruckMaintCreateOrUpdate.</remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckMaintSearch(Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Tìm kiếm thông tin bảo dưỡng xe tải.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm thông tin bảo dưỡng xe tải.</returns>
            <remarks>Lọc theo phạm vi chi nhánh của xe đang gắn với bản ghi (nợ BD-12).</remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckMaintCreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Tạo mới hoặc cập nhật thông tin bảo dưỡng xe tải.
            </summary>
            <param name="param">Thông tin bảo dưỡng xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckMaintDelete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Xóa thông tin bảo dưỡng xe tải.
            </summary>
            <param name="param">Thông tin bảo dưỡng xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckMaintAttrGetAll">
            <summary>
            Lấy tất cả thuộc tính bảo dưỡng của xe tải.
            </summary>
            <returns>Kết quả chứa tất cả thuộc tính bảo dưỡng của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckMaintAttrSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm thuộc tính bảo dưỡng của xe tải.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm thuộc tính bảo dưỡng của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckMaintAttrCreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintAttributeModel)">
            <summary>
            Tạo mới hoặc cập nhật thuộc tính bảo dưỡng của xe tải.
            </summary>
            <param name="param">Thuộc tính bảo dưỡng của xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckMaintAttrDelete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintAttributeModel)">
            <summary>
            Xóa thuộc tính bảo dưỡng của xe tải.
            </summary>
            <param name="param">Thuộc tính bảo dưỡng của xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.TruckMaintLinkGetAll(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintLinkModel,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Lấy tất cả thông tin liên kết bảo dưỡng của xe tải.
            </summary>
            <param name="param">Thông tin liên kết bảo dưỡng của xe tải.</param>
            <returns>Kết quả chứa tất cả thông tin liên kết bảo dưỡng của xe tải.</returns>
            <remarks>Gác phạm vi chi nhánh theo xe của bản ghi bảo dưỡng (nợ BD-12) — dòng công
            việc là một phần của bản ghi, ai không xem được bản ghi thì cũng không xem được dòng.</remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.ITruckService.SugTruck(System.String)">
            <summary>
            Gợi ý xe theo từ khóa (biển số, thương hiệu, model)
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService">
            <summary>
            Triển khai dịch vụ quản lý xe tải.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.#ctor(Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Categories.Agency},Lada.Framework.Data.Repositories.IUserRepository{Lada.Framework.Data.Domains.Identity.User},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.Truck},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckActivity},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckActivityMedia},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Medias.Media},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckAsset},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckSpecAttribute},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintAttribute},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintenance},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintLink},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckSpecification},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMedia},Lada.Framework.Infrastructures.Services.IUnifiedMediaService,Ladaer.BackEnd.Infrastructures.Services.Trucks.IComponentMaintenanceSyncService,Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckComponent},Lada.Framework.Data.Repositories.IRepository{Lada.Framework.Data.Domains.Trucks.TruckMaintenanceMedia},Microsoft.Extensions.Logging.ILogger{Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService})">
            <summary>
            Khởi tạo
            </summary>
            <param name="agencyRepository"></param>
            <param name="userRepository"></param>
            <param name="truckRepository"></param>
            <param name="truckActivityRepository"></param>
            <param name="truckActivityMediaRepository"></param>
            <param name="mediaRepository"></param>
            <param name="truckAssetRepository"></param>
            <param name="truckSpecAttributeRepository"></param>
            <param name="truckMaintAttributeRepository"></param>
            <param name="truckMaintenanceRepository"></param>
            <param name="truckMaintLinkRepository"></param>
            <param name="truckSpecificationRepository"></param>
            <param name="unifiedMediaService"></param>
            <param name="componentMaintenanceSyncService"></param>
            <param name="truckComponentRepository"></param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.Search(Lada.Framework.DTO.SmartTable.SmartTableParam,System.Collections.Generic.List{System.Int32})">
            <summary>
            Tìm kiếm thông tin xe tải.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.GetByIds(Ladaer.BackEnd.Infrastructures.DTO.Models.KeyModels{System.Int32})">
            <summary>
            Lấy thông tin xe tải theo danh sách ID.
            </summary>
            <param name="param">Danh sách ID của xe tải.</param>
            <returns>Kết quả chứa thông tin xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.GetTruckByAgencyId(System.Int32)">
            <summary>
            Lấy thông tin xe tải theo ID của đại lý.
            </summary>
            <param name="param">ID của đại lý.</param>
            <returns>Kết quả chứa thông tin xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.GetTruckByAgencyIds(System.Collections.Generic.List{System.Int32})">
            <summary>
            Lấy thông tin xe tải theo danh sách ID đơn vị (bao gồm chi nhánh con).
            </summary>
            <param name="agencyIds">Danh sách ID đơn vị.</param>
            <returns>Kết quả chứa thông tin xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.CreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel)">
            <summary>
            Tạo mới hoặc cập nhật thông tin xe tải.
            </summary>
            <param name="param">Thông tin xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.HandleTruckMediaAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckModel)">
            <summary>
            Xử lý upload/cập nhật media cho xe tải (ảnh đăng ký, đăng kiểm)
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.Delete(System.Int32)">
            <summary>
            Xóa thông tin xe tải.
            </summary>
            <param name="id">ID xe tải cần xóa.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.GetById(System.Int32)">
            <summary>
            Lấy thông tin xe tải theo ID.
            </summary>
            <param name="truckId">ID của xe tải.</param>
            <returns>Thông tin xe tải kèm danh sách ảnh.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.GetTruckMediaAsync(System.Int32)">
            <summary>
            Lấy danh sách media (ảnh đăng ký, đăng kiểm) của xe tải
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckSpecSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm thông số kỹ thuật của xe tải.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm thông số kỹ thuật của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckSpecGetAll(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecificationModel)">
            <summary>
            Lấy tất cả thông số kỹ thuật của xe tải.
            </summary>
            <param name="param">Thông số kỹ thuật của xe tải.</param>
            <returns>Kết quả chứa tất cả thông số kỹ thuật của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckSpecByIds(Ladaer.BackEnd.Infrastructures.DTO.Models.KeyModels{System.Int32})">
            <summary>
            Lấy thông số kỹ thuật của xe tải theo danh sách ID.
            </summary>
            <param name="param">Danh sách ID của thông số kỹ thuật.</param>
            <returns>Kết quả chứa thông số kỹ thuật của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckSpecCreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecificationModel)">
            <summary>
            Tạo mới hoặc cập nhật thông số kỹ thuật của xe tải.
            </summary>
            <param name="param">Thông số kỹ thuật của xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckSpecDelete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecificationModel)">
            <summary>
            Xóa thông số kỹ thuật của xe tải.
            </summary>
            <param name="param">Thông số kỹ thuật của xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckSpecAttrGetAll">
            <summary>
            Lấy tất cả thuộc tính kỹ thuật của xe tải.
            </summary>
            <returns>Kết quả chứa tất cả thuộc tính kỹ thuật của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckSpecAttrSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm thuộc tính kỹ thuật của xe tải.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm thuộc tính kỹ thuật của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckSpecAttrCreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecAttributeModel)">
            <summary>
            Tạo mới hoặc cập nhật thuộc tính kỹ thuật của xe tải.
            </summary>
            <param name="param">Thuộc tính kỹ thuật của xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckSpecAttrDelete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckSpecAttributeModel)">
            <summary>
            Xóa thuộc tính kỹ thuật của xe tải.
            </summary>
            <param name="param">Thuộc tính kỹ thuật của xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckMaintSearch(Lada.Framework.DTO.SmartTable.SmartTableParam,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Tìm kiếm thông tin bảo dưỡng xe tải.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm thông tin bảo dưỡng xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckMaintByIds(Ladaer.BackEnd.Infrastructures.DTO.Models.KeyModels{System.Int32},Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Lấy thông tin bảo dưỡng xe tải theo danh sách ID.
            </summary>
            <param name="param">Danh sách ID của thông tin bảo dưỡng.</param>
            <returns>Kết quả chứa thông tin bảo dưỡng xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckMaintCreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Tạo mới hoặc cập nhật thông tin bảo dưỡng xe tải.
            </summary>
            <param name="param">Thông tin bảo dưỡng xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.ValidateMaintLinkShapes(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel)">
            <summary>
            Mỗi dòng công việc phải trỏ tới ít nhất một thứ: hạng mục theo danh mục cũ hoặc bộ phận trên xe.
            Hạng mục gửi 0 được coi là null (client cũ gửi 0 khi bỏ trống) — trước GĐ E giá trị 0 đi thẳng
            xuống FK và nổ DbUpdateException, còn production không có hạng mục nào để mà chọn.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.LaDuongDanAnToan(System.String)">
            <summary>
            Xe có nằm trong phạm vi chi nhánh của người gọi hay không.
            </summary>
            <remarks>
            Cùng luật với <c>TruckComponentService.IsTruckInScope</c>: <c>Unrestricted</c> (Founder)
            thấy tất, <c>None</c> không thấy gì, còn lại lọc theo cây chi nhánh. Đặt ở đây vì luồng
            bảo dưỡng cũ nằm trong <c>TruckService</c>, không đi qua service bộ phận.
            </remarks>
            <summary>
            Chuỗi có an toàn để hiển thị thành liên kết bấm được không: rỗng (xoá) hoặc http/https.
            </summary>
            <remarks>
            Trường <c>InvoiceUrl</c> vốn là ô nhập tự do của màn cũ và nay được render thành
            <c>&lt;a href&gt;</c> ở hồ sơ xe. Frontend đã lọc scheme khi hiển thị; chốt chặn thứ hai
            nằm đây để dữ liệu bẩn không vào được DB ngay từ đầu.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.IsMaintenanceInScopeAsync(System.Int32,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Bản ghi bảo dưỡng có nằm trong phạm vi chi nhánh của người gọi không — xét theo XE
            đang gắn với bản ghi.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.ValidateComponentOwnershipAsync(System.Int32,Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel)">
            <summary>
            Mọi bộ phận được nhắc tới trong lần lưu này phải thuộc đúng chiếc xe của bản ghi bảo dưỡng.
            </summary>
            <remarks>
            <c>TruckComponentId</c> là số nguyên client gửi lên và id bộ phận tăng dần nên đoán được.
            Không có kiểm tra này thì một dòng <c>Replace</c> trỏ sang bộ phận xe chi nhánh khác sẽ
            ghi đè <c>InstalledDate</c>/<c>InstalledOdo</c> của bộ phận đó và đóng sạch cảnh báo đang
            mở của nó — tức tắt cảnh báo an toàn của một chiếc xe mình không được phép đụng tới.
            Kiểm cả dòng cũ đang có: bản ghi bảo dưỡng bị đổi sang xe khác thì liên kết cũ cũng thành
            liên kết xuyên xe. Trả <c>null</c> khi mọi thứ hợp lệ.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.SyncTruckMaintLinksAsync(Lada.Framework.Data.Domains.Trucks.TruckMaintenance,Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel)">
            <summary>
            Đồng bộ danh sách dòng công việc của một lần bảo dưỡng theo <b>từng dòng</b>.
            </summary>
            <remarks>
            <b>Đây là chỗ đóng nợ BD-8.</b> Luồng cũ xoá mềm toàn bộ <c>TruckMaintLink</c> rồi chèn
            lại từ payload; payload màn cũ không có <c>TruckComponentId</c>/<c>ActionType</c>/
            <c>LineCost</c> nên một lần bấm Lưu vô hại làm thủng lịch sử tuổi thọ của bộ phận.
            Luật mới:
            <list type="bullet">
            <item>Khớp dòng theo <c>Id</c>; màn cũ không gửi <c>Id</c> nên khớp tạm theo hạng mục để
            không nhân đôi dòng sau mỗi lần Lưu.</item>
            <item>Ba trường mới chỉ ghi đè khi payload có giá trị — <c>null</c> là "không nhắc tới".</item>
            <item>Dòng đang có bộ phận mà payload không nhắc tới thì <b>giữ nguyên</b>; muốn xoá phải
            nói tên nó trong <c>DeletedTruckMaintLinkIds</c>.</item>
            </list>
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckMaintDelete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintenanceModel,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Xóa thông tin bảo dưỡng xe tải.
            </summary>
            <param name="param">Thông tin bảo dưỡng xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckMaintLinkGetAll(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintLinkModel,Ladaer.BackEnd.Infrastructures.Services.Trucks.MaintenanceAgencyScope)">
            <summary>
            Lấy tất cả thông tin liên kết bảo dưỡng của xe tải.
            </summary>
            <param name="param">Thông tin liên kết bảo dưỡng của xe tải.</param>
            <returns>Kết quả chứa tất cả thông tin liên kết bảo dưỡng của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckMaintAttrGetAll">
            <summary>
            Lấy tất cả thuộc tính bảo dưỡng của xe tải.
            </summary>
            <returns>Kết quả chứa tất cả thuộc tính bảo dưỡng của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckMaintAttrSearch(Lada.Framework.DTO.SmartTable.SmartTableParam)">
            <summary>
            Tìm kiếm thuộc tính bảo dưỡng của xe tải.
            </summary>
            <param name="param">Thông số tìm kiếm.</param>
            <returns>Kết quả tìm kiếm thuộc tính bảo dưỡng của xe tải.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckMaintAttrCreateOrUpdate(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintAttributeModel)">
            <summary>
            Tạo mới hoặc cập nhật thuộc tính bảo dưỡng của xe tải.
            </summary>
            <param name="param">Thuộc tính bảo dưỡng của xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.TruckMaintAttrDelete(Ladaer.BackEnd.Infrastructures.DTO.Models.Trucks.TruckMaintAttributeModel)">
            <summary>
            Xóa thuộc tính bảo dưỡng của xe tải.
            </summary>
            <param name="param">Thuộc tính bảo dưỡng của xe tải.</param>
            <returns>Kết quả của thao tác.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.GetTruckActivityHistory(System.Int32)">
            <summary>
            Lấy lịch sử giao nhận xe tải theo ID xe
            </summary>
            <param name="truckId">ID của xe tải</param>
            <returns>Danh sách lịch sử giao nhận xe</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.GetActivityMediaAsync(System.Int32)">
            <summary>
            Lấy danh sách media cho một activity
            </summary>
            <param name="activityId">ID của activity</param>
            <returns>Danh sách media items</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Trucks.TruckService.UpdateLastRefillOdo(System.Int32,System.Int32)">
            <summary>
            Cập nhật giá trị ODO đổ dầu gần nhất của xe tải
            </summary>
            <param name="truckId">ID xe tải</param>
            <param name="odoValue">Giá trị ODO</param>
            <returns>Kết quả cập nhật</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.ITtsCacheService">
            <summary>
            Gateway giọng đọc dẫn đường: câu → khoá cache → file trên đĩa; thiếu thì gọi nguồn tổng hợp
            một lần rồi giữ mãi (plan §3.5.6). Không đụng database.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.ITtsCacheService.BatchAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchModel,System.Int32,System.Threading.CancellationToken)">
            <summary>
            Bảo đảm mọi câu trong <paramref name="model"/> có âm thanh; trả bytes cho câu app chưa có.
            </summary>
            <param name="model">Các câu cần đọc + hash app đã có.</param>
            <param name="userId">Người gọi — để tính trần ký tự câu mới theo ngày.</param>
            <param name="cancellationToken">Huỷ khi app ngắt kết nối (lượt tổng hợp đang chạy vẫn chạy nốt và vào cache).</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsCacheService">
            <summary>Cài đặt <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Tts.ITtsCacheService"/>. Đăng ký SINGLETON — giữ trạng thái dùng chung.</summary>
            <remarks>
            Trạng thái trong bộ nhớ (lượt đang bay, trần ngày, tạm ngắt khi hết token) mất khi khởi động
            lại tiến trình — chấp nhận: trần ngày là chốt chặn chống đốt token (Cloud) / đốt CPU (tự host),
            không phải sổ kế toán. Câu <c>Pending</c> của nguồn tự host được hoàn trần ngay (không Ok) nên hỏi
            lại nhiều lần không tiêu hạn mức.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsCacheService.QuotaBlockDuration">
            <summary>Hết token / khoá sai thì ngừng gọi VieNeu chừng này rồi mới thử lại.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsCacheService.MaxQuotaBlock">
            <summary>Hết hạn mức ngày/tuần có giờ đặt lại: ngừng tới giờ đó nhưng không quá chừng này.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsCacheService.DefaultRateLimitBlock">
            <summary>
            429 không kèm Retry-After cũng không kèm giờ đặt lại (lớp chắn theo IP của VieNeu) thì
            chờ chừng này. Ngắn hơn tổng hai lượt thử lại của app (4 s + 12 s).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsCacheService.VietnamOffset">
            <summary>Múi giờ tính "ngày" của trần ký tự.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsCacheService.BatchAsync(Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsBatchModel,System.Int32,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsCacheService.ResolveCacheDir(Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions,Microsoft.Extensions.Hosting.IHostEnvironment)">
            <summary>
            Thư mục cache: <c>Tts:CacheDir</c>, trống thì <c>{ContentRoot}/App_Data/tts-cache</c>. Tiến trình PHẢI có
            quyền ghi — trên IIS app pool identity thường chỉ đọc được thư mục site: khi đó mọi câu có âm thanh về
            đều thành <c>Unavailable</c> "Không lưu được file âm thanh" trong khi câu <c>Pending</c> vẫn Success →
            app lúc báo lỗi lúc không (cắn thật production 2026-09-28, thư mục App_Data không bao giờ xuất hiện).
            <c>GET api/Tts/Status</c> kiểm quyền ghi này.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsCacheService.AudioPath(System.String,System.String)">
            <summary>
            Đường dẫn file âm thanh của một khoá — chia thư mục theo 2 ký tự đầu. Đuôi file theo
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Tts.ITtsEngine.FileExtension"/> của nguồn (cả hai nguồn hiện là mp3).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsCacheService.WorstCode(System.Collections.Generic.IEnumerable{System.String})">
            <summary>
            Mã lỗi cấp lượt gọi: lỗi nặng nhất trong các câu hỏng. Câu bị từ chối riêng lẻ (<c>Rejected</c>)
            hay đang chờ sinh nền ở nguồn tự host (<c>Pending</c>) KHÔNG làm cả lượt thành lỗi — những câu
            còn lại vẫn đọc được, app bỏ câu thiếu im lặng.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsText">
            <summary>Luật chữ của gateway: chuẩn hoá, kiểm, băm, tính ký tự.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsText.MinBilledChars">
            <summary>VieNeu tính tối thiểu chừng này ký tự mỗi lần gọi (đo thật 2026-09-23).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsText.ForbiddenChars">
            <summary>
            Ký tự cấm ngoài ký tự điều khiển: ngoặc nhọn/vuông/nhọn kép — VieNeu có cú pháp chèn cảm
            xúc trong câu, và câu chỉ dẫn thật (Valhalla + app) không bao giờ chứa chúng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsText.Normalize(System.String)">
            <summary>NFC, gộp mọi khoảng trắng liền nhau thành một dấu cách, bỏ hai đầu.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsText.Validate(System.String,System.Int32)">
            <summary>Lỗi của câu đã chuẩn hoá, <c>null</c> khi hợp lệ.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsText.VoiceKey(System.String)">
            <summary>
            Nhận diện GIỌNG đang dùng (12 ký tự hex của sha256 khoá nguồn) — app thấy đổi thì bỏ chỉ
            mục câu → file cũ, không trộn hai giọng trong một chuyến. Không lộ khoá API.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsText.Hash(System.String,System.String)">
            <summary><c>sha256(câu \n khoá nguồn)</c>, hex thường.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsText.IsHash(System.String)">
            <summary>Chuỗi có đúng dạng khoá cache không.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsText.BilledChars(System.String)">
            <summary>Số ký tự VieNeu tính tiền cho một câu.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.ITtsEngineProvider">
            <summary>
            Chọn nguồn tổng hợp cho MỖI lượt gọi — để đổi nguồn (Cloud ↔ tự host), địa chỉ sidecar hay khoá
            lúc đang chạy mà không khởi động lại API (đợt tự host 2026-09-28, memory <c>project-tts-tu-host</c>).
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.ITtsEngineProvider.GetAsync(System.Threading.CancellationToken)">
            <summary>Engine đang có hiệu lực. Không ném lỗi — đọc cấu hình hỏng thì rơi về appsettings.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.StaticTtsEngineProvider">
            <summary>Provider cố định một engine — cho test và cho chỗ không có AppConfig.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.StaticTtsEngineProvider.#ctor(Ladaer.BackEnd.Infrastructures.Services.Tts.ITtsEngine)">
            <summary>Provider cố định một engine — cho test và cho chỗ không có AppConfig.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.StaticTtsEngineProvider.GetAsync(System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsConfigKeys">
            <summary>
            Khoá <c>AppConfig</c> (màn Cấu hình hệ thống, bảng <c>AppConfig</c>) của giọng đọc dẫn đường. Giá trị
            trống thì rơi về section <c>Tts</c> của appsettings / biến môi trường (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions"/>).
            Seed bằng migration <c>ChenCauHinhGiongDocTuHost</c>.
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsConfigKeys.Engine">
            <summary><c>VieNeuCloud</c> | <c>VieNeuSelfHost</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsConfigKeys.SelfHostBaseUrl">
            <summary>Gốc URL sidecar, ví dụ <c>http://192.168.1.50:8011</c>.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsConfigKeys.SelfHostApiKey">
            <summary>Khoá Bearer của sidecar (<c>SIDECAR_API_KEY</c>).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsConfigKeys.SelfHostVoice">
            <summary>Giọng sidecar đang dùng — thành phần khoá cache.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsConfigKeys.SelfHostModelVersion">
            <summary>Tag VieNeu-TTS đang ghim ở sidecar — thành phần khoá cache.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsConfigKeys.All">
            <summary>Đủ năm khoá, theo thứ tự hiển thị.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.AppConfigTtsEngineProvider">
            <summary>
            Đọc năm khoá <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsConfigKeys"/> từ AppConfig (Lada.Framework cache 1 giờ và làm mới ngay khi
            sửa qua màn quản trị — <c>AppConfigManagementService.ReloadFrameworkCacheAsync</c>), rơi về
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions"/> khi khoá trống hoặc DB lỗi. Giữ engine đã dựng cho tới khi giá trị đổi; đọc lại
            tối đa mỗi <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Tts.AppConfigTtsEngineProvider.RefreshInterval"/> nên đổi cấu hình có hiệu lực trong vòng nửa phút.
            </summary>
            <remarks>
            Singleton (như <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsCacheService"/>) nhưng <c>IAppConfigService</c> của Framework là scoped
            (cần DbContext) → mở scope riêng cho mỗi lần đọc. Khoá Cloud (<c>Tts:VieNeu:ApiKey</c>) vẫn đọc từ
            appsettings/biến môi trường như trước — chỉ phần tự host và công tắc nguồn nằm ở AppConfig.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.AppConfigTtsEngineProvider.RefreshInterval">
            <summary>Đọc lại AppConfig tối đa mỗi chừng này.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.AppConfigTtsEngineProvider.GetAsync(System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.AppConfigTtsEngineProvider.ReadAsync">
            <summary>Tên nguồn + cấu hình tự host đang có hiệu lực (AppConfig đè appsettings). Không ném lỗi.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions">
            <summary>
            Cấu hình gateway giọng đọc dẫn đường (section <c>Tts</c>). Đợt dẫn đường DriverApp GĐ D2
            (plan <c>docs/plan-dan-duong-driverapp.md</c> §3.5.6) và đợt tự host 2026-09-28
            (memory <c>project-tts-tu-host</c>).
            </summary>
            <remarks>
            Hai nguồn tổng hợp, chọn bằng <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.Engine"/>: <c>VieNeuCloud</c> (api.vieneu.io, cần
            <c>Tts:VieNeu:ApiKey</c>) hoặc <c>VieNeuSelfHost</c> (sidecar trên ladamap, cần <c>Tts:SelfHost:BaseUrl</c>
            + <c>ApiKey</c>). Thiếu khoá thì endpoint trả 503 "chưa cấu hình" chứ API vẫn khởi động — app coi đó là
            lỗi giọng đọc và dẫn đường bằng chữ. Khoá chỉ đặt ở user-secrets (dev) hoặc cấu hình server
            (production), KHÔNG vào repo:
            <c>dotnet user-secrets set "Tts:SelfHost:ApiKey" "&lt;khoá&gt;" --project Ladaer.BackEnd/Ladaer.BackEnd</c>.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.SectionName">
            <summary>Tên section trong cấu hình.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.EngineVieNeuCloud">
            <summary>Giá trị <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.Engine"/>: VieNeu Cloud API.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.EngineVieNeuSelfHost">
            <summary>Giá trị <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.Engine"/>: sidecar VieNeu-TTS tự host trên ladamap.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.Engine">
            <summary>
            Nguồn tổng hợp đang dùng: <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.EngineVieNeuCloud"/> (mặc định) hay <see cref="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.EngineVieNeuSelfHost"/>.
            Đổi nguồn là đổi khoá cache và <c>VoiceKey</c> → app tự bỏ chỉ mục giọng cũ, không trộn hai giọng.
            Khoá AppConfig <c>Tts.Engine</c> (màn Cấu hình hệ thống) ĐÈ giá trị này khi không trống — xem
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsConfigKeys"/>; tương tự cho bốn khoá <c>Tts.SelfHost.*</c>.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.CacheDir">
            <summary>
            Thư mục cache file âm thanh. Để trống = <c>{ContentRoot}/App_Data/tts-cache</c>. Cache là
            dữ liệu công cộng (câu chỉ dẫn theo tên đường), xoá đi chỉ tốn token/CPU tổng hợp lại.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.MaxTextsPerBatch">
            <summary>Số câu tối đa mỗi lần gọi (plan §3.11).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.MaxTextLength">
            <summary>Số ký tự tối đa mỗi câu (plan §3.11). Câu dài nhất đo được ở D1/D2 là 106.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.UserDailyCharBudget">
            <summary>
            Trần ký tự TÍNH TIỀN của câu mới (chưa có trong cache) mỗi người dùng mỗi ngày. Câu ngắn
            hơn 50 ký tự vẫn tính 50 — đúng cách VieNeu tính. 20.000 ≈ 400 câu mới/ngày, gấp nhiều lần
            một chuyến 50 điểm (~150 câu, phần lớn trúng cache sau vài ngày). Với nguồn tự host đây là
            chốt chống lạm dụng CPU; câu <c>Pending</c> được hoàn trần ngay.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.DailyCharBudget">
            <summary>
            Trần ký tự tính tiền của câu mới toàn server mỗi ngày — chốt chặn cuối để một lỗi app
            hay một tài khoản bị lộ không đốt hết gói token trong vài phút. 300.000 ký tự ≈ 1,17 triệu
            token v4 ≈ 6.000 câu mới.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.MaxConcurrency">
            <summary>
            Số lần gọi nguồn chạy đồng thời toàn server, áp cho nguồn đang chọn. Cloud đo Việc 0 D2: 4 luồng
            v4 ra ~165 lượt/phút, 1,2 s/câu (p50). Sidecar tự host trả lời tức thì (cache hoặc pending) nên
            4 cũng đủ; TTS thật chạy tuần tự ở worker của sidecar, không phụ thuộc số này.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.RequestsPerMinute">
            <summary>
            Trần lượt gọi nguồn mỗi phút, tự giới hạn phía mình: Cloud ghi 300/phút/khoá cộng một lớp chắn
            theo IP không công bố ngưỡng → lấy 80 %. Vượt thì lượt gọi xếp hàng tối đa
            <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.MaxQueueWaitSeconds"/> rồi báo <c>RateLimited</c> (không gọi ra ngoài).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.MaxQueueWaitSeconds">
            <summary>Chờ hàng đợi nhịp gọi tối đa chừng này giây.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.VieNeu">
            <summary>Cấu hình VieNeu Cloud.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsOptions.SelfHost">
            <summary>Cấu hình sidecar tự host.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuOptions">
            <summary>Cấu hình VieNeu Cloud API (<c>https://docs.vieneu.io</c>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuOptions.ApiKey">
            <summary>Khoá API <c>vn_sk_…</c> (gói trả phí) hoặc <c>vn_test_…</c> (thử 7 ngày).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuOptions.BaseUrl">
            <summary>Gốc API.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuOptions.Engine">
            <summary><c>v3</c> (×1,5 token/ký tự) hoặc <c>v4</c> (×3). Chọn ở Việc 0 GĐ D2.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuOptions.Voice">
            <summary>Id giọng theo <c>GET /voices?engine=</c> — id khác nhau giữa v3 và v4.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuOptions.ResponseFormat">
            <summary>
            Định dạng trả về. <c>mp3</c> vì app còn chạy iOS 15/16 — AVPlayer ở đó không mở được Ogg
            Opus (opus nhỏ hơn 2,5 lần nhưng không phát được trên một phần máy lái xe).
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuOptions.TimeoutSeconds">
            <summary>Trần thời gian một lần tổng hợp (plan §3.5.10: timeout 10 s).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.SelfHostTtsOptions">
            <summary>
            Cấu hình sidecar VieNeu-TTS tự host trên ladamap (<c>Scripts/tts-vps/sidecar/vieneu_gateway.py</c>,
            cài bằng <c>05-cai-sidecar.sh</c>). Sidecar giữ cache, tách/ghép câu, chuyển mp3 và xếp hàng sinh nền;
            engine phía này chỉ là client mỏng.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.SelfHostTtsOptions.BaseUrl">
            <summary>Gốc URL sidecar = <c>SIDECAR_BIND</c> trong <c>/opt/vieneu/sidecar.env</c>, ví dụ <c>http://192.168.1.50:8011</c>. Trống = chưa cấu hình.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.SelfHostTtsOptions.ApiKey">
            <summary>Khoá Bearer của sidecar (<c>SIDECAR_API_KEY</c>). Production: biến môi trường <c>Tts__SelfHost__ApiKey</c>.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.SelfHostTtsOptions.Voice">
            <summary>
            Giọng sidecar đang dùng (<c>VOICE</c> của nó) — ở đây chỉ để dựng khoá cache và <c>VoiceKey</c>; sidecar tự
            chọn giọng khi gọi TTS. Đổi giọng ở sidecar thì đổi cả đây để cache cũ hai phía bị bỏ. Chốt 2026-09-28
            (chủ dự án nghe thử trên bản tự host): một giọng duy nhất <c>Trúc Ly</c> — bản v3 Turbo mở không có
            "Ban Mai" của Cloud v4.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.SelfHostTtsOptions.ModelVersion">
            <summary>Tag repo VieNeu-TTS đang ghim ở sidecar (<c>MODEL_VERSION</c>) — thành phần khoá cache.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.SelfHostTtsOptions.TimeoutSeconds">
            <summary>Trần thời gian một lần gọi sidecar. Nó trả ngay (cache/pending); ghép ffmpeg vài trăm ms.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.ITtsStatusService">
            <summary>
            Ảnh chụp trạng thái gateway giọng đọc cho người vận hành (<c>GET api/Tts/Status</c>) — xem
            <see cref="T:Ladaer.BackEnd.Infrastructures.DTO.Models.DriverApp.TtsStatusResult"/>. Mọi bước đều bắt lỗi và ghi vào kết quả, không ném ra ngoài.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.ITtsStatusService.GetAsync(System.Int32,System.Threading.CancellationToken)">
            <param name="userId">Người gọi — lượt tổng hợp thử tính vào trần ký tự của người này (50 ký tự).</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsStatusService">
            <inheritdoc cref="T:Ladaer.BackEnd.Infrastructures.Services.Tts.ITtsStatusService"/>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsStatusService.ProbeText">
            <summary>Câu thử: đoạn cố định sidecar sinh sẵn và Cloud tổng hợp được ngay — bình thường phải Ready.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsStatusService.GetAsync(System.Int32,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsStatusService.CheckCacheDir(System.String)">
            <summary>Tạo thư mục, ghi rồi xoá một file thử; đếm file mp3 hiện có (trần 100.000 để không quét quá lâu).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsStatusService.Pick(System.Collections.Generic.IReadOnlyDictionary{System.String,System.String},System.String,System.String)">
            <summary>AppConfig không trống thì đè appsettings — cùng luật với provider.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsStatusService.Mask(System.String)">
            <summary>Che khoá bí mật: chỉ còn độ dài và 4 ký tự đầu — đủ để nhận ra dán nhầm (ngoặc kép → dài 66).</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.ITtsEngine">
            <summary>
            Một nguồn tổng hợp giọng. Hai cài đặt: <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuCloudEngine"/> (api.vieneu.io) và
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuSelfHostEngine"/> (sidecar tự host trên ladamap, đợt 2026-09-28 — memory
            <c>project-tts-tu-host</c>); chọn bằng <c>Tts:Engine</c> ở DependencyRegister để chuyển qua lại trong
            giai đoạn thử. Cache, trần ký tự, nhịp gọi nằm ở <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsCacheService"/>, dùng chung.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.ITtsEngine.IsConfigured">
            <summary>Đã có khoá API. <c>false</c> thì gateway trả "chưa cấu hình" mà không gọi ra ngoài.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.ITtsEngine.CacheKey">
            <summary>
            Phần khoá cache phụ thuộc nguồn: mọi thứ làm đổi âm thanh ra (nhà cung cấp, engine, giọng,
            định dạng). Đổi giọng trong cấu hình là mọi câu có khoá mới — cache cũ tự bị bỏ qua.
            </summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.ITtsEngine.FileExtension">
            <summary>Đuôi file âm thanh lưu cache, không có dấu chấm.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.ITtsEngine.SynthesizeAsync(System.String,System.Threading.CancellationToken)">
            <summary>Tổng hợp một câu. Không ném lỗi — mọi thất bại trả về trong kết quả.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsFailure">
            <summary>Vì sao một lần tổng hợp thất bại.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsFailure.Rejected">
            <summary>Nguồn từ chối CÂU này (400: câu không hợp lệ, giọng không tồn tại…).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsFailure.Unauthorized">
            <summary>Khoá sai/bị thu hồi (401) — lỗi cấu hình server.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsFailure.QuotaExhausted">
            <summary>Hết token, gói hết hạn, hoặc gói không được dùng engine này (403).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsFailure.RateLimited">
            <summary>Vượt giới hạn tần suất hoặc hạn mức ngày/tuần (429).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsFailure.Unavailable">
            <summary>Nguồn không phục vụ được (5xx, lỗi mạng, trả rỗng).</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsFailure.Timeout">
            <summary>Quá thời gian chờ.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsFailure.Pending">
            <summary>
            Nguồn tự host chưa có câu này và đã xếp hàng sinh nền (sidecar trả 202; RTF ≈ 2 nên không chờ).
            KHÔNG phải lỗi: gateway trả <c>Ready=false, ErrorCode=Pending</c> cho riêng câu, lượt gọi vẫn
            Success, không tạm ngắt nguồn, hoàn trần ký tự. App bỏ câu im lặng và tự hỏi lại lượt sau.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsSynthesis">
            <summary>Kết quả một lần tổng hợp.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsSynthesis.Audio">
            <summary>Bytes âm thanh khi thành công.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsSynthesis.Failure">
            <summary>Lý do thất bại; <c>null</c> khi thành công.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsSynthesis.Message">
            <summary>Mô tả ngắn để ghi log — không chứa khoá.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsSynthesis.RetryAfter">
            <summary>Nguồn yêu cầu chờ bao lâu rồi mới thử lại (429), nếu có.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsSynthesis.Ok">
            <summary>Thành công.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsSynthesis.Success(System.Byte[])">
            <summary>Tạo kết quả thành công.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.TtsSynthesis.Fail(Ladaer.BackEnd.Infrastructures.Services.Tts.TtsFailure,System.String,System.Nullable{System.TimeSpan})">
            <summary>Tạo kết quả thất bại.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuCloudEngine">
            <summary>
            Gọi <c>POST /audio/speech</c> của VieNeu Cloud (OpenAI-compatible, trả thẳng bytes âm thanh).
            </summary>
            <remarks>
            Đo thật 2026-09-23 (Việc 0 GĐ D2, plan §5.4): tính tiền đúng <c>max(50, số ký tự) × hệ số
            engine × 1,3</c>; <c>aiRefine</c> mặc định TẮT ở API công khai (câu đọc nguyên văn, không chuẩn
            hoá phát âm, không phụ phí) — nên câu phải chuẩn hoá sẵn ở app (plan §3.5.5). Route này trả
            lỗi theo phong bì OpenAI (<c>{error:{message,type,code}}</c>), KHÔNG mang mã
            <c>GRANT_TOKENS_EXHAUSTED</c> như các route <c>/v1/tts</c> — nên dựa vào mã HTTP, cộng giờ
            đặt lại trong câu lỗi 429 của hạn mức ngày/tuần (khoá thử: 50.000 token/ngày, đặt lại 00:00
            giờ VN — cắn thật ở Việc 0 D2, xem <see cref="M:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuCloudEngine.ParseResetAt(System.String)"/>).
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuCloudEngine.HttpClientName">
            <summary>Tên HttpClient đăng ký ở DependencyRegister.</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuCloudEngine.IsConfigured">
            <inheritdoc />
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuCloudEngine.CacheKey">
            <inheritdoc />
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuCloudEngine.FileExtension">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuCloudEngine.SynthesizeAsync(System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuCloudEngine.MapStatus(System.Net.HttpStatusCode)">
            <summary>Mã HTTP → loại thất bại (hợp đồng lỗi của <c>/audio/speech</c>, docs.vieneu.io).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuCloudEngine.ParseResetAt(System.String)">
            <summary>
            Giờ đặt lại hạn mức trong câu lỗi 429 của VieNeu, <c>null</c> khi không có. Nguyên văn đo
            được: <c>"Daily token limit reached (50,000 tokens/day). Resets at 2026-09-23T17:00:00.000Z."</c>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuCloudEngine.ReadErrorAsync(System.Net.Http.HttpResponseMessage,System.Threading.CancellationToken)">
            <summary>Đọc <c>error.message</c> (+ <c>code</c>) của phong bì OpenAI, cắt ngắn để ghi log.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuSelfHostEngine">
            <summary>
            Gọi sidecar VieNeu-TTS tự host trên ladamap (<c>Scripts/tts-vps/sidecar/vieneu_gateway.py</c>):
            <c>POST {BaseUrl}/v1/clip {text}</c> → 200 <c>audio/mpeg</c> (đã có trong cache sidecar, hoặc ghép
            từ các đoạn sẵn có trong vài trăm ms) hoặc 202 <c>pending</c> (đã xếp hàng sinh nền — TTS trên
            ladamap có RTF ≈ 2 nên KHÔNG chờ; app bỏ câu im lặng và tự hỏi lại lượt sau).
            </summary>
            <remarks>
            Khác <see cref="T:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuCloudEngine"/>: không có hạn mức token, không có "Resets at"; 429 chỉ khi
            hàng đợi sidecar đầy (kèm Retry-After). Tách câu theo mẫu Valhalla, ghép bằng ffmpeg, chuyển mp3
            đều ở sidecar. Đổi giọng/phiên bản ở sidecar thì đổi <c>Tts:SelfHost:Voice</c>/<c>ModelVersion</c>
            để <see cref="P:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuSelfHostEngine.CacheKey"/> đổi theo và app bỏ chỉ mục cũ. Memory <c>project-tts-tu-host</c>.
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuSelfHostEngine.HttpClientName">
            <summary>Tên HttpClient đăng ký ở DependencyRegister.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuSelfHostEngine.#ctor(System.Net.Http.IHttpClientFactory,Ladaer.BackEnd.Infrastructures.Services.Tts.SelfHostTtsOptions,Microsoft.Extensions.Logging.ILogger{Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuSelfHostEngine})">
            <summary>Dựng với cấu hình đã hợp nhất AppConfig + appsettings (<see cref="T:Ladaer.BackEnd.Infrastructures.Services.Tts.AppConfigTtsEngineProvider"/>).</summary>
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuSelfHostEngine.IsConfigured">
            <inheritdoc />
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuSelfHostEngine.CacheKey">
            <inheritdoc />
        </member>
        <member name="P:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuSelfHostEngine.FileExtension">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuSelfHostEngine.SynthesizeAsync(System.String,System.Threading.CancellationToken)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuSelfHostEngine.MapStatus(System.Net.HttpStatusCode)">
            <summary>Mã HTTP của sidecar → loại thất bại (hợp đồng trong <c>vieneu_gateway.py</c>, route <c>/v1/clip</c>).</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Services.Tts.VieNeuSelfHostEngine.ReadErrorAsync(System.Net.Http.HttpResponseMessage,System.Threading.CancellationToken)">
            <summary>Đọc <c>{"error": "…"}</c> của sidecar, cắt ngắn để ghi log; không phải JSON thì ghi thô.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Startup.DependencyRegister">
            <summary>
            Lớp tĩnh để đăng ký các phụ thuộc cho ứng dụng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.DependencyRegister.RegisterDependency(Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.Configuration.IConfiguration)">
            <summary>
            Đăng ký các phụ thuộc cho ứng dụng.
            </summary>
            <param name="services">Bộ sưu tập dịch vụ.</param>
            <param name="Configuration">Cấu hình ứng dụng.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Startup.GeneralRegister">
            <summary>
            Lớp mở rộng để đăng ký các dịch vụ và cấu hình ứng dụng.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.GeneralRegister.RegisterGeneralServices(Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.Configuration.IConfiguration)">
            <summary>
            Đăng ký các dịch vụ chung.
            </summary>
            <param name="services">Đối tượng IServiceCollection.</param>
            <param name="Configuration">Đối tượng IConfiguration.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.GeneralRegister.ConfigAndRunApp(Microsoft.AspNetCore.Builder.WebApplication)">
            <summary>
            Cấu hình và chạy ứng dụng.
            </summary>
            <param name="app">Đối tượng WebApplication.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Startup.GlobalExceptionResponse">
            <summary>
            Thân phản hồi của handler lỗi toàn cục ngoài Development — <c>ProblemDetails</c> (RFC 7807)
            <b>không chứa stack trace, không chứa thông điệp của exception</b>, chỉ có mã lỗi và mã tra cứu.
            </summary>
            <remarks>
            <para>
            <b>Vì sao tách khỏi <see cref="M:Ladaer.BackEnd.Infrastructures.Startup.GeneralRegister.ConfigAndRunApp(Microsoft.AspNetCore.Builder.WebApplication)"/>:</b> đoạn này là thứ duy nhất
            người ngoài Internet nhìn thấy khi máy chủ hỏng, nên nó phải có ca test của chính nó. Nằm trong
            lambda của <c>UseExceptionHandler</c> thì không có cách nào gọi tới mà không dựng cả pipeline.
            </para>
            <para>
            <b>Vì sao không trả cả <c>Message</c> của exception</b> (sổ nợ CS-25): thông điệp lỗi .NET
            thường xuyên mang đường dẫn ổ đĩa (<c>FileNotFoundException</c>), tên máy chủ và tên database
            (<c>SqlException</c>), tên assembly và tên kiểu (<c>AutoMapper</c>, <c>JsonException</c>). Bản cũ
            trả nguyên <c>StackTrace</c> của cả chuỗi <c>InnerException</c> ra body — chấp nhận được khi API
            chỉ nằm sau tường lửa, nhưng đợt này mở <c>/connect/register</c> (DCR) ra Internet, và đường đó
            <b>không cần đăng nhập</b>: một request méo là một bản đồ máy chủ.
            </para>
            <para>
            Chi tiết không mất đi — nó vào <b>nhật ký</b> kèm đúng <c>RequestId</c> in ra cho người gọi, nên
            tra ngược được. Với lời gọi <c>/mcp</c>, <c>RequestId</c> chính là request-id mà
            <c>McpGateMiddleware</c> đã gán vào <c>TraceIdentifier</c> và đã trả ở header <c>X-Request-Id</c>.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Startup.GlobalExceptionResponse.ErrorCode">
            <summary>Mã lỗi ổn định cho client — cùng họ với mã lỗi của lớp MCP.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Startup.GlobalExceptionResponse.ContentType">
            <summary>Kiểu nội dung theo RFC 7807.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Startup.GlobalExceptionResponse.Detail">
            <summary>Câu duy nhất người gọi nhận được. Cố ý không nói gì về nguyên nhân.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Startup.GlobalExceptionResponse.RequestIdHeader">
            <summary>Header trả mã tra cứu để người gọi đọc được mà không cần đọc body.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.GlobalExceptionResponse.WriteAsync(Microsoft.AspNetCore.Http.HttpContext,System.Exception,Microsoft.Extensions.Logging.ILogger)">
            <summary>
            Ghi nhật ký đầy đủ rồi trả body an toàn. Không ném — handler lỗi mà ném thì client nhận
            kết nối đứt, còn khó hiểu hơn lỗi gốc.
            </summary>
            <param name="context">Ngữ cảnh request đang hỏng.</param>
            <param name="error">Exception gốc; <c>null</c> khi pipeline không kèm được (vẫn trả 500).</param>
            <param name="logger">Nơi chi tiết thật sự đi tới.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.GlobalExceptionResponse.WriteAsync(Microsoft.AspNetCore.Http.HttpContext,Microsoft.Extensions.Logging.ILogger)">
            <summary>Bản dùng trong pipeline: lấy exception từ <see cref="T:Microsoft.AspNetCore.Diagnostics.IExceptionHandlerFeature"/>.</summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Startup.RateLimitingRegister">
            <summary>
            Đăng ký Rate Limiting để chống spam/brute-force cho các endpoint công khai và chặn client chạy loạn.
            Sử dụng built-in Rate Limiting của .NET (System.Threading.RateLimiting). Ngưỡng đọc từ mục
            <c>RateLimiting</c> của appsettings (<see cref="T:Ladaer.BackEnd.Infrastructures.AppSettings.RateLimitingSettings"/>).
            </summary>
            <remarks>
            <para>
            <b>Giới hạn toàn cục tính theo user khi đã đăng nhập, theo IP khi chưa</b> (<see cref="T:Ladaer.BackEnd.Infrastructures.Networking.RateLimitPartitionKey"/>,
            2026-10-16). Bản cũ tính 100 request/phút/IP cho mọi request, mà cả văn phòng ra Internet bằng một IP NAT nên
            vài chục nhân viên chia nhau một hạn mức và liên tục nhận 429 như bị khoá. Muốn biết user thì middleware này
            phải chạy <b>sau</b> <c>UseAuthentication</c> — thứ tự ở <c>GeneralRegister.ConfigAndRunApp</c>; đặt trước là
            mọi request lại rơi về IP.
            </para>
            <para>
            <b>Khoá IP luôn lấy từ <see cref="M:Ladaer.BackEnd.Infrastructures.Networking.ClientIpResolver.ResolveKey(Microsoft.AspNetCore.Http.HttpContext)"/></b> — không có hàm đọc IP riêng
            ở file này (sổ nợ CS-23, đóng 2026-09-07). Bản cũ tự đọc <c>X-Forwarded-For</c> và lấy phần tử
            <b>đầu</b>, tức là sau reverse proxy thì ai cũng tự khai header để nhảy sang phân vùng khác và bơm
            request không giới hạn — trong khi whitelist IP của MCP lấy phần tử cuối. Hai luật cho cùng một câu
            hỏi thì sớm muộn cũng lệch; nay chỉ còn một.
            </para>
            </remarks>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Startup.RateLimitingRegister.AnonymousPolicy">
            <summary>
            Tên policy cho các endpoint anonymous (báo lỗi, đăng ký client MCP, callback OAuth kênh chat).
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Startup.RateLimitingRegister.LoginPolicy">
            <summary>
            Tên policy cho các endpoint nhạy cảm (Login - chống brute-force)
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Startup.RateLimitingRegister.SocialChatWebhookPolicy">
            <summary>
            Tên policy cho webhook chat đa nền tảng (Zalo OA, Facebook Messenger)
            </summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Startup.RateLimitingRegister.GlobalUserPolicyLabel">
            <summary>Tên ghi vào log/header khi request bị giới hạn toàn cục theo user.</summary>
        </member>
        <member name="F:Ladaer.BackEnd.Infrastructures.Startup.RateLimitingRegister.GlobalIpPolicyLabel">
            <summary>Tên ghi vào log/header khi request bị giới hạn toàn cục theo IP.</summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.RateLimitingRegister.RegisterRateLimiting(Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.Configuration.IConfiguration)">
            <summary>
            Đăng ký Rate Limiting services.
            </summary>
            <param name="services">DI container.</param>
            <param name="configuration">Cấu hình ứng dụng — đọc mục <c>RateLimiting</c>, thiếu thì dùng mặc định.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.RateLimitingRegister.ResolvePolicyName(Microsoft.AspNetCore.Http.HttpContext,Ladaer.BackEnd.Infrastructures.Networking.RateLimitPartitionKey.Partition)">
            <summary>
            Tên policy để ghi log và trả header <c>X-RateLimit-Policy</c>: lấy từ metadata
            <see cref="T:Microsoft.AspNetCore.RateLimiting.EnableRateLimitingAttribute"/> của endpoint đã khớp route; endpoint không gắn policy riêng thì
            là giới hạn toàn cục — theo user hay theo IP tuỳ phân vùng.
            </summary>
            <remarks>
            Bản cũ đoán policy bằng cách so chuỗi path (<c>Contains("Login")</c>…) nên endpoint mới gắn policy
            mà không cập nhật danh sách đó thì log ghi sai. Đọc metadata thì không phải nhớ.
            </remarks>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.RateLimitingRegister.FixedWindowPerIp(Microsoft.AspNetCore.Http.HttpContext,System.Int32)">
            <summary>
            Phân vùng cửa sổ cố định 1 phút theo IP (<see cref="M:Ladaer.BackEnd.Infrastructures.Networking.ClientIpResolver.ResolveKey(Microsoft.AspNetCore.Http.HttpContext)"/>); preflight OPTIONS không tính.
            </summary>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Startup.SecurityRegister">
            <summary>
            Lớp mở rộng để đăng ký các dịch vụ bảo mật.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.SecurityRegister.RegisterSecurityServices(Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.Configuration.IConfiguration)">
            <summary>
            Đăng ký các dịch vụ bảo mật.
            </summary>
            <param name="services">Đối tượng IServiceCollection.</param>
            <param name="configuration">Đối tượng IConfiguration.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.SecurityRegister.RegisterSecurity(Microsoft.AspNetCore.Builder.IApplicationBuilder)">
            <summary>
            Đăng ký các middleware bảo mật.
            </summary>
            <param name="app">Đối tượng IApplicationBuilder.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Startup.StartupHostedService">
            <summary>
            Dịch vụ khởi động được lưu trữ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.StartupHostedService.#ctor(System.IServiceProvider,Microsoft.Extensions.Logging.ILogger{Ladaer.BackEnd.Infrastructures.Startup.StartupHostedService})">
            <summary>
            Khởi tạo một thể hiện của <see cref="T:Ladaer.BackEnd.Infrastructures.Startup.StartupHostedService"/>.
            </summary>
            <param name="serviceProvider">Đối tượng IServiceProvider.</param>
            <param name="logger">Bộ ghi nhật ký.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.StartupHostedService.StartAsync(System.Threading.CancellationToken)">
            <summary>
            Phương thức được gọi khi dịch vụ khởi động.
            </summary>
            <param name="cancellationToken">Đối tượng CancellationToken.</param>
            <returns>Nhiệm vụ không đồng bộ.</returns>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.StartupHostedService.ProtectAiProviderKeysAsync(System.IServiceProvider,Lada.Framework.Data.Mappings.DbContexts.LadaDbContext,System.Threading.CancellationToken)">
            <summary>
            Mã hoá các API key nhà cung cấp AI còn ở dạng bản rõ (cổng nhượng quyền GĐ G, CNQ-1) — xem
            <see cref="T:Ladaer.BackEnd.Infrastructures.Services.AI.AiProviderKeyProtection"/>. Không bao giờ chặn khởi động: lỗi thì ghi cảnh báo rồi đi tiếp,
            key vẫn đọc được ở dạng cũ.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.StartupHostedService.LogSchemaVersionAsync(Lada.Framework.Data.Mappings.DbContexts.LadaDbContext,System.Threading.CancellationToken)">
            <summary>
            In phiên bản schema (migration mới nhất đã áp dụng) ra nhật ký lúc khởi động.
            <para>
            Lý do tồn tại: quy trình vận hành cấm can thiệp database production trực tiếp, mà
            <c>Lada.Migrations -- list</c> — đường duy nhất còn lại để biết production đang ở đâu —
            vẫn đòi chuỗi kết nối. Một dòng nhật ký lúc khởi động trả lời đúng câu hỏi ấy vào đúng
            lúc cần nhất (ngay sau deploy) mà không mở thêm bề mặt công khai nào.
            </para>
            <para>
            CHỈ ĐỌC, và cố ý <b>không bao giờ chặn khởi động</b>: bảng <c>VersionInfo</c> do
            FluentMigrator sở hữu và ứng dụng không tham chiếu project migration, nên nó có thể
            chưa tồn tại trên một database mới tinh. Hỏng thì ghi cảnh báo rồi đi tiếp.
            </para>
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.StartupHostedService.StopAsync(System.Threading.CancellationToken)">
            <summary>
            Phương thức được gọi khi dịch vụ dừng.
            </summary>
            <param name="cancellationToken">Đối tượng CancellationToken.</param>
            <returns>Nhiệm vụ hoàn thành.</returns>
        </member>
        <member name="T:Ladaer.BackEnd.Infrastructures.Startup.SwaggerRegister">
            <summary>
            Lớp mở rộng để đăng ký các dịch vụ và middleware của Swagger.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.SwaggerRegister.RegisterSwaggerServices(Microsoft.Extensions.DependencyInjection.IServiceCollection)">
            <summary>
            Đăng ký các dịch vụ của Swagger.
            </summary>
            <param name="services">Đối tượng IServiceCollection.</param>
        </member>
        <member name="M:Ladaer.BackEnd.Infrastructures.Startup.SwaggerRegister.RegisterSwagger(Microsoft.AspNetCore.Builder.IApplicationBuilder)">
            <summary>
            Đăng ký các middleware của Swagger.
            </summary>
            <param name="app">Đối tượng IApplicationBuilder.</param>
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddGrossSalesCommissionIncome">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddGrossSalesCommissionIncome.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddGrossSalesCommissionIncome.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddGrossSalesCommissionIncome.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddAddressLevelType">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAddressLevelType.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAddressLevelType.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAddressLevelType.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddLevelTypeToEndPoints">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddLevelTypeToEndPoints.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddLevelTypeToEndPoints.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddLevelTypeToEndPoints.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddLoanSettlement">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddLoanSettlement.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddLoanSettlement.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddLoanSettlement.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.StandaloneLesson_NullableSectionId_CourseId_GlobalOrder">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.StandaloneLesson_NullableSectionId_CourseId_GlobalOrder.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.StandaloneLesson_NullableSectionId_CourseId_GlobalOrder.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.StandaloneLesson_NullableSectionId_CourseId_GlobalOrder.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.Section_AddGlobalOrder">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.Section_AddGlobalOrder.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.Section_AddGlobalOrder.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.Section_AddGlobalOrder.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddSurchargeToLocation">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddSurchargeToLocation.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddSurchargeToLocation.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddSurchargeToLocation.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddCustomerCoManager">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddCustomerCoManager.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddCustomerCoManager.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddCustomerCoManager.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddBankAccountCurrentBalance">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddBankAccountCurrentBalance.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddBankAccountCurrentBalance.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddBankAccountCurrentBalance.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddPitFields">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddPitFields.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddPitFields.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddPitFields.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddAgencyIdToOrderTrack">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAgencyIdToOrderTrack.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAgencyIdToOrderTrack.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAgencyIdToOrderTrack.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddDefaultScorePercentToSalaryConfig">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddDefaultScorePercentToSalaryConfig.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddDefaultScorePercentToSalaryConfig.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddDefaultScorePercentToSalaryConfig.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.ChangeTotalOvertimeKipsToDecimal">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.ChangeTotalOvertimeKipsToDecimal.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.ChangeTotalOvertimeKipsToDecimal.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddSalaryAdvanceAndDeposit">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddSalaryAdvanceAndDeposit.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddSalaryAdvanceAndDeposit.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddSalaryAdvanceAndDeposit.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddOgImageToPostProductJobPost">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddOgImageToPostProductJobPost.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddOgImageToPostProductJobPost.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddOgImageToPostProductJobPost.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddLeaveManagement">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddLeaveManagement.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddLeaveManagement.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddLeaveManagement.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddUserTrack">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddUserTrack.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddUserTrack.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddUserTrack.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddTrainingCoursePermission">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddTrainingCoursePermission.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddTrainingCoursePermission.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddTrainingCoursePermission.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddSalaryOtherDeduction">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddSalaryOtherDeduction.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddSalaryOtherDeduction.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddSalaryOtherDeduction.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.RefactorSalaryOtherDeductionToPayroll">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.RefactorSalaryOtherDeductionToPayroll.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.RefactorSalaryOtherDeductionToPayroll.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.RefactorSalaryOtherDeductionToPayroll.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddKipPriceToSalaryConfig">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddKipPriceToSalaryConfig.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddKipPriceToSalaryConfig.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddKipPriceToSalaryConfig.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddAiMarketing">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiMarketing.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiMarketing.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiMarketing.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddAiProvider">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiProvider.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiProvider.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiProvider.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddAiProviderDescription">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiProviderDescription.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiProviderDescription.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiProviderDescription.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddBrandRegistryTables">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddBrandRegistryTables.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddBrandRegistryTables.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddBrandRegistryTables.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddNotificationSystem">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddNotificationSystem.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddNotificationSystem.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddNotificationSystem.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddCanCollectCodToBankAccount">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddCanCollectCodToBankAccount.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddCanCollectCodToBankAccount.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddCanCollectCodToBankAccount.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddFuelCardQrCode">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddFuelCardQrCode.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddFuelCardQrCode.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddFuelCardQrCode.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddFuelRefillPayrollLock">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddFuelRefillPayrollLock.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddFuelRefillPayrollLock.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddFuelRefillPayrollLock.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddAiPlatformCoreEntities">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiPlatformCoreEntities.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiPlatformCoreEntities.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiPlatformCoreEntities.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddAiKnowledgeDocument">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiKnowledgeDocument.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiKnowledgeDocument.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiKnowledgeDocument.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.RenameAllowedRolesToAllowedPermissions">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.RenameAllowedRolesToAllowedPermissions.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.RenameAllowedRolesToAllowedPermissions.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.RenameAllowedRolesToAllowedPermissions.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddIsDefaultToModelConfig">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddIsDefaultToModelConfig.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddIsDefaultToModelConfig.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddIsDefaultToModelConfig.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.KnowledgeDocMetadataApproval">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.KnowledgeDocMetadataApproval.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.KnowledgeDocMetadataApproval.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.KnowledgeDocMetadataApproval.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddAiGuardrail">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiGuardrail.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiGuardrail.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddAiGuardrail.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddUserAttendanceCode">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddUserAttendanceCode.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddUserAttendanceCode.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddUserAttendanceCode.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddSyncEngine">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddSyncEngine.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddSyncEngine.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddSyncEngine.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddSyncOutboxEnvelopeV1">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddSyncOutboxEnvelopeV1.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddSyncOutboxEnvelopeV1.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddSyncOutboxEnvelopeV1.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.HardenSyncCheckpoint">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.HardenSyncCheckpoint.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.HardenSyncCheckpoint.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.HardenSyncCheckpoint.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddDepositUserIdToExpense">
            <summary>
            Thêm Expense.DepositUserId (phiếu chi hoàn cọc / tạm ứng gắn với lái xe).
            Kèm Income.MediaId: migration 20260724055334_AddMediaIdToIncome bị gỡ khỏi thư mục
            (gitignore, chưa từng apply vào DB dev) nên gộp cột đó vào đây.
            Body được viết tay — scaffold gốc gánh theo diff không liên quan do snapshot lệch DB.
            </summary>
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddDepositUserIdToExpense.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddDepositUserIdToExpense.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddDepositUserIdToExpense.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddGoodsCategoryToOrderPackage">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddGoodsCategoryToOrderPackage.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddGoodsCategoryToOrderPackage.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddGoodsCategoryToOrderPackage.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:Ladaer.BackEnd.Migrations.AddWeightToGoodsAttributeOption">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddWeightToGoodsAttributeOption.Up(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddWeightToGoodsAttributeOption.Down(Microsoft.EntityFrameworkCore.Migrations.MigrationBuilder)">
            <inheritdoc />
        </member>
        <member name="M:Ladaer.BackEnd.Migrations.AddWeightToGoodsAttributeOption.BuildTargetModel(Microsoft.EntityFrameworkCore.ModelBuilder)">
            <inheritdoc />
        </member>
        <member name="T:MediaServiceConfigurationExample">
            <summary>
            Example appsettings.json configuration
            </summary>
        </member>
        <member name="M:SvgCaptchaSolver.SolveCaptcha(System.String,System.Int32)">
            <summary>
            Giải captcha từ file SVG
            </summary>
        </member>
        <member name="M:SvgCaptchaSolver.SolveCaptchaFromContent(System.String,System.Int32)">
            <summary>
            Giải captcha từ nội dung SVG string (dùng khi nhận SVG từ API response)
            </summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.PhonePattern_0">
            <summary>Custom <see cref="T:System.Text.RegularExpressions.Regex"/>-derived type for the PhonePattern method.</summary>
        </member>
        <member name="F:System.Text.RegularExpressions.Generated.PhonePattern_0.Instance">
            <summary>Cached, thread-safe singleton instance.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.PhonePattern_0.#ctor">
            <summary>Initializes the instance.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.PhonePattern_0.RunnerFactory">
            <summary>Provides a factory for creating <see cref="T:System.Text.RegularExpressions.RegexRunner"/> instances to be used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.PhonePattern_0.RunnerFactory.CreateInstance">
            <summary>Creates an instance of a <see cref="T:System.Text.RegularExpressions.RegexRunner"/> used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.PhonePattern_0.RunnerFactory.Runner">
            <summary>Provides the runner that contains the custom logic implementing the specified regular expression.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.PhonePattern_0.RunnerFactory.Runner.Scan(System.ReadOnlySpan{System.Char})">
            <summary>Scan the <paramref name="inputSpan"/> starting from base.runtextstart for the next match.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.PhonePattern_0.RunnerFactory.Runner.TryFindNextPossibleStartingPosition(System.ReadOnlySpan{System.Char})">
            <summary>Search <paramref name="inputSpan"/> starting from base.runtextpos for the next location a match could possibly start.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if a possible match was found; false if no more matches are possible.</returns>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.PhonePattern_0.RunnerFactory.Runner.TryMatchAtCurrentPosition(System.ReadOnlySpan{System.Char})">
            <summary>Determine whether <paramref name="inputSpan"/> at base.runtextpos is a match for the regular expression.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if the regular expression matches at the current position; otherwise, false.</returns>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.ScriptOrStyle_1">
            <summary>Caches a <see cref="T:System.Text.RegularExpressions.Regex"/> instance for the ScriptOrStyle method.</summary>
            <remarks>A custom Regex-derived type could not be generated because the expression contains case-insensitive backreferences which are not supported by the source generator.</remarks>
        </member>
        <member name="F:System.Text.RegularExpressions.Generated.ScriptOrStyle_1.Instance">
            <summary>Cached, thread-safe singleton instance.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.BlockBreak_2">
            <summary>Custom <see cref="T:System.Text.RegularExpressions.Regex"/>-derived type for the BlockBreak method.</summary>
        </member>
        <member name="F:System.Text.RegularExpressions.Generated.BlockBreak_2.Instance">
            <summary>Cached, thread-safe singleton instance.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.BlockBreak_2.#ctor">
            <summary>Initializes the instance.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.BlockBreak_2.RunnerFactory">
            <summary>Provides a factory for creating <see cref="T:System.Text.RegularExpressions.RegexRunner"/> instances to be used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.BlockBreak_2.RunnerFactory.CreateInstance">
            <summary>Creates an instance of a <see cref="T:System.Text.RegularExpressions.RegexRunner"/> used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.BlockBreak_2.RunnerFactory.Runner">
            <summary>Provides the runner that contains the custom logic implementing the specified regular expression.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.BlockBreak_2.RunnerFactory.Runner.Scan(System.ReadOnlySpan{System.Char})">
            <summary>Scan the <paramref name="inputSpan"/> starting from base.runtextstart for the next match.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.BlockBreak_2.RunnerFactory.Runner.TryFindNextPossibleStartingPosition(System.ReadOnlySpan{System.Char})">
            <summary>Search <paramref name="inputSpan"/> starting from base.runtextpos for the next location a match could possibly start.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if a possible match was found; false if no more matches are possible.</returns>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.BlockBreak_2.RunnerFactory.Runner.TryMatchAtCurrentPosition(System.ReadOnlySpan{System.Char})">
            <summary>Determine whether <paramref name="inputSpan"/> at base.runtextpos is a match for the regular expression.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if the regular expression matches at the current position; otherwise, false.</returns>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.AnyTag_3">
            <summary>Custom <see cref="T:System.Text.RegularExpressions.Regex"/>-derived type for the AnyTag method.</summary>
        </member>
        <member name="F:System.Text.RegularExpressions.Generated.AnyTag_3.Instance">
            <summary>Cached, thread-safe singleton instance.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.AnyTag_3.#ctor">
            <summary>Initializes the instance.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.AnyTag_3.RunnerFactory">
            <summary>Provides a factory for creating <see cref="T:System.Text.RegularExpressions.RegexRunner"/> instances to be used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.AnyTag_3.RunnerFactory.CreateInstance">
            <summary>Creates an instance of a <see cref="T:System.Text.RegularExpressions.RegexRunner"/> used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.AnyTag_3.RunnerFactory.Runner">
            <summary>Provides the runner that contains the custom logic implementing the specified regular expression.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.AnyTag_3.RunnerFactory.Runner.Scan(System.ReadOnlySpan{System.Char})">
            <summary>Scan the <paramref name="inputSpan"/> starting from base.runtextstart for the next match.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.AnyTag_3.RunnerFactory.Runner.TryFindNextPossibleStartingPosition(System.ReadOnlySpan{System.Char})">
            <summary>Search <paramref name="inputSpan"/> starting from base.runtextpos for the next location a match could possibly start.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if a possible match was found; false if no more matches are possible.</returns>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.AnyTag_3.RunnerFactory.Runner.TryMatchAtCurrentPosition(System.ReadOnlySpan{System.Char})">
            <summary>Determine whether <paramref name="inputSpan"/> at base.runtextpos is a match for the regular expression.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if the regular expression matches at the current position; otherwise, false.</returns>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.NonAlphaNum_4">
            <summary>Custom <see cref="T:System.Text.RegularExpressions.Regex"/>-derived type for the NonAlphaNum method.</summary>
        </member>
        <member name="F:System.Text.RegularExpressions.Generated.NonAlphaNum_4.Instance">
            <summary>Cached, thread-safe singleton instance.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.NonAlphaNum_4.#ctor">
            <summary>Initializes the instance.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.NonAlphaNum_4.RunnerFactory">
            <summary>Provides a factory for creating <see cref="T:System.Text.RegularExpressions.RegexRunner"/> instances to be used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.NonAlphaNum_4.RunnerFactory.CreateInstance">
            <summary>Creates an instance of a <see cref="T:System.Text.RegularExpressions.RegexRunner"/> used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.NonAlphaNum_4.RunnerFactory.Runner">
            <summary>Provides the runner that contains the custom logic implementing the specified regular expression.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.NonAlphaNum_4.RunnerFactory.Runner.Scan(System.ReadOnlySpan{System.Char})">
            <summary>Scan the <paramref name="inputSpan"/> starting from base.runtextstart for the next match.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.NonAlphaNum_4.RunnerFactory.Runner.TryFindNextPossibleStartingPosition(System.ReadOnlySpan{System.Char})">
            <summary>Search <paramref name="inputSpan"/> starting from base.runtextpos for the next location a match could possibly start.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if a possible match was found; false if no more matches are possible.</returns>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.NonAlphaNum_4.RunnerFactory.Runner.TryMatchAtCurrentPosition(System.ReadOnlySpan{System.Char})">
            <summary>Determine whether <paramref name="inputSpan"/> at base.runtextpos is a match for the regular expression.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if the regular expression matches at the current position; otherwise, false.</returns>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.SlugRegex_5">
            <summary>Custom <see cref="T:System.Text.RegularExpressions.Regex"/>-derived type for the SlugRegex method.</summary>
        </member>
        <member name="F:System.Text.RegularExpressions.Generated.SlugRegex_5.Instance">
            <summary>Cached, thread-safe singleton instance.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.SlugRegex_5.#ctor">
            <summary>Initializes the instance.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.SlugRegex_5.RunnerFactory">
            <summary>Provides a factory for creating <see cref="T:System.Text.RegularExpressions.RegexRunner"/> instances to be used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.SlugRegex_5.RunnerFactory.CreateInstance">
            <summary>Creates an instance of a <see cref="T:System.Text.RegularExpressions.RegexRunner"/> used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.SlugRegex_5.RunnerFactory.Runner">
            <summary>Provides the runner that contains the custom logic implementing the specified regular expression.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.SlugRegex_5.RunnerFactory.Runner.Scan(System.ReadOnlySpan{System.Char})">
            <summary>Scan the <paramref name="inputSpan"/> starting from base.runtextstart for the next match.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.SlugRegex_5.RunnerFactory.Runner.TryFindNextPossibleStartingPosition(System.ReadOnlySpan{System.Char})">
            <summary>Search <paramref name="inputSpan"/> starting from base.runtextpos for the next location a match could possibly start.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if a possible match was found; false if no more matches are possible.</returns>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.SlugRegex_5.RunnerFactory.Runner.TryMatchAtCurrentPosition(System.ReadOnlySpan{System.Char})">
            <summary>Determine whether <paramref name="inputSpan"/> at base.runtextpos is a match for the regular expression.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if the regular expression matches at the current position; otherwise, false.</returns>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.Spaces_6">
            <summary>Custom <see cref="T:System.Text.RegularExpressions.Regex"/>-derived type for the Spaces method.</summary>
        </member>
        <member name="F:System.Text.RegularExpressions.Generated.Spaces_6.Instance">
            <summary>Cached, thread-safe singleton instance.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.Spaces_6.#ctor">
            <summary>Initializes the instance.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.Spaces_6.RunnerFactory">
            <summary>Provides a factory for creating <see cref="T:System.Text.RegularExpressions.RegexRunner"/> instances to be used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.Spaces_6.RunnerFactory.CreateInstance">
            <summary>Creates an instance of a <see cref="T:System.Text.RegularExpressions.RegexRunner"/> used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.Spaces_6.RunnerFactory.Runner">
            <summary>Provides the runner that contains the custom logic implementing the specified regular expression.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.Spaces_6.RunnerFactory.Runner.Scan(System.ReadOnlySpan{System.Char})">
            <summary>Scan the <paramref name="inputSpan"/> starting from base.runtextstart for the next match.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.Spaces_6.RunnerFactory.Runner.TryFindNextPossibleStartingPosition(System.ReadOnlySpan{System.Char})">
            <summary>Search <paramref name="inputSpan"/> starting from base.runtextpos for the next location a match could possibly start.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if a possible match was found; false if no more matches are possible.</returns>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.Spaces_6.RunnerFactory.Runner.TryMatchAtCurrentPosition(System.ReadOnlySpan{System.Char})">
            <summary>Determine whether <paramref name="inputSpan"/> at base.runtextpos is a match for the regular expression.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if the regular expression matches at the current position; otherwise, false.</returns>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.E164Vn_7">
            <summary>Custom <see cref="T:System.Text.RegularExpressions.Regex"/>-derived type for the E164Vn method.</summary>
        </member>
        <member name="F:System.Text.RegularExpressions.Generated.E164Vn_7.Instance">
            <summary>Cached, thread-safe singleton instance.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.E164Vn_7.#ctor">
            <summary>Initializes the instance.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.E164Vn_7.RunnerFactory">
            <summary>Provides a factory for creating <see cref="T:System.Text.RegularExpressions.RegexRunner"/> instances to be used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.E164Vn_7.RunnerFactory.CreateInstance">
            <summary>Creates an instance of a <see cref="T:System.Text.RegularExpressions.RegexRunner"/> used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.E164Vn_7.RunnerFactory.Runner">
            <summary>Provides the runner that contains the custom logic implementing the specified regular expression.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.E164Vn_7.RunnerFactory.Runner.Scan(System.ReadOnlySpan{System.Char})">
            <summary>Scan the <paramref name="inputSpan"/> starting from base.runtextstart for the next match.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.E164Vn_7.RunnerFactory.Runner.TryFindNextPossibleStartingPosition(System.ReadOnlySpan{System.Char})">
            <summary>Search <paramref name="inputSpan"/> starting from base.runtextpos for the next location a match could possibly start.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if a possible match was found; false if no more matches are possible.</returns>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.E164Vn_7.RunnerFactory.Runner.TryMatchAtCurrentPosition(System.ReadOnlySpan{System.Char})">
            <summary>Determine whether <paramref name="inputSpan"/> at base.runtextpos is a match for the regular expression.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if the regular expression matches at the current position; otherwise, false.</returns>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.PhoneNoise_8">
            <summary>Custom <see cref="T:System.Text.RegularExpressions.Regex"/>-derived type for the PhoneNoise method.</summary>
        </member>
        <member name="F:System.Text.RegularExpressions.Generated.PhoneNoise_8.Instance">
            <summary>Cached, thread-safe singleton instance.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.PhoneNoise_8.#ctor">
            <summary>Initializes the instance.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.PhoneNoise_8.RunnerFactory">
            <summary>Provides a factory for creating <see cref="T:System.Text.RegularExpressions.RegexRunner"/> instances to be used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.PhoneNoise_8.RunnerFactory.CreateInstance">
            <summary>Creates an instance of a <see cref="T:System.Text.RegularExpressions.RegexRunner"/> used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.PhoneNoise_8.RunnerFactory.Runner">
            <summary>Provides the runner that contains the custom logic implementing the specified regular expression.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.PhoneNoise_8.RunnerFactory.Runner.Scan(System.ReadOnlySpan{System.Char})">
            <summary>Scan the <paramref name="inputSpan"/> starting from base.runtextstart for the next match.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.PhoneNoise_8.RunnerFactory.Runner.TryFindNextPossibleStartingPosition(System.ReadOnlySpan{System.Char})">
            <summary>Search <paramref name="inputSpan"/> starting from base.runtextpos for the next location a match could possibly start.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if a possible match was found; false if no more matches are possible.</returns>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.EmailPattern_9">
            <summary>Custom <see cref="T:System.Text.RegularExpressions.Regex"/>-derived type for the EmailPattern method.</summary>
        </member>
        <member name="F:System.Text.RegularExpressions.Generated.EmailPattern_9.Instance">
            <summary>Cached, thread-safe singleton instance.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.EmailPattern_9.#ctor">
            <summary>Initializes the instance.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.EmailPattern_9.RunnerFactory">
            <summary>Provides a factory for creating <see cref="T:System.Text.RegularExpressions.RegexRunner"/> instances to be used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.EmailPattern_9.RunnerFactory.CreateInstance">
            <summary>Creates an instance of a <see cref="T:System.Text.RegularExpressions.RegexRunner"/> used by methods on <see cref="T:System.Text.RegularExpressions.Regex"/>.</summary>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.EmailPattern_9.RunnerFactory.Runner">
            <summary>Provides the runner that contains the custom logic implementing the specified regular expression.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.EmailPattern_9.RunnerFactory.Runner.Scan(System.ReadOnlySpan{System.Char})">
            <summary>Scan the <paramref name="inputSpan"/> starting from base.runtextstart for the next match.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.EmailPattern_9.RunnerFactory.Runner.TryFindNextPossibleStartingPosition(System.ReadOnlySpan{System.Char})">
            <summary>Search <paramref name="inputSpan"/> starting from base.runtextpos for the next location a match could possibly start.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if a possible match was found; false if no more matches are possible.</returns>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.EmailPattern_9.RunnerFactory.Runner.TryMatchAtCurrentPosition(System.ReadOnlySpan{System.Char})">
            <summary>Determine whether <paramref name="inputSpan"/> at base.runtextpos is a match for the regular expression.</summary>
            <param name="inputSpan">The text being scanned by the regular expression.</param>
            <returns>true if the regular expression matches at the current position; otherwise, false.</returns>
        </member>
        <member name="T:System.Text.RegularExpressions.Generated.Utilities">
            <summary>Helper methods used by generated <see cref="T:System.Text.RegularExpressions.Regex"/>-derived implementations.</summary>
        </member>
        <member name="F:System.Text.RegularExpressions.Generated.Utilities.s_defaultTimeout">
            <summary>Default timeout value set in <see cref="T:System.AppContext"/>, or <see cref="F:System.Text.RegularExpressions.Regex.InfiniteMatchTimeout"/> if none was set.</summary>
        </member>
        <member name="F:System.Text.RegularExpressions.Generated.Utilities.s_hasTimeout">
            <summary>Whether <see cref="F:System.Text.RegularExpressions.Generated.Utilities.s_defaultTimeout"/> is non-infinite.</summary>
        </member>
        <member name="M:System.Text.RegularExpressions.Generated.Utilities.IndexOfNonAsciiOrAny_094414B33327C614B4460DC7B5A6D948AA36895516B236C0CF4FD32A473A886B(System.ReadOnlySpan{System.Char})">
            <summary>Finds the next index of any character that matches a character in the set [()-.\s].</summary>
        </member>
        <member name="F:System.Text.RegularExpressions.Generated.Utilities.s_ascii_FF0300000000FEFFFF07">
            <summary>Supports searching for characters in or not in "0123456789abcdefghijklmnopqrstuvwxyz".</summary>
        </member>
        <member name="F:System.Text.RegularExpressions.Generated.Utilities.s_ascii_FFC1FFFFFE9CFFFFFFFFFFFFFFFFFFFF">
            <summary>Supports searching for characters in or not in "\0\u0001\u0002\u0003\u0004\u0005\u0006\a\b\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f!\"#$%&amp;'*+,/0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f".</summary>
        </member>
        <member name="F:System.Text.RegularExpressions.Generated.Utilities.s_whitespace">
            <summary>Supports searching for characters in or not in "\t\n\v\f\r \u0085             \u2028\u2029  　".</summary>
        </member>
    </members>
</doc>
