-- 文件职责：补齐 Tenant 端财务中心发票管理权限与菜单权限绑定（可重复执行）。
-- 执行范围：takeout_identity 数据库（Portal=1，Tenant 端）。

BEGIN;

-- 1) 新增/修正发票管理权限码
WITH invoice_permissions(code, name, sort_order) AS (
    VALUES
        ('tenant:finance:invoice:view', '查看发票管理', 63),
        ('tenant:finance:invoice:issue', '发票开票', 64),
        ('tenant:finance:invoice:void', '发票作废', 65),
        ('tenant:finance:invoice:settings', '发票设置', 66)
),
missing AS (
    SELECT
        source.code,
        source.name,
        source.sort_order,
        ROW_NUMBER() OVER (ORDER BY source.sort_order, source.code) AS rn
    FROM invoice_permissions source
    LEFT JOIN public.permissions existing
        ON existing."Code" = source.code
    WHERE existing."Id" IS NULL
),
base AS (
    SELECT COALESCE(MAX("Id"), 820000000000000000) AS max_id
    FROM public.permissions
),
parent AS (
    SELECT COALESCE(
        (
            SELECT "ParentId"
            FROM public.permissions
            WHERE "Code" = 'tenant:finance:transaction:view'
            LIMIT 1
        ),
        (
            SELECT "ParentId"
            FROM public.permissions
            WHERE "Code" = 'tenant:order:list:view'
            LIMIT 1
        ),
        820000000000000004
    ) AS parent_id
)
INSERT INTO public.permissions
(
    "Id", "Name", "Code", "Description", "CreatedAt", "UpdatedAt", "DeletedAt",
    "CreatedBy", "UpdatedBy", "DeletedBy", "ParentId", "SortOrder", "Type", "Portal"
)
SELECT
    base.max_id + missing.rn,
    missing.name,
    missing.code,
    NULL,
    NOW(),
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    parent.parent_id,
    missing.sort_order,
    'leaf',
    1
FROM missing
CROSS JOIN base
CROSS JOIN parent;

WITH invoice_permissions(code, name, sort_order) AS (
    VALUES
        ('tenant:finance:invoice:view', '查看发票管理', 63),
        ('tenant:finance:invoice:issue', '发票开票', 64),
        ('tenant:finance:invoice:void', '发票作废', 65),
        ('tenant:finance:invoice:settings', '发票设置', 66)
),
parent AS (
    SELECT COALESCE(
        (
            SELECT "ParentId"
            FROM public.permissions
            WHERE "Code" = 'tenant:finance:transaction:view'
            LIMIT 1
        ),
        (
            SELECT "ParentId"
            FROM public.permissions
            WHERE "Code" = 'tenant:order:list:view'
            LIMIT 1
        ),
        820000000000000004
    ) AS parent_id
)
UPDATE public.permissions target
SET
    "Name" = source.name,
    "ParentId" = parent.parent_id,
    "SortOrder" = source.sort_order,
    "Type" = 'leaf',
    "Portal" = 1,
    "DeletedAt" = NULL,
    "DeletedBy" = NULL,
    "UpdatedAt" = NOW()
FROM invoice_permissions source
CROSS JOIN parent
WHERE target."Code" = source.code;

-- 2) 绑定发票管理菜单权限
UPDATE public.menu_definitions
SET
    "RequiredPermissions" = 'tenant:finance:invoice:view',
    "MetaPermissions" = 'tenant:finance:invoice:view,tenant:finance:invoice:issue,tenant:finance:invoice:void,tenant:finance:invoice:settings',
    "AuthListJson" = '[{"title":"开票","authMark":"tenant:finance:invoice:issue"},{"title":"作废","authMark":"tenant:finance:invoice:void"},{"title":"设置","authMark":"tenant:finance:invoice:settings"}]',
    "UpdatedAt" = NOW()
WHERE
    "Portal" = 1
    AND (
        "Name" = 'InvoiceMgmt'
        OR "Path" = 'invoice'
        OR "Component" = '/finance/invoice/index'
    );

-- 3) 给角色模板补齐发票管理权限（按交易流水权限映射）
WITH code_mapping(source_code, target_code) AS (
    VALUES
        ('tenant:finance:transaction:view', 'tenant:finance:invoice:view'),
        ('tenant:finance:transaction:export', 'tenant:finance:invoice:issue'),
        ('tenant:finance:transaction:export', 'tenant:finance:invoice:void'),
        ('tenant:finance:transaction:export', 'tenant:finance:invoice:settings')
),
candidates AS (
    SELECT DISTINCT
        source."RoleTemplateId",
        mapping.target_code
    FROM public.role_template_permissions source
    INNER JOIN code_mapping mapping
        ON mapping.source_code = source."PermissionCode"
    WHERE source."DeletedAt" IS NULL
),
missing AS (
    SELECT
        candidate."RoleTemplateId",
        candidate.target_code,
        ROW_NUMBER() OVER (
            ORDER BY candidate."RoleTemplateId", candidate.target_code
        ) AS rn
    FROM candidates candidate
    LEFT JOIN public.role_template_permissions existing
        ON existing."RoleTemplateId" = candidate."RoleTemplateId"
       AND existing."PermissionCode" = candidate.target_code
    WHERE existing."Id" IS NULL
),
base AS (
    SELECT COALESCE(MAX("Id"), 820000000000000000) AS max_id
    FROM public.role_template_permissions
)
INSERT INTO public.role_template_permissions
(
    "Id", "RoleTemplateId", "PermissionCode", "CreatedAt", "UpdatedAt", "DeletedAt",
    "CreatedBy", "UpdatedBy", "DeletedBy"
)
SELECT
    base.max_id + missing.rn,
    missing."RoleTemplateId",
    missing.target_code,
    NOW(),
    NULL,
    NULL,
    NULL,
    NULL,
    NULL
