From 56882acc4f6212aa0080ee19e5ad5cfcaea39b45 Mon Sep 17 00:00:00 2001 From: pqhuy1987 Date: Thu, 11 Jun 2026 15:35:25 +0700 Subject: [PATCH] [CLAUDE] PurchaseEvaluation: tree Panel 1 doi nhom theo anh Kiet FDC "Du an (Nam) > Hang muc cong viec > Phieu" (bo tang NCC, SHA256 mirror x2 app) + wipe testing data prod S59 - Tree Panel 1: moi cap (Du an, Nam-tao-phieu) = 1 folder label "Ten du an (Nam)", level 2 = Hang muc cong viec (WorkItemId Mig 49, phieu cu null -> "(Chua gan hang muc)"), bo tang NCC khoi tree (van hien o card/detail). Expand-state localStorage key v2. - scripts/s59-wipe-testing-data.sql DA CHAY prod (anh chot AskUserQuestion): xoa 10 PE + 7 HD [DEMO] + 64 notif + 1 workflow V2 cu inactive; reset PeSeq/CtSeq -> ma moi tu 001; GIU master 70/86/22 + users 55 + templates 9 + 7 workflow ghim. Uploads orphan da don. --- .../pages/pe/PurchaseEvaluationsListPage.tsx | 228 ++++++++---------- .../pages/pe/PurchaseEvaluationsListPage.tsx | 228 ++++++++---------- scripts/s59-wipe-testing-data.sql | 77 ++++++ 3 files changed, 279 insertions(+), 254 deletions(-) create mode 100644 scripts/s59-wipe-testing-data.sql diff --git a/fe-admin/src/pages/pe/PurchaseEvaluationsListPage.tsx b/fe-admin/src/pages/pe/PurchaseEvaluationsListPage.tsx index 123e784..1202a77 100644 --- a/fe-admin/src/pages/pe/PurchaseEvaluationsListPage.tsx +++ b/fe-admin/src/pages/pe/PurchaseEvaluationsListPage.tsx @@ -115,64 +115,60 @@ export function PurchaseEvaluationsListPage() { // Đã duyệt/Từ chối loại bỏ). BE /inbox hiện loose UAT có thể trả phiếu Nháp → // FE filter để UX đúng kỳ vọng. Phân quyền strict V2 BE pending Session 18+. - // Plan AG5 — Group 3-level Project > Năm > NCC > PE (anh feedback 2026-05-21: - // "Folder cấp dưới dự án là theo năm và dưới năm là theo NCC"). Filter pendingMe TRƯỚC group. - // Year extract từ createdAt.getFullYear(). NCC = selectedSupplierName fallback "(Chưa chọn NCC)" - // khi PE chưa DaDuyet. Sort: Project A-Z (vi) + Year DESC + NCC A-Z (vi) + PE createdAt DESC. - type SupplierGroup = { - supplierId: string | null - supplierName: string + // S59 — anh Kiệt FDC (Zalo 2026-06-11): "Tên dự án ( 2026 ) -> Hạng mục công việc -> Phiếu cần duyệt" + // (mirror cấu trúc folder Outlook FDC, thứ tự label "Dự án - Năm"). Thay tree AG5 cũ (Project > Năm > NCC): + // mỗi cặp (Dự án, Năm-tạo-phiếu) = 1 folder label "Tên dự án (Năm)", level 2 = Hạng mục công việc + // (WorkItemId Mig 49, phiếu cũ chưa gắn → "(Chưa gắn hạng mục)"). NCC bỏ khỏi tree — vẫn hiện ở card/detail. + // Filter pendingMe TRƯỚC group. Sort: Project A-Z (vi) + Năm DESC + Hạng mục A-Z (vi) + PE createdAt DESC. + type WorkItemGroup = { + workItemId: string | null + workItemName: string items: PeListItem[] } - type YearGroup = { - year: number - suppliers: SupplierGroup[] - totalCount: number - } - type ProjectGroup = { + type ProjectYearGroup = { projectId: string | null projectName: string - years: YearGroup[] + year: number + label: string + workItems: WorkItemGroup[] totalCount: number } - const projectGroups = useMemo(() => { + const projectGroups = useMemo(() => { const filtered = pendingMe ? allRows.filter(p => getPeDisplayStatus(p.phase) === PeDisplayStatus.DaGuiDuyet) : allRows - const projectMap = new Map() + const groupMap = new Map() for (const p of filtered) { - const projKey = p.projectId ?? '__no_project__' - const projName = p.projectName?.trim() || '(Dự án đã xoá)' - if (!projectMap.has(projKey)) { - projectMap.set(projKey, { projectId: p.projectId ?? null, projectName: projName, years: [], totalCount: 0 }) - } - const pg = projectMap.get(projKey)! const year = new Date(p.createdAt).getFullYear() - let yg = pg.years.find(y => y.year === year) - if (!yg) { - yg = { year, suppliers: [], totalCount: 0 } - pg.years.push(yg) + const projName = p.projectName?.trim() || '(Dự án đã xoá)' + const groupKey = `${p.projectId ?? '__no_project__'}::y${year}` + if (!groupMap.has(groupKey)) { + groupMap.set(groupKey, { + projectId: p.projectId ?? null, + projectName: projName, + year, + label: `${projName} (${year})`, + workItems: [], + totalCount: 0, + }) } - const supKey = p.selectedSupplierId ?? '__no_supplier__' - const supName = p.selectedSupplierName?.trim() || '(Chưa chọn NCC)' - let sg = yg.suppliers.find(s => (s.supplierId ?? '__no_supplier__') === supKey) - if (!sg) { - sg = { supplierId: p.selectedSupplierId ?? null, supplierName: supName, items: [] } - yg.suppliers.push(sg) + const pg = groupMap.get(groupKey)! + const wiKey = p.workItemId ?? '__no_workitem__' + const wiName = p.workItemName?.trim() || '(Chưa gắn hạng mục)' + let wg = pg.workItems.find(w => (w.workItemId ?? '__no_workitem__') === wiKey) + if (!wg) { + wg = { workItemId: p.workItemId ?? null, workItemName: wiName, items: [] } + pg.workItems.push(wg) } - sg.items.push(p) - yg.totalCount++ + wg.items.push(p) pg.totalCount++ } - const arr = Array.from(projectMap.values()) - arr.sort((a, b) => a.projectName.localeCompare(b.projectName, 'vi')) + const arr = Array.from(groupMap.values()) + arr.sort((a, b) => a.projectName.localeCompare(b.projectName, 'vi') || b.year - a.year) for (const pg of arr) { - pg.years.sort((a, b) => b.year - a.year) - for (const yg of pg.years) { - yg.suppliers.sort((a, b) => a.supplierName.localeCompare(b.supplierName, 'vi')) - for (const sg of yg.suppliers) { - sg.items.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()) - } + pg.workItems.sort((a, b) => a.workItemName.localeCompare(b.workItemName, 'vi')) + for (const wg of pg.workItems) { + wg.items.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()) } } return arr @@ -181,9 +177,9 @@ export function PurchaseEvaluationsListPage() { // Total row count cho header badge (pendingMe đếm filtered, Danh sách đếm BE total). const totalRowCount = projectGroups.reduce((sum, pg) => sum + pg.totalCount, 0) - // Plan AG2 — Expand state localStorage Set (projectId only, drop ::gtKey suffix). - // Default empty Set (all collapse). Single-PE project skip
wrapper (render flat). - const STORAGE_KEY = 'pe_list_expanded_projects' + // Plan AG2 — Expand state localStorage Set. Default empty Set (all collapse). + // S59 key v2: node scheme đổi (Dự án+Năm gộp 1 node + Hạng mục thay NCC) → key cũ vô nghĩa. + const STORAGE_KEY = 'pe_list_expanded_projects_v2' const [expandedSet, setExpandedSet] = useState>(() => { try { const raw = localStorage.getItem(STORAGE_KEY) @@ -285,13 +281,11 @@ export function PurchaseEvaluationsListPage() { )} - {/* Plan AG5 — Tree view 3-level Project > Năm > NCC > PE (anh feedback 2026-05-21: - "Folder cấp dưới dự án là theo năm và dưới năm là theo NCC"). - 3 layer
: 📁 Project (bg-slate-50) > 📅 Năm > 🏢 NCC > PE card. - Tailwind v3 named groups group/proj + group/year + group/sup cho chevron rotation. */} + {/* S59 — Tree view theo anh Kiệt FDC: 📁 "Tên dự án (Năm)" (bg-slate-50) > 🧱 Hạng mục + công việc > PE card. 2 layer
, named groups group/proj + group/wi cho chevron. */}
{projectGroups.map(pg => { - const projKey = pg.projectId ?? '__no_project__' + const projKey = `${pg.projectId ?? '__no_project__'}::y${pg.year}` return (
📁 - {pg.projectName} + {pg.label} {pg.totalCount}
- {pg.years.map(yg => { - const yearKey = `${projKey}::y${yg.year}` + {pg.workItems.map(wg => { + const wiKey = `${projKey}::w${wg.workItemId ?? '_none_'}` return (
toggleExpand(yearKey, (e.currentTarget as HTMLDetailsElement).open)} - className="group/year" + key={wiKey} + open={isExpanded(wiKey)} + onToggle={e => toggleExpand(wiKey, (e.currentTarget as HTMLDetailsElement).open)} + className="group/wi" > - - 📅 - Năm {yg.year} - {yg.totalCount} + + 🧱 + {wg.workItemName} + {wg.items.length} -
- {yg.suppliers.map(sg => { - const supKey = `${yearKey}::s${sg.supplierId ?? '_none_'}` - return ( -
toggleExpand(supKey, (e.currentTarget as HTMLDetailsElement).open)} - className="group/sup" +
    + {wg.items.map(p => ( +
  • + -
  • - ))} -
-
- ) - })} -
+ {/* Plan AG6 — compact card 3 row: title+badge / mã+time / drafter+dept+contract */} +
+
{p.tenGoiThau}
+ + {PeDisplayStatusLabel[getPeDisplayStatus(p.phase)]} + +
+
+ {p.maPhieu ?? '—'} + · + {/* S23 t2 UAT: BE list sort theo UpdatedAt DESC (fallback CreatedAt). */} + + {new Date(p.createdAt).toLocaleString('vi-VN', { + day: '2-digit', month: '2-digit', year: 'numeric', + hour: '2-digit', minute: '2-digit', + })} + +
+ {(p.drafterName || p.departmentName || p.contractId) && ( +
+ + {p.drafterName && <>👤 {p.drafterName}} + {p.drafterName && p.departmentName && · } + {p.departmentName && {p.departmentName}} + + {p.contractId && ✓ HĐ} +
+ )} + + + ))} +
) })} diff --git a/fe-user/src/pages/pe/PurchaseEvaluationsListPage.tsx b/fe-user/src/pages/pe/PurchaseEvaluationsListPage.tsx index 123e784..1202a77 100644 --- a/fe-user/src/pages/pe/PurchaseEvaluationsListPage.tsx +++ b/fe-user/src/pages/pe/PurchaseEvaluationsListPage.tsx @@ -115,64 +115,60 @@ export function PurchaseEvaluationsListPage() { // Đã duyệt/Từ chối loại bỏ). BE /inbox hiện loose UAT có thể trả phiếu Nháp → // FE filter để UX đúng kỳ vọng. Phân quyền strict V2 BE pending Session 18+. - // Plan AG5 — Group 3-level Project > Năm > NCC > PE (anh feedback 2026-05-21: - // "Folder cấp dưới dự án là theo năm và dưới năm là theo NCC"). Filter pendingMe TRƯỚC group. - // Year extract từ createdAt.getFullYear(). NCC = selectedSupplierName fallback "(Chưa chọn NCC)" - // khi PE chưa DaDuyet. Sort: Project A-Z (vi) + Year DESC + NCC A-Z (vi) + PE createdAt DESC. - type SupplierGroup = { - supplierId: string | null - supplierName: string + // S59 — anh Kiệt FDC (Zalo 2026-06-11): "Tên dự án ( 2026 ) -> Hạng mục công việc -> Phiếu cần duyệt" + // (mirror cấu trúc folder Outlook FDC, thứ tự label "Dự án - Năm"). Thay tree AG5 cũ (Project > Năm > NCC): + // mỗi cặp (Dự án, Năm-tạo-phiếu) = 1 folder label "Tên dự án (Năm)", level 2 = Hạng mục công việc + // (WorkItemId Mig 49, phiếu cũ chưa gắn → "(Chưa gắn hạng mục)"). NCC bỏ khỏi tree — vẫn hiện ở card/detail. + // Filter pendingMe TRƯỚC group. Sort: Project A-Z (vi) + Năm DESC + Hạng mục A-Z (vi) + PE createdAt DESC. + type WorkItemGroup = { + workItemId: string | null + workItemName: string items: PeListItem[] } - type YearGroup = { - year: number - suppliers: SupplierGroup[] - totalCount: number - } - type ProjectGroup = { + type ProjectYearGroup = { projectId: string | null projectName: string - years: YearGroup[] + year: number + label: string + workItems: WorkItemGroup[] totalCount: number } - const projectGroups = useMemo(() => { + const projectGroups = useMemo(() => { const filtered = pendingMe ? allRows.filter(p => getPeDisplayStatus(p.phase) === PeDisplayStatus.DaGuiDuyet) : allRows - const projectMap = new Map() + const groupMap = new Map() for (const p of filtered) { - const projKey = p.projectId ?? '__no_project__' - const projName = p.projectName?.trim() || '(Dự án đã xoá)' - if (!projectMap.has(projKey)) { - projectMap.set(projKey, { projectId: p.projectId ?? null, projectName: projName, years: [], totalCount: 0 }) - } - const pg = projectMap.get(projKey)! const year = new Date(p.createdAt).getFullYear() - let yg = pg.years.find(y => y.year === year) - if (!yg) { - yg = { year, suppliers: [], totalCount: 0 } - pg.years.push(yg) + const projName = p.projectName?.trim() || '(Dự án đã xoá)' + const groupKey = `${p.projectId ?? '__no_project__'}::y${year}` + if (!groupMap.has(groupKey)) { + groupMap.set(groupKey, { + projectId: p.projectId ?? null, + projectName: projName, + year, + label: `${projName} (${year})`, + workItems: [], + totalCount: 0, + }) } - const supKey = p.selectedSupplierId ?? '__no_supplier__' - const supName = p.selectedSupplierName?.trim() || '(Chưa chọn NCC)' - let sg = yg.suppliers.find(s => (s.supplierId ?? '__no_supplier__') === supKey) - if (!sg) { - sg = { supplierId: p.selectedSupplierId ?? null, supplierName: supName, items: [] } - yg.suppliers.push(sg) + const pg = groupMap.get(groupKey)! + const wiKey = p.workItemId ?? '__no_workitem__' + const wiName = p.workItemName?.trim() || '(Chưa gắn hạng mục)' + let wg = pg.workItems.find(w => (w.workItemId ?? '__no_workitem__') === wiKey) + if (!wg) { + wg = { workItemId: p.workItemId ?? null, workItemName: wiName, items: [] } + pg.workItems.push(wg) } - sg.items.push(p) - yg.totalCount++ + wg.items.push(p) pg.totalCount++ } - const arr = Array.from(projectMap.values()) - arr.sort((a, b) => a.projectName.localeCompare(b.projectName, 'vi')) + const arr = Array.from(groupMap.values()) + arr.sort((a, b) => a.projectName.localeCompare(b.projectName, 'vi') || b.year - a.year) for (const pg of arr) { - pg.years.sort((a, b) => b.year - a.year) - for (const yg of pg.years) { - yg.suppliers.sort((a, b) => a.supplierName.localeCompare(b.supplierName, 'vi')) - for (const sg of yg.suppliers) { - sg.items.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()) - } + pg.workItems.sort((a, b) => a.workItemName.localeCompare(b.workItemName, 'vi')) + for (const wg of pg.workItems) { + wg.items.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()) } } return arr @@ -181,9 +177,9 @@ export function PurchaseEvaluationsListPage() { // Total row count cho header badge (pendingMe đếm filtered, Danh sách đếm BE total). const totalRowCount = projectGroups.reduce((sum, pg) => sum + pg.totalCount, 0) - // Plan AG2 — Expand state localStorage Set (projectId only, drop ::gtKey suffix). - // Default empty Set (all collapse). Single-PE project skip
wrapper (render flat). - const STORAGE_KEY = 'pe_list_expanded_projects' + // Plan AG2 — Expand state localStorage Set. Default empty Set (all collapse). + // S59 key v2: node scheme đổi (Dự án+Năm gộp 1 node + Hạng mục thay NCC) → key cũ vô nghĩa. + const STORAGE_KEY = 'pe_list_expanded_projects_v2' const [expandedSet, setExpandedSet] = useState>(() => { try { const raw = localStorage.getItem(STORAGE_KEY) @@ -285,13 +281,11 @@ export function PurchaseEvaluationsListPage() {
)} - {/* Plan AG5 — Tree view 3-level Project > Năm > NCC > PE (anh feedback 2026-05-21: - "Folder cấp dưới dự án là theo năm và dưới năm là theo NCC"). - 3 layer
: 📁 Project (bg-slate-50) > 📅 Năm > 🏢 NCC > PE card. - Tailwind v3 named groups group/proj + group/year + group/sup cho chevron rotation. */} + {/* S59 — Tree view theo anh Kiệt FDC: 📁 "Tên dự án (Năm)" (bg-slate-50) > 🧱 Hạng mục + công việc > PE card. 2 layer
, named groups group/proj + group/wi cho chevron. */}
{projectGroups.map(pg => { - const projKey = pg.projectId ?? '__no_project__' + const projKey = `${pg.projectId ?? '__no_project__'}::y${pg.year}` return (
📁 - {pg.projectName} + {pg.label} {pg.totalCount}
- {pg.years.map(yg => { - const yearKey = `${projKey}::y${yg.year}` + {pg.workItems.map(wg => { + const wiKey = `${projKey}::w${wg.workItemId ?? '_none_'}` return (
toggleExpand(yearKey, (e.currentTarget as HTMLDetailsElement).open)} - className="group/year" + key={wiKey} + open={isExpanded(wiKey)} + onToggle={e => toggleExpand(wiKey, (e.currentTarget as HTMLDetailsElement).open)} + className="group/wi" > - - 📅 - Năm {yg.year} - {yg.totalCount} + + 🧱 + {wg.workItemName} + {wg.items.length} -
- {yg.suppliers.map(sg => { - const supKey = `${yearKey}::s${sg.supplierId ?? '_none_'}` - return ( -
toggleExpand(supKey, (e.currentTarget as HTMLDetailsElement).open)} - className="group/sup" +
    + {wg.items.map(p => ( +
  • + -
  • - ))} -
-
- ) - })} -
+ {/* Plan AG6 — compact card 3 row: title+badge / mã+time / drafter+dept+contract */} +
+
{p.tenGoiThau}
+ + {PeDisplayStatusLabel[getPeDisplayStatus(p.phase)]} + +
+
+ {p.maPhieu ?? '—'} + · + {/* S23 t2 UAT: BE list sort theo UpdatedAt DESC (fallback CreatedAt). */} + + {new Date(p.createdAt).toLocaleString('vi-VN', { + day: '2-digit', month: '2-digit', year: 'numeric', + hour: '2-digit', minute: '2-digit', + })} + +
+ {(p.drafterName || p.departmentName || p.contractId) && ( +
+ + {p.drafterName && <>👤 {p.drafterName}} + {p.drafterName && p.departmentName && · } + {p.departmentName && {p.departmentName}} + + {p.contractId && ✓ HĐ} +
+ )} + + + ))} +
) })} diff --git a/scripts/s59-wipe-testing-data.sql b/scripts/s59-wipe-testing-data.sql new file mode 100644 index 0000000..491b62a --- /dev/null +++ b/scripts/s59-wipe-testing-data.sql @@ -0,0 +1,77 @@ +-- ============================================================================ +-- S59 (2026-06-11) — Wipe transactional TESTING data trước khi team vào testing +-- Chỉ đạo: anh Kiệt FDC (Zalo 14:28 "xoá các cái testing trước đi em"). +-- Anh chốt (AskUserQuestion S59): wipe 3 cụm + reset bộ đếm mã về 0. +-- +-- XÓA: 10 PurchaseEvaluations (A/031-040, cascade child) · 7 Contracts [DEMO] +-- (cascade) · 64 Notifications · 1 ApprovalWorkflow V2 cũ (inactive+unghim) +-- · PurchaseEvaluationCodeSequences + ContractCodeSequences (generator tự +-- INSERT LastSeq=1 khi thiếu row → phiếu/HĐ thật đầu tiên = .../001). +-- GIỮ: Projects/WorkItems/Suppliers/Departments (master S55) · Users/Roles/ +-- Permissions/MenuItems · ContractTemplates/Clauses · ApprovalWorkflows +-- GHIM (7 active) · WorkflowDefinitions V1 + PE V1 defs (policy, không +-- phải transactional) · HRM catalogs · EmployeeProfiles. +-- FK: PE child ALL CASCADE trừ Quotes NO_ACTION (multi-path) — single DELETE +-- PurchaseEvaluations vẫn pass vì cascade Details→Quotes dọn trước +-- end-of-statement check (proven scripts/plan-r-cleanup.sql S23). +-- Resurrect-safe: SeedDemoContracts/PurchaseEvaluations nằm trong gate +-- DemoSeed:Disabled=true (DbInitializer.cs) → không seed lại sau restart. +-- Run: sqlcmd -S .\SQLEXPRESS -d SolutionErp -i s59-wipe-testing-data.sql +-- ============================================================================ +SET QUOTED_IDENTIFIER ON; +SET NOCOUNT ON; + +PRINT '=== BEFORE ==='; +SELECT 'PE' AS T, COUNT(*) AS C FROM PurchaseEvaluations +UNION ALL SELECT 'Contracts', COUNT(*) FROM Contracts +UNION ALL SELECT 'Notifications', COUNT(*) FROM Notifications +UNION ALL SELECT 'AwV2_total', COUNT(*) FROM ApprovalWorkflows +UNION ALL SELECT 'PeSeq', COUNT(*) FROM PurchaseEvaluationCodeSequences +UNION ALL SELECT 'CtSeq', COUNT(*) FROM ContractCodeSequences; + +BEGIN TRANSACTION; + +-- 1. Phiếu PE (cascade: Suppliers/Details/Quotes/Approvals/Changelogs/ +-- Attachments/LevelOpinions/DepartmentOpinions) +DELETE FROM PurchaseEvaluations; + +-- 2. Hợp đồng [DEMO] (cascade: Approvals + 7 bảng type-details + Comments/Attachments) +DELETE FROM Contracts; + +-- 3. Thông báo +DELETE FROM Notifications; + +-- 4. Workflow V2 cũ không dùng (QT-DN-V2-001 v1 inactive+unghim — PE pin đã gone +-- ở bước 1 nên FK Restrict released). 7 workflow GHIM active KHÔNG match filter. +DELETE FROM ApprovalWorkflows WHERE IsActive = 0 AND IsUserSelectable = 0; + +-- 5. Reset bộ đếm mã (DELETE row → generator INSERT lại LastSeq=1) +DELETE FROM PurchaseEvaluationCodeSequences; +DELETE FROM ContractCodeSequences; + +PRINT '=== AFTER (expect 0 các bảng transactional, KEEP_* giữ nguyên) ==='; +SELECT 'PE' AS T, COUNT(*) AS C FROM PurchaseEvaluations +UNION ALL SELECT 'PeSuppliers', COUNT(*) FROM PurchaseEvaluationSuppliers +UNION ALL SELECT 'PeDetails', COUNT(*) FROM PurchaseEvaluationDetails +UNION ALL SELECT 'PeQuotes', COUNT(*) FROM PurchaseEvaluationQuotes +UNION ALL SELECT 'PeApprovals', COUNT(*) FROM PurchaseEvaluationApprovals +UNION ALL SELECT 'PeChangelogs', COUNT(*) FROM PurchaseEvaluationChangelogs +UNION ALL SELECT 'PeAttachments', COUNT(*) FROM PurchaseEvaluationAttachments +UNION ALL SELECT 'PeLevelOpinions', COUNT(*) FROM PurchaseEvaluationLevelOpinions +UNION ALL SELECT 'Contracts', COUNT(*) FROM Contracts +UNION ALL SELECT 'CtApprovals', COUNT(*) FROM ContractApprovals +UNION ALL SELECT 'Notifications', COUNT(*) FROM Notifications +UNION ALL SELECT 'AwV2_total', COUNT(*) FROM ApprovalWorkflows +UNION ALL SELECT 'AwV2_active_ghim', COUNT(*) FROM ApprovalWorkflows WHERE IsActive = 1 +UNION ALL SELECT 'PeSeq', COUNT(*) FROM PurchaseEvaluationCodeSequences +UNION ALL SELECT 'CtSeq', COUNT(*) FROM ContractCodeSequences +UNION ALL SELECT 'KEEP_Projects', COUNT(*) FROM Projects +UNION ALL SELECT 'KEEP_WorkItems', COUNT(*) FROM WorkItems +UNION ALL SELECT 'KEEP_Suppliers', COUNT(*) FROM Suppliers +UNION ALL SELECT 'KEEP_Users', COUNT(*) FROM Users +UNION ALL SELECT 'KEEP_Templates', COUNT(*) FROM ContractTemplates +UNION ALL SELECT 'KEEP_WfDefV1', COUNT(*) FROM WorkflowDefinitions +UNION ALL SELECT 'KEEP_PeWfDefV1', COUNT(*) FROM PurchaseEvaluationWorkflowDefinitions; + +COMMIT TRANSACTION; +PRINT 'S59 wipe COMMITTED.';