VoiceNotes is an Arduino sketch for the Waveshare ESP32-C6-LCD-0.85 that records meetings and voice memos to microSD and turns them into notes: - Records 16 kHz mono WAV (up to 4 h) from the ES7210 dual mics, with a boosted preamp and soft-limited digital gain - Transcribes via an OpenAI-compatible speech-to-text API in ~10 min parts cut at quiet points, with retries and resume after failures - Summarizes the transcript with Claude into meeting notes (decisions, action items, topics with timestamps), streamed to and from the card - Copies the notes to Nextcloud over WebDAV - Shows recording/processing state on the 0.85" LCD and the LED ring - Works around the board's SD card failing multi-sector reads Credentials live in VoiceNotes/secrets.h, which is git-ignored; see secrets.example.h. Also adds the Microsoft CDM customer service SQL implementation (DDL, sample data, reporting queries and docs). Its README is renamed to CDM_README.md so the repository README stays at the top level. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
581 lines
19 KiB
Transact-SQL
581 lines
19 KiB
Transact-SQL
-- Microsoft Common Data Model - Customer Service
|
|
-- Reporting and Administrative Queries - FIXED VERSION
|
|
-- Version: 1.0
|
|
|
|
USE CDM_CustomerService;
|
|
GO
|
|
|
|
PRINT 'Creating reporting views and procedures...';
|
|
GO
|
|
|
|
-- ============================================================================
|
|
-- DASHBOARD & KPI VIEWS
|
|
-- ============================================================================
|
|
|
|
-- 1. Executive Dashboard - Key Metrics
|
|
CREATE OR ALTER VIEW cdm.v_ExecutiveDashboard AS
|
|
SELECT
|
|
(SELECT COUNT(*) FROM cdm.[Case] WHERE status = 'Active') AS activeCases,
|
|
(SELECT COUNT(*) FROM cdm.[Case] WHERE status = 'Resolved') AS resolvedCases,
|
|
(SELECT COUNT(*) FROM cdm.[Case] WHERE status = 'Closed') AS closedCases,
|
|
(SELECT COUNT(*) FROM cdm.Account WHERE accountType = 'Customer' AND isActive = 1) AS totalCustomers,
|
|
(SELECT COUNT(*) FROM cdm.Contract WHERE status = 'Active') AS activeContracts,
|
|
(SELECT SUM(contractValue) FROM cdm.Contract WHERE status = 'Active') AS activeContractValue,
|
|
(SELECT COUNT(DISTINCT contactId) FROM cdm.[Case] WHERE status = 'Active') AS affectedContacts,
|
|
(SELECT AVG(DATEDIFF(DAY, createdDate, ISNULL(closedDate, GETUTCDATE())))
|
|
FROM cdm.[Case] WHERE status = 'Closed' AND closedDate IS NOT NULL) AS avgDaysToClose;
|
|
|
|
PRINT 'View v_ExecutiveDashboard created.';
|
|
GO
|
|
|
|
-- 2. Case Performance Metrics
|
|
CREATE OR ALTER VIEW cdm.v_CasePerformanceMetrics AS
|
|
SELECT
|
|
c.caseId,
|
|
c.caseNumber,
|
|
c.title,
|
|
c.priority,
|
|
c.status,
|
|
a.accountName,
|
|
u.firstName + ' ' + u.lastName AS ownerName,
|
|
DATEDIFF(DAY, c.createdDate, GETUTCDATE()) AS daysOpen,
|
|
DATEDIFF(HOUR, c.createdDate, ISNULL(c.resolvedDate, GETUTCDATE())) AS hoursToResolution,
|
|
cr.actualServiceDuration,
|
|
CASE
|
|
WHEN c.status = 'Closed' THEN 'Complete'
|
|
WHEN c.status = 'Resolved' THEN 'Awaiting Close'
|
|
WHEN DATEDIFF(DAY, c.createdDate, GETUTCDATE()) > 30 THEN 'Overdue'
|
|
ELSE 'On Track'
|
|
END AS statusHealth
|
|
FROM cdm.[Case] c
|
|
LEFT JOIN cdm.Account a ON c.accountId = a.accountId
|
|
LEFT JOIN cdm.[User] u ON c.ownerUserId = u.userId
|
|
LEFT JOIN cdm.CaseResolution cr ON c.caseId = cr.caseId
|
|
WHERE c.isActive = 1;
|
|
|
|
PRINT 'View v_CasePerformanceMetrics created.';
|
|
GO
|
|
|
|
-- 3. Agent Performance Report
|
|
CREATE OR ALTER VIEW cdm.v_AgentPerformance AS
|
|
SELECT
|
|
u.userId,
|
|
u.firstName + ' ' + u.lastName AS agentName,
|
|
COUNT(DISTINCT c.caseId) AS totalCasesOwned,
|
|
SUM(CASE WHEN c.status = 'Active' THEN 1 ELSE 0 END) AS activeCases,
|
|
SUM(CASE WHEN c.status = 'Closed' THEN 1 ELSE 0 END) AS closedCases,
|
|
AVG(CAST(DATEDIFF(HOUR, c.createdDate, ISNULL(c.resolvedDate, GETUTCDATE())) AS FLOAT)) AS avgHoursToResolution,
|
|
SUM(CASE WHEN c.priority = 'Critical' THEN 1 ELSE 0 END) AS criticalCases,
|
|
SUM(CASE WHEN c.priority = 'High' THEN 1 ELSE 0 END) AS highPriorityCases
|
|
FROM cdm.[User] u
|
|
LEFT JOIN cdm.[Case] c ON u.userId = c.ownerUserId AND c.isActive = 1
|
|
GROUP BY u.userId, u.firstName, u.lastName;
|
|
|
|
PRINT 'View v_AgentPerformance created.';
|
|
GO
|
|
|
|
-- 4. Contract Utilization Dashboard
|
|
CREATE OR ALTER VIEW cdm.v_ContractUtilizationDashboard AS
|
|
SELECT
|
|
c.contractNumber,
|
|
c.contractName,
|
|
a.accountName,
|
|
DATEDIFF(DAY, c.startDate, c.endDate) AS contractDurationDays,
|
|
DATEDIFF(DAY, GETUTCDATE(), c.endDate) AS daysRemaining,
|
|
SUM(cl.quantityIncluded) AS totalUnitsIncluded,
|
|
SUM(cl.quantityUsed) AS totalUnitsUsed,
|
|
CASE
|
|
WHEN SUM(cl.quantityIncluded) > 0
|
|
THEN CAST(CAST(SUM(cl.quantityUsed) AS FLOAT) / CAST(SUM(cl.quantityIncluded) AS FLOAT) * 100 AS DECIMAL(5,2))
|
|
ELSE 0
|
|
END AS utilizationPercent,
|
|
c.contractValue,
|
|
SUM(cl.price) AS lineItemValue,
|
|
CASE
|
|
WHEN CAST(CAST(SUM(cl.quantityUsed) AS FLOAT) / CAST(SUM(cl.quantityIncluded) AS FLOAT) * 100 AS DECIMAL(5,2)) > 80
|
|
THEN 'APPROACHING LIMIT'
|
|
WHEN CAST(CAST(SUM(cl.quantityUsed) AS FLOAT) / CAST(SUM(cl.quantityIncluded) AS FLOAT) * 100 AS DECIMAL(5,2)) > 100
|
|
THEN 'EXCEEDED'
|
|
ELSE 'NORMAL'
|
|
END AS utilizationStatus
|
|
FROM cdm.Contract c
|
|
LEFT JOIN cdm.Account a ON c.accountId = a.accountId
|
|
LEFT JOIN cdm.ContractLine cl ON c.contractId = cl.contractId
|
|
WHERE c.isActive = 1 AND c.status = 'Active'
|
|
GROUP BY c.contractId, c.contractNumber, c.contractName, a.accountName,
|
|
c.startDate, c.endDate, c.contractValue;
|
|
|
|
PRINT 'View v_ContractUtilizationDashboard created.';
|
|
GO
|
|
|
|
-- ============================================================================
|
|
-- ANALYTICAL PROCEDURES
|
|
-- ============================================================================
|
|
|
|
-- 5. Case Volume by Priority (Last 90 Days)
|
|
CREATE OR ALTER PROCEDURE sp_CaseVolumeByPriority
|
|
@Days INT = 90
|
|
AS
|
|
BEGIN
|
|
SELECT
|
|
c.priority,
|
|
COUNT(*) AS caseCount,
|
|
CAST(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM cdm.[Case]
|
|
WHERE createdDate >= DATEADD(DAY, -@Days, CAST(GETUTCDATE() AS DATE))) AS DECIMAL(5,2)) AS percentOfTotal,
|
|
AVG(DATEDIFF(HOUR, c.createdDate, ISNULL(c.resolvedDate, GETUTCDATE()))) AS avgHoursOpen
|
|
FROM cdm.[Case] c
|
|
WHERE c.createdDate >= DATEADD(DAY, -@Days, CAST(GETUTCDATE() AS DATE))
|
|
AND c.isActive = 1
|
|
GROUP BY c.priority
|
|
ORDER BY CASE c.priority
|
|
WHEN 'Critical' THEN 1
|
|
WHEN 'High' THEN 2
|
|
WHEN 'Medium' THEN 3
|
|
WHEN 'Low' THEN 4
|
|
ELSE 5 END;
|
|
END;
|
|
|
|
PRINT 'Procedure sp_CaseVolumeByPriority created.';
|
|
GO
|
|
|
|
-- 6. Customer Satisfaction Analysis
|
|
CREATE OR ALTER PROCEDURE sp_CustomerSatisfactionAnalysis
|
|
@Months INT = 6
|
|
AS
|
|
BEGIN
|
|
SELECT
|
|
a.accountId,
|
|
a.accountName,
|
|
COUNT(DISTINCT c.caseId) AS totalCases,
|
|
SUM(CASE WHEN c.status = 'Closed' THEN 1 ELSE 0 END) AS closedCases,
|
|
CAST(SUM(CASE WHEN c.status = 'Closed' THEN 1 ELSE 0 END) * 100.0 / COUNT(*) AS DECIMAL(5,2)) AS closureRate,
|
|
AVG(CAST(DATEDIFF(DAY, c.createdDate, ISNULL(c.resolvedDate, GETUTCDATE())) AS FLOAT)) AS avgDaysOpen,
|
|
COUNT(DISTINCT c.contactId) AS uniqueContacts,
|
|
SUM(CASE WHEN c.priority = 'Critical' THEN 1 ELSE 0 END) AS criticalCases
|
|
FROM cdm.Account a
|
|
LEFT JOIN cdm.[Case] c ON a.accountId = c.accountId
|
|
AND c.createdDate >= DATEADD(MONTH, -@Months, GETUTCDATE())
|
|
AND c.isActive = 1
|
|
WHERE a.accountType = 'Customer' AND a.isActive = 1
|
|
GROUP BY a.accountId, a.accountName
|
|
ORDER BY closureRate DESC;
|
|
END;
|
|
|
|
PRINT 'Procedure sp_CustomerSatisfactionAnalysis created.';
|
|
GO
|
|
|
|
-- 7. SLA Compliance Report
|
|
CREATE OR ALTER PROCEDURE sp_SLAComplianceReport
|
|
AS
|
|
BEGIN
|
|
SELECT
|
|
c.caseNumber,
|
|
c.title,
|
|
sk.kpiName,
|
|
sk.metricValue,
|
|
sk.metricUnit,
|
|
sk.targetValue,
|
|
CASE
|
|
WHEN sk.metricValue <= sk.targetValue THEN 'COMPLIANT'
|
|
WHEN sk.metricValue <= sk.targetValue * 1.1 THEN 'WARNING'
|
|
ELSE 'CRITICAL'
|
|
END AS complianceStatus,
|
|
CAST((sk.metricValue - sk.targetValue) * 100.0 / sk.targetValue AS DECIMAL(5,2)) AS variancePercent,
|
|
a.accountName,
|
|
u.firstName + ' ' + u.lastName AS owner
|
|
FROM cdm.[Case] c
|
|
JOIN cdm.SLAKPIInstance sk ON c.caseId = sk.caseId
|
|
LEFT JOIN cdm.Account a ON c.accountId = a.accountId
|
|
LEFT JOIN cdm.[User] u ON c.ownerUserId = u.userId
|
|
WHERE c.status IN ('Active', 'Waiting')
|
|
ORDER BY
|
|
CASE
|
|
WHEN sk.metricValue > sk.targetValue THEN 1
|
|
ELSE 2
|
|
END,
|
|
sk.metricValue DESC;
|
|
END;
|
|
|
|
PRINT 'Procedure sp_SLAComplianceReport created.';
|
|
GO
|
|
|
|
-- 8. Service Activity Schedule
|
|
CREATE OR ALTER PROCEDURE sp_ServiceActivitySchedule
|
|
@Days INT = 7
|
|
AS
|
|
BEGIN
|
|
SELECT
|
|
sa.activityId,
|
|
sa.subject,
|
|
s.serviceName,
|
|
c.caseNumber,
|
|
a.accountName,
|
|
u.firstName + ' ' + u.lastName AS technician,
|
|
CAST(sa.startTime AS DATE) AS scheduleDate,
|
|
FORMAT(sa.startTime, 'HH:mm') AS startTime,
|
|
FORMAT(sa.endTime, 'HH:mm') AS endTime,
|
|
sa.duration,
|
|
sa.location,
|
|
sa.status
|
|
FROM cdm.ServiceActivity sa
|
|
LEFT JOIN cdm.Service s ON sa.serviceId = s.serviceId
|
|
LEFT JOIN cdm.[Case] c ON sa.caseId = c.caseId
|
|
LEFT JOIN cdm.Account a ON c.accountId = a.accountId
|
|
LEFT JOIN cdm.[User] u ON sa.ownerUserId = u.userId
|
|
WHERE sa.startTime >= GETUTCDATE()
|
|
AND sa.startTime <= DATEADD(DAY, @Days, GETUTCDATE())
|
|
AND sa.isActive = 1
|
|
ORDER BY sa.startTime;
|
|
END;
|
|
|
|
PRINT 'Procedure sp_ServiceActivitySchedule created.';
|
|
GO
|
|
|
|
-- ============================================================================
|
|
-- ADMINISTRATIVE PROCEDURES
|
|
-- ============================================================================
|
|
|
|
-- 9. Close Resolved Cases
|
|
CREATE OR ALTER PROCEDURE sp_CloseResolvedCases
|
|
@DaysOld INT = 7
|
|
AS
|
|
BEGIN
|
|
UPDATE cdm.[Case]
|
|
SET status = 'Closed',
|
|
closedDate = GETUTCDATE(),
|
|
modifiedOn = GETUTCDATE()
|
|
WHERE status = 'Resolved'
|
|
AND resolvedDate <= DATEADD(DAY, -@DaysOld, CAST(GETUTCDATE() AS DATE))
|
|
AND isActive = 1;
|
|
|
|
DECLARE @rowsAffected INT = @@ROWCOUNT;
|
|
PRINT 'Closed ' + CAST(@rowsAffected AS VARCHAR) + ' resolved cases.';
|
|
RETURN @rowsAffected;
|
|
END;
|
|
|
|
PRINT 'Procedure sp_CloseResolvedCases created.';
|
|
GO
|
|
|
|
-- 10. Archive Old Cases
|
|
CREATE OR ALTER PROCEDURE sp_ArchiveOldCases
|
|
@YearsOld INT = 2
|
|
AS
|
|
BEGIN
|
|
UPDATE cdm.[Case]
|
|
SET isActive = 0
|
|
WHERE status IN ('Closed', 'Resolved')
|
|
AND closedDate <= DATEADD(YEAR, -@YearsOld, GETUTCDATE())
|
|
AND isActive = 1;
|
|
|
|
DECLARE @rowsAffected INT = @@ROWCOUNT;
|
|
PRINT 'Archived ' + CAST(@rowsAffected AS VARCHAR) + ' old cases.';
|
|
RETURN @rowsAffected;
|
|
END;
|
|
|
|
PRINT 'Procedure sp_ArchiveOldCases created.';
|
|
GO
|
|
|
|
-- 11. Deactivate Expired Contracts
|
|
CREATE OR ALTER PROCEDURE sp_DeactivateExpiredContracts
|
|
AS
|
|
BEGIN
|
|
UPDATE cdm.Contract
|
|
SET status = 'Expired',
|
|
modifiedOn = GETUTCDATE()
|
|
WHERE endDate < CAST(GETUTCDATE() AS DATE)
|
|
AND status = 'Active'
|
|
AND isActive = 1;
|
|
|
|
DECLARE @rowsAffected INT = @@ROWCOUNT;
|
|
PRINT 'Expired ' + CAST(@rowsAffected AS VARCHAR) + ' contracts.';
|
|
RETURN @rowsAffected;
|
|
END;
|
|
|
|
PRINT 'Procedure sp_DeactivateExpiredContracts created.';
|
|
GO
|
|
|
|
-- 12. Update Entitlement Status
|
|
CREATE OR ALTER PROCEDURE sp_UpdateEntitlementStatus
|
|
AS
|
|
BEGIN
|
|
UPDATE cdm.Entitlement
|
|
SET status = 'Expired',
|
|
modifiedOn = GETUTCDATE()
|
|
WHERE endDate < CAST(GETUTCDATE() AS DATE)
|
|
AND status = 'Active'
|
|
AND isActive = 1;
|
|
|
|
DECLARE @rowsAffected INT = @@ROWCOUNT;
|
|
PRINT 'Expired ' + CAST(@rowsAffected AS VARCHAR) + ' entitlements.';
|
|
RETURN @rowsAffected;
|
|
END;
|
|
|
|
PRINT 'Procedure sp_UpdateEntitlementStatus created.';
|
|
GO
|
|
|
|
-- 13. Find Overdue Cases
|
|
CREATE OR ALTER PROCEDURE sp_UpdateCaseOverdueStatus
|
|
@ThresholdDays INT = 30
|
|
AS
|
|
BEGIN
|
|
SELECT
|
|
c.caseId,
|
|
c.caseNumber,
|
|
a.accountName,
|
|
DATEDIFF(DAY, c.createdDate, GETUTCDATE()) AS daysOpen
|
|
FROM cdm.[Case] c
|
|
LEFT JOIN cdm.Account a ON c.accountId = a.accountId
|
|
WHERE c.status IN ('Active', 'Waiting')
|
|
AND DATEDIFF(DAY, c.createdDate, GETUTCDATE()) > @ThresholdDays
|
|
AND c.isActive = 1
|
|
ORDER BY DATEDIFF(DAY, c.createdDate, GETUTCDATE()) DESC;
|
|
END;
|
|
|
|
PRINT 'Procedure sp_UpdateCaseOverdueStatus created.';
|
|
GO
|
|
|
|
-- 14. Contract Renewal Alerts
|
|
CREATE OR ALTER PROCEDURE sp_ContractRenewalAlerts
|
|
@DaysUntilExpiry INT = 30
|
|
AS
|
|
BEGIN
|
|
SELECT
|
|
c.contractId,
|
|
c.contractNumber,
|
|
c.contractName,
|
|
a.accountName,
|
|
c.endDate,
|
|
DATEDIFF(DAY, GETUTCDATE(), c.endDate) AS daysUntilExpiry,
|
|
c.contractValue,
|
|
u.firstName + ' ' + u.lastName AS owner,
|
|
u.email
|
|
FROM cdm.Contract c
|
|
LEFT JOIN cdm.Account a ON c.accountId = a.accountId
|
|
LEFT JOIN cdm.[User] u ON c.ownerUserId = u.userId
|
|
WHERE c.status = 'Active'
|
|
AND DATEDIFF(DAY, GETUTCDATE(), c.endDate) <= @DaysUntilExpiry
|
|
AND DATEDIFF(DAY, GETUTCDATE(), c.endDate) > 0
|
|
AND c.isActive = 1
|
|
ORDER BY c.endDate;
|
|
END;
|
|
|
|
PRINT 'Procedure sp_ContractRenewalAlerts created.';
|
|
GO
|
|
|
|
-- ============================================================================
|
|
-- DATA QUALITY PROCEDURES
|
|
-- ============================================================================
|
|
|
|
-- 15. Cases without Required Information
|
|
CREATE OR ALTER PROCEDURE sp_CasesWithMissingData
|
|
AS
|
|
BEGIN
|
|
SELECT
|
|
'Missing Account' AS dataQualityIssue,
|
|
COUNT(*) AS caseCount
|
|
FROM cdm.[Case]
|
|
WHERE accountId IS NULL AND isActive = 1
|
|
UNION ALL
|
|
SELECT
|
|
'Missing Owner',
|
|
COUNT(*)
|
|
FROM cdm.[Case]
|
|
WHERE ownerUserId IS NULL AND isActive = 1
|
|
UNION ALL
|
|
SELECT
|
|
'Missing Contact (High Priority)',
|
|
COUNT(*)
|
|
FROM cdm.[Case]
|
|
WHERE contactId IS NULL
|
|
AND priority IN ('High', 'Critical')
|
|
AND status IN ('Active', 'Waiting')
|
|
AND isActive = 1;
|
|
END;
|
|
|
|
PRINT 'Procedure sp_CasesWithMissingData created.';
|
|
GO
|
|
|
|
-- 16. Find Orphaned Records
|
|
CREATE OR ALTER PROCEDURE sp_FindOrphanedRecords
|
|
AS
|
|
BEGIN
|
|
SELECT 'Orphaned ServiceActivity' AS recordType, COUNT(*) AS count
|
|
FROM cdm.ServiceActivity sa
|
|
WHERE sa.caseId IS NOT NULL
|
|
AND NOT EXISTS (SELECT 1 FROM cdm.[Case] c WHERE c.caseId = sa.caseId)
|
|
|
|
UNION ALL
|
|
|
|
SELECT 'Orphaned Task', COUNT(*)
|
|
FROM cdm.Task t
|
|
WHERE t.caseId IS NOT NULL
|
|
AND NOT EXISTS (SELECT 1 FROM cdm.[Case] c WHERE c.caseId = t.caseId)
|
|
|
|
UNION ALL
|
|
|
|
SELECT 'Orphaned ContractLine', COUNT(*)
|
|
FROM cdm.ContractLine cl
|
|
WHERE NOT EXISTS (SELECT 1 FROM cdm.Contract c WHERE c.contractId = cl.contractId);
|
|
END;
|
|
|
|
PRINT 'Procedure sp_FindOrphanedRecords created.';
|
|
GO
|
|
|
|
-- ============================================================================
|
|
-- REPORTING PROCEDURES
|
|
-- ============================================================================
|
|
|
|
-- 17. Monthly Activity Report
|
|
CREATE OR ALTER PROCEDURE sp_MonthlyActivityReport
|
|
@Year INT,
|
|
@Month INT
|
|
AS
|
|
BEGIN
|
|
DECLARE @StartDate DATE = DATEFROMPARTS(@Year, @Month, 1);
|
|
DECLARE @EndDate DATE = EOMONTH(@StartDate);
|
|
|
|
SELECT
|
|
FORMAT(@StartDate, 'MMMM yyyy') AS reportMonth,
|
|
(SELECT COUNT(*) FROM cdm.[Case] WHERE createdDate >= @StartDate AND createdDate <= @EndDate AND isActive = 1) AS newCases,
|
|
(SELECT COUNT(*) FROM cdm.[Case] WHERE status = 'Closed' AND closedDate >= @StartDate AND closedDate <= @EndDate AND isActive = 1) AS closedCases,
|
|
(SELECT COUNT(*) FROM cdm.ServiceActivity WHERE createdDate >= @StartDate AND createdDate <= @EndDate AND isActive = 1) AS serviceActivities,
|
|
(SELECT COUNT(*) FROM cdm.Task WHERE createdDate >= @StartDate AND createdDate <= @EndDate) AS tasksCreated,
|
|
(SELECT COUNT(*) FROM cdm.Task WHERE status = 'Completed' AND modifiedOn >= @StartDate AND modifiedOn <= @EndDate) AS tasksCompleted,
|
|
(SELECT COUNT(*) FROM cdm.Contract WHERE status = 'Active' AND startDate <= @EndDate AND endDate >= @StartDate) AS activeContracts;
|
|
END;
|
|
|
|
PRINT 'Procedure sp_MonthlyActivityReport created.';
|
|
GO
|
|
|
|
-- 18. Customer Revenue Analysis
|
|
CREATE OR ALTER PROCEDURE sp_CustomerRevenueAnalysis
|
|
AS
|
|
BEGIN
|
|
SELECT
|
|
TOP 20
|
|
a.accountId,
|
|
a.accountName,
|
|
a.industry,
|
|
COUNT(DISTINCT c.contractId) AS numberOfContracts,
|
|
SUM(c.contractValue) AS totalContractValue,
|
|
AVG(c.contractValue) AS avgContractValue,
|
|
COUNT(DISTINCT CASE WHEN c.status = 'Active' THEN c.contractId END) AS activeContracts,
|
|
COUNT(DISTINCT ca.caseId) AS totalCases,
|
|
SUM(CASE WHEN ca.status = 'Closed' THEN 1 ELSE 0 END) AS closedCases
|
|
FROM cdm.Account a
|
|
LEFT JOIN cdm.Contract c ON a.accountId = c.accountId
|
|
LEFT JOIN cdm.[Case] ca ON a.accountId = ca.accountId
|
|
WHERE a.accountType = 'Customer' AND a.isActive = 1
|
|
GROUP BY a.accountId, a.accountName, a.industry
|
|
ORDER BY totalContractValue DESC;
|
|
END;
|
|
|
|
PRINT 'Procedure sp_CustomerRevenueAnalysis created.';
|
|
GO
|
|
|
|
-- 19. Resource Utilization Report
|
|
CREATE OR ALTER PROCEDURE sp_ResourceUtilizationReport
|
|
@Days INT = 30
|
|
AS
|
|
BEGIN
|
|
SELECT
|
|
r.resourceId,
|
|
r.resourceName,
|
|
r.resourceType,
|
|
COUNT(DISTINCT sa.activityId) AS scheduledActivities,
|
|
SUM(sa.duration) AS totalMinutesScheduled,
|
|
AVG(sa.duration) AS avgActivityDuration,
|
|
COUNT(DISTINCT CASE WHEN sa.status = 'Completed' THEN sa.activityId END) AS completedActivities,
|
|
COUNT(DISTINCT CASE WHEN sa.status = 'In Progress' THEN sa.activityId END) AS inProgressActivities,
|
|
COUNT(DISTINCT CASE WHEN sa.status = 'Scheduled' THEN sa.activityId END) AS scheduledForFuture
|
|
FROM cdm.Resource r
|
|
LEFT JOIN cdm.[User] u ON r.userId = u.userId
|
|
LEFT JOIN cdm.ServiceActivity sa ON u.userId = sa.ownerUserId
|
|
AND sa.startTime >= DATEADD(DAY, -@Days, GETUTCDATE())
|
|
AND sa.isActive = 1
|
|
WHERE r.resourceType = 'User' AND r.isActive = 1
|
|
GROUP BY r.resourceId, r.resourceName, r.resourceType
|
|
ORDER BY totalMinutesScheduled DESC;
|
|
END;
|
|
|
|
PRINT 'Procedure sp_ResourceUtilizationReport created.';
|
|
GO
|
|
|
|
-- 20. Knowledge Article Effectiveness
|
|
CREATE OR ALTER PROCEDURE sp_KnowledgeArticleEffectiveness
|
|
AS
|
|
BEGIN
|
|
SELECT
|
|
TOP 20
|
|
ka.articleId,
|
|
ka.title,
|
|
ka.category,
|
|
ka.viewCount,
|
|
COUNT(DISTINCT kai.caseId) AS linkedToCases,
|
|
COUNT(DISTINCT CASE WHEN kai.isResolved = 1 THEN kai.caseId END) AS helpedResolve,
|
|
CASE
|
|
WHEN COUNT(DISTINCT kai.caseId) > 0
|
|
THEN CAST(COUNT(DISTINCT CASE WHEN kai.isResolved = 1 THEN kai.caseId END) * 100.0 / COUNT(DISTINCT kai.caseId) AS DECIMAL(5,2))
|
|
ELSE 0
|
|
END AS resolutionRate,
|
|
ka.publishedDate
|
|
FROM cdm.KnowledgeArticle ka
|
|
LEFT JOIN cdm.KnowledgeArticleIncident kai ON ka.articleId = kai.articleId
|
|
WHERE ka.status = 'Published' AND ka.isActive = 1
|
|
GROUP BY ka.articleId, ka.title, ka.category, ka.viewCount, ka.publishedDate
|
|
ORDER BY ka.viewCount DESC;
|
|
END;
|
|
|
|
PRINT 'Procedure sp_KnowledgeArticleEffectiveness created.';
|
|
GO
|
|
|
|
-- ============================================================================
|
|
-- SUMMARY
|
|
-- ============================================================================
|
|
|
|
PRINT '';
|
|
PRINT '========================================';
|
|
PRINT 'Reporting & Administrative Tools Installed Successfully!';
|
|
PRINT '========================================';
|
|
PRINT '';
|
|
PRINT 'Views Created: 4';
|
|
PRINT ' - v_ExecutiveDashboard';
|
|
PRINT ' - v_CasePerformanceMetrics';
|
|
PRINT ' - v_AgentPerformance';
|
|
PRINT ' - v_ContractUtilizationDashboard';
|
|
PRINT '';
|
|
PRINT 'Procedures Created: 16';
|
|
PRINT ' Analytics:';
|
|
PRINT ' - sp_CaseVolumeByPriority';
|
|
PRINT ' - sp_CustomerSatisfactionAnalysis';
|
|
PRINT ' - sp_SLAComplianceReport';
|
|
PRINT ' - sp_ServiceActivitySchedule';
|
|
PRINT ' - sp_MonthlyActivityReport';
|
|
PRINT ' - sp_CustomerRevenueAnalysis';
|
|
PRINT ' - sp_ResourceUtilizationReport';
|
|
PRINT ' - sp_KnowledgeArticleEffectiveness';
|
|
PRINT '';
|
|
PRINT ' Administration:';
|
|
PRINT ' - sp_CloseResolvedCases';
|
|
PRINT ' - sp_ArchiveOldCases';
|
|
PRINT ' - sp_DeactivateExpiredContracts';
|
|
PRINT ' - sp_UpdateEntitlementStatus';
|
|
PRINT ' - sp_ContractRenewalAlerts';
|
|
PRINT ' - sp_UpdateCaseOverdueStatus';
|
|
PRINT '';
|
|
PRINT ' Data Quality:';
|
|
PRINT ' - sp_CasesWithMissingData';
|
|
PRINT ' - sp_FindOrphanedRecords';
|
|
PRINT '';
|
|
PRINT 'Quick Start:';
|
|
PRINT ' SELECT * FROM cdm.v_ExecutiveDashboard';
|
|
PRINT ' SELECT * FROM cdm.v_AgentPerformance';
|
|
PRINT ' SELECT * FROM cdm.v_ContractUtilizationDashboard';
|
|
PRINT ' EXEC sp_CaseVolumeByPriority @Days = 90';
|
|
PRINT ' EXEC sp_CustomerSatisfactionAnalysis @Months = 6';
|
|
PRINT ' EXEC sp_SLAComplianceReport';
|
|
PRINT '';
|
|
PRINT '========================================';
|
|
|
|
GO
|