namespace FrameworkDAL.Query.MenuGroup { /// /// SQL constants for MMENUGROUP / MMENUGROUPDETAIL. Every query here uses only /// ANSI-standard constructs (COALESCE, not ISNULL) so a single constant is valid on /// both SQL Server and PostgreSQL — unlike MenuQB.cs's legacy dual-dialect pairs, /// no _POSTGRE-suffixed duplicates are needed for this table family. /// /// Required indexes (mirrored in the schema migration): /// MMENUGROUP (MENUSETID, PARENTGROUPID) /// MMENUGROUPDETAIL (MENUGROUPID) /// MMENUGROUPDETAIL (MENUID) /// MMENUSETDETAIL (MENUSETID, MENUGROUPID) /// public static class MenuGroupQB { /// /// Flat list of every group visible to a given MenuSetId: shared bundle nodes /// (MENUSETID IS NULL) plus any private nodes scoped to this set. The BLL builds /// the tree from this flat list via TreeHelper.ConvertToTree, after translating /// ParentGroupId == -1 to a null Parent reference (mirrors MenuBLL's MMENU handling). /// public const string GET_MENUGROUP_FLAT_LIST = @" SELECT MENUGROUPID AS MenuGroupId, GROUPCODE AS GroupCode, GROUPNAME AS GroupName, MODULEID AS ModuleId, MENUSETID AS MenuSetId, PARENTGROUPID AS ParentGroupId, PARENTGROUPIDS AS ParentGroupIds, LEVELS AS Levels, ICONNAME AS IconName, REMARKS AS Remarks, SORTORDER AS SortOrder, STATUS AS Status, VERSION AS Version, SOURCETYPE AS SourceType, CREATEDBYID AS CreatedById, CREATEDON AS CreatedOn, MODIFIEDBYID AS ModifiedById, MODIFIEDON AS ModifiedOn FROM MMENUGROUP WHERE (MENUSETID IS NULL OR MENUSETID = @MenuSetId) AND STATUS = 1 ORDER BY SORTORDER"; /// Small, dedicated lookup — not a reuse of MenuSetQB.GET_MENUSET, see /// MenuSetPresentationInfoDTO's remarks. public const string GET_MENUSET_PRESENTATION_INFO = @" SELECT menusetid AS MenuSetId, moduleid AS ModuleId --presentationtype AS PresentationType, -- menugroupid AS MenuGroupId FROM mmenuset WHERE menusetid = @MenuSetId"; public const string GET_MENUGROUP_BY_ID = @" SELECT MENUGROUPID AS MenuGroupId, GROUPCODE AS GroupCode, GROUPNAME AS GroupName, MODULEID AS ModuleId, MENUSETID AS MenuSetId, PARENTGROUPID AS ParentGroupId, ICONNAME AS IconName, SORTORDER AS SortOrder, STATUS AS Status, VERSION AS Version, SOURCETYPE AS SourceType FROM MMENUGROUP WHERE MENUGROUPID = @MenuGroupId"; /// /// Resolved leaves for a set of group ids (the tree just walked): bundle membership /// (MMENUGROUPDETAIL) left-joined to MMENU for the fallback display name, left-joined /// to MMENUSETDETAIL for this MenuSetId's per-client override. ResolvedMenuGroupId /// applies the MENUGROUPID re-filing override; the other Resolved* columns apply the /// display-name/sort/visibility override, per the resolution order documented in /// gb5_menu_presentation_layer.sql: override row found -> use it, not found -> MMENU's /// own display name + the bundle's own SORTORDER + ISVISIBLE = 1. /// /// @RoleId is nullable by design: admin/content-management callers (the MenuGroup admin /// tree, the Client Menu Set Editor) pass NULL to see full bundle membership regardless /// of any one role's rights. End-user callers (the production menu-tree endpoint) pass /// the caller's LoginDTO.RoleId, which applies the same MROLEVSMENU view-right check /// (Allow position 1 = '0') the legacy GetMenuForUserModule query enforces. /// public const string GET_RESOLVED_LEAVES_BY_GROUPIDS = @" SELECT COALESCE(msd.MENUGROUPID, gd.MENUGROUPID) AS MenuGroupId, gd.MENUID AS MenuId, m.MENUCODE AS MenuCode, CASE WHEN COALESCE(msd.MENUDISPLAYNAME, '') = '' THEN m.MENUDISPLAYNAME ELSE msd.MENUDISPLAYNAME END AS DisplayName, COALESCE(msd.SORTORDER, gd.SORTORDER) AS SortOrder, COALESCE(msd.ISVISIBLE, 1) AS IsVisible, COALESCE(msd.MENUSETDETAILID, 0) AS MenuSetDetailId FROM MMENUGROUPDETAIL gd JOIN MMENU m ON m.MENUID = gd.MENUID LEFT JOIN MMENUSETDETAIL msd ON msd.MENUSETID = @MenuSetId AND msd.MENUID = gd.MENUID WHERE gd.MENUGROUPID IN @GroupIds AND (@RoleId IS NULL OR EXISTS ( SELECT 1 FROM MROLEVSMENU rvm WHERE rvm.MENUID = gd.MENUID AND rvm.ROLEID = @RoleId AND SUBSTRING(rvm.ALLOW, 1, 1) = '0' ))"; /// Resolves the MenuSetId a client currently has bound to a module, via /// MCLIENTMODULE — the same join the legacy GET_MENU_TREE_FOR_USER_MODULE query uses /// inline. Returns null if the client has no menu set assigned for this module. public const string GET_MENUSETID_FOR_MODULE = @" SELECT MENUSETID FROM MCLIENTMODULE WHERE CLIENTID = @ClientId AND MODULEID = @ModuleId"; public const string INSERT_MENUGROUP = @" INSERT INTO MMENUGROUP (MENUGROUPID, GROUPCODE, GROUPNAME, MODULEID, MENUSETID, PARENTGROUPID, ICONNAME, REMARKS, SORTORDER, STATUS, VERSION, SOURCETYPE, CREATEDBYID, CREATEDON, MODIFIEDBYID, MODIFIEDON) VALUES (@MenuGroupId, @GroupCode, @GroupName, @ModuleId, @MenuSetId, @ParentGroupId, @IconName, @Remarks, @SortOrder, @Status, @Version, @SourceType, @CreatedById, @CreatedOn, @ModifiedById, @ModifiedOn)"; public const string UPDATE_MENUGROUP = @" UPDATE MMENUGROUP SET GROUPCODE = @GroupCode, GROUPNAME = @GroupName, MODULEID = @ModuleId, MENUSETID = @MenuSetId, PARENTGROUPID = @ParentGroupId, ICONNAME = @IconName, REMARKS = @Remarks, SORTORDER = @SortOrder, STATUS = @Status, VERSION = VERSION + 1, MODIFIEDBYID = @ModifiedById, MODIFIEDON = @ModifiedOn WHERE MENUGROUPID = @MenuGroupId"; public const string DELETE_MENUGROUP = "DELETE FROM MMENUGROUP WHERE MENUGROUPID = @MenuGroupId"; // ── MMENUGROUPDETAIL diff-save statements (SkillProcessStageMapDAL shape) ────────── public const string DELETE_MENUGROUPDETAIL_NOT_IN = @" DELETE FROM MMENUGROUPDETAIL WHERE MENUGROUPID = @MenuGroupId AND MENUGROUPDETAILID NOT IN @SurvivingIds"; public const string DELETE_MENUGROUPDETAIL_BY_GROUP = "DELETE FROM MMENUGROUPDETAIL WHERE MENUGROUPID = @MenuGroupId"; public const string INSERT_MENUGROUPDETAIL = @" INSERT INTO MMENUGROUPDETAIL (MENUGROUPDETAILID, MENUGROUPID, MENUID, SORTORDER, SOURCETYPE, CREATEDBYID, CREATEDON, MODIFIEDBYID, MODIFIEDON) VALUES (@MenuGroupDetailId, @MenuGroupId, @MenuId, @SortOrder, @SourceType, @CreatedById, @CreatedOn, @ModifiedById, @ModifiedOn)"; public const string UPDATE_MENUGROUPDETAIL = @" UPDATE MMENUGROUPDETAIL SET MENUID = @MenuId, SORTORDER = @SortOrder, SOURCETYPE = @SourceType, MODIFIEDBYID = @ModifiedById, MODIFIEDON = @ModifiedOn WHERE MENUGROUPDETAILID = @MenuGroupDetailId"; } }