FROM missing
CROSS JOIN base;

WITH code_mapping(source_code, target_code) AS (
    VALUES
        ('tenant:finance:transaction:view', 'tenant:finance:invoice:view'),
        ('tenant:finance:transaction:export', 'tenant:finance:invoice:issue'),
        ('tenant:finance:transaction:export', 'tenant:finance:invoice:void'),
        ('tenant:finance:transaction:export', 'tenant:finance:invoice:settings')
)
UPDATE public.role_template_permissions target
SET
    "DeletedAt" = NULL,
    "DeletedBy" = NULL,
    "UpdatedAt" = NOW()
FROM public.role_template_permissions source
INNER JOIN code_mapping mapping
    ON mapping.source_code = source."PermissionCode"
WHERE
    source."RoleTemplateId" = target."RoleTemplateId"
    AND target."PermissionCode" = mapping.target_code;

-- 4) 给租户角色补齐发票管理权限（按交易流水权限映射）
WITH code_mapping(source_code, target_code) AS (
    VALUES
        ('tenant:finance:transaction:view', 'tenant:finance:invoice:view'),
        ('tenant:finance:transaction:export', 'tenant:finance:invoice:issue'),
        ('tenant:finance:transaction:export', 'tenant:finance:invoice:void'),
        ('tenant:finance:transaction:export', 'tenant:finance:invoice:settings')
),
source_rows AS (
    SELECT DISTINCT
        source."RoleId",
        source."TenantId",
        source."Portal",
        mapping.target_code
    FROM public.role_permissions source
    INNER JOIN public.permissions source_permission
        ON source_permission."Id" = source."PermissionId"
    INNER JOIN code_mapping mapping
        ON mapping.source_code = source_permission."Code"
    WHERE source."DeletedAt" IS NULL
      AND source."Portal" = 1
),
candidates AS (
    SELECT DISTINCT
        source_row."RoleId",
        source_row."TenantId",
        source_row."Portal",
        target_permission."Id" AS target_permission_id
    FROM source_rows source_row
    INNER JOIN public.permissions target_permission
        ON target_permission."Code" = source_row.target_code
),
missing AS (
    SELECT
        candidate."RoleId",
        candidate."TenantId",
        candidate."Portal",
        candidate.target_permission_id,
        ROW_NUMBER() OVER (
            ORDER BY candidate."TenantId", candidate."RoleId", candidate.target_permission_id
        ) AS rn
    FROM candidates candidate
    LEFT JOIN public.role_permissions existing
        ON existing."RoleId" = candidate."RoleId"
       AND existing."PermissionId" = candidate.target_permission_id
       AND existing."Portal" = candidate."Portal"
       AND (
            (existing."TenantId" IS NULL AND candidate."TenantId" IS NULL)
            OR existing."TenantId" = candidate."TenantId"
       )
    WHERE existing."Id" IS NULL
),
base AS (
    SELECT COALESCE(MAX("Id"), 830000000000000000) AS max_id
    FROM public.role_permissions
)
INSERT INTO public.role_permissions
(
    "Id", "RoleId", "PermissionId", "CreatedAt", "UpdatedAt", "DeletedAt",
    "CreatedBy", "UpdatedBy", "DeletedBy", "TenantId", "Portal"
)
SELECT
    base.max_id + missing.rn,
    missing."RoleId",
    missing.target_permission_id,
    NOW(),
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    missing."TenantId",
    missing."Portal"
FROM missing
CROSS JOIN base;

WITH code_mapping(source_code, target_code) AS (
    VALUES
        ('tenant:finance:transaction:view', 'tenant:finance:invoice:view'),
        ('tenant:finance:transaction:export', 'tenant:finance:invoice:issue'),
        ('tenant:finance:transaction:export', 'tenant:finance:invoice:void'),
        ('tenant:finance:transaction:export', 'tenant:finance:invoice:settings')
)
UPDATE public.role_permissions target
SET
    "DeletedAt" = NULL,
    "DeletedBy" = NULL,
    "UpdatedAt" = NOW()
FROM public.role_permissions source
INNER JOIN public.permissions source_permission
    ON source_permission."Id" = source."PermissionId"
INNER JOIN code_mapping mapping
    ON mapping.source_code = source_permission."Code"
INNER JOIN public.permissions target_permission
    ON target_permission."Code" = mapping.target_code
WHERE
    source."Portal" = 1
    AND target."Portal" = source."Portal"
    AND target."RoleId" = source."RoleId"
    AND target."PermissionId" = target_permission."Id"
    AND (
        (target."TenantId" IS NULL AND source."TenantId" IS NULL)
        OR target."TenantId" = source."TenantId"
    );

COMMIT;
