Add VoiceNotes firmware and CDM customer service SQL project
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>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
ef38a502d8
commit
3b371cdb28
@@ -0,0 +1,559 @@
|
||||
-- Microsoft Common Data Model - Customer Service
|
||||
-- Reporting and Administrative Queries
|
||||
-- Version: 1.0
|
||||
|
||||
USE CDM_CustomerService;
|
||||
GO
|
||||
|
||||
-- ============================================================================
|
||||
-- DASHBOARD & KPI QUERIES
|
||||
-- ============================================================================
|
||||
|
||||
-- 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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
GO
|
||||
|
||||
-- ============================================================================
|
||||
-- ANALYTICAL QUERIES
|
||||
-- ============================================================================
|
||||
|
||||
-- 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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
GO
|
||||
|
||||
-- ============================================================================
|
||||
-- ADMINISTRATIVE PROCEDURES
|
||||
-- ============================================================================
|
||||
|
||||
-- 9. Close Resolved Cases
|
||||
CREATE OR ALTER PROCEDURE sp_CloseResolvedCases
|
||||
@DaysOld INT = 7,
|
||||
@UserIdClosing UNIQUEIDENTIFIER
|
||||
AS
|
||||
BEGIN
|
||||
UPDATE cdm.Case
|
||||
SET status = 'Closed',
|
||||
closedDate = GETUTCDATE(),
|
||||
modifiedBy = @UserIdClosing,
|
||||
modifiedOn = GETUTCDATE()
|
||||
WHERE status = 'Resolved'
|
||||
AND resolvedDate <= DATEADD(DAY, -@DaysOld, CAST(GETUTCDATE() AS DATE))
|
||||
AND isActive = 1;
|
||||
|
||||
RETURN @@ROWCOUNT;
|
||||
END;
|
||||
|
||||
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;
|
||||
|
||||
RETURN @@ROWCOUNT;
|
||||
END;
|
||||
|
||||
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;
|
||||
|
||||
RETURN @@ROWCOUNT;
|
||||
END;
|
||||
|
||||
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;
|
||||
|
||||
RETURN @@ROWCOUNT;
|
||||
END;
|
||||
|
||||
GO
|
||||
|
||||
-- 13. Update Case Overdue Status
|
||||
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;
|
||||
|
||||
GO
|
||||
|
||||
-- 14. Generate 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;
|
||||
|
||||
GO
|
||||
|
||||
-- ============================================================================
|
||||
-- DATA QUALITY QUERIES
|
||||
-- ============================================================================
|
||||
|
||||
-- 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;
|
||||
|
||||
GO
|
||||
|
||||
-- 16. Orphaned Records
|
||||
CREATE OR ALTER PROCEDURE sp_FindOrphanedRecords
|
||||
AS
|
||||
BEGIN
|
||||
-- Orphaned Service Activities (Case not found)
|
||||
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
|
||||
|
||||
-- Orphaned Tasks (Case not found)
|
||||
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
|
||||
|
||||
-- Orphaned ContractLines (Contract not found)
|
||||
SELECT 'Orphaned ContractLine', COUNT(*)
|
||||
FROM cdm.ContractLine cl
|
||||
WHERE NOT EXISTS (SELECT 1 FROM cdm.Contract c WHERE c.contractId = cl.contractId);
|
||||
END;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
GO
|
||||
|
||||
-- ============================================================================
|
||||
-- USAGE EXAMPLES
|
||||
-- ============================================================================
|
||||
|
||||
/*
|
||||
|
||||
-- Execute Executive Dashboard View
|
||||
SELECT * FROM cdm.v_ExecutiveDashboard;
|
||||
|
||||
-- Get Agent Performance
|
||||
SELECT * FROM cdm.v_AgentPerformance
|
||||
ORDER BY closedCases DESC;
|
||||
|
||||
-- Get Contract Utilization
|
||||
SELECT * FROM cdm.v_ContractUtilizationDashboard
|
||||
WHERE utilizationStatus != 'NORMAL';
|
||||
|
||||
-- Case Volume Analysis
|
||||
EXEC sp_CaseVolumeByPriority @Days = 90;
|
||||
|
||||
-- Customer Satisfaction Analysis
|
||||
EXEC sp_CustomerSatisfactionAnalysis @Months = 6;
|
||||
|
||||
-- SLA Compliance Report
|
||||
EXEC sp_SLAComplianceReport;
|
||||
|
||||
-- Service Activity Schedule
|
||||
EXEC sp_ServiceActivitySchedule @Days = 7;
|
||||
|
||||
-- Overdue Cases (> 30 days)
|
||||
EXEC sp_UpdateCaseOverdueStatus @ThresholdDays = 30;
|
||||
|
||||
-- Contract Renewal Alerts (within 30 days)
|
||||
EXEC sp_ContractRenewalAlerts @DaysUntilExpiry = 30;
|
||||
|
||||
-- Data Quality Issues
|
||||
EXEC sp_CasesWithMissingData;
|
||||
|
||||
-- Monthly Activity Report
|
||||
EXEC sp_MonthlyActivityReport @Year = 2024, @Month = 9;
|
||||
|
||||
-- Top Revenue Customers
|
||||
EXEC sp_CustomerRevenueAnalysis;
|
||||
|
||||
-- Resource Utilization
|
||||
EXEC sp_ResourceUtilizationReport @Days = 30;
|
||||
|
||||
-- Knowledge Article Effectiveness
|
||||
EXEC sp_KnowledgeArticleEffectiveness;
|
||||
|
||||
*/
|
||||
|
||||
PRINT 'All reporting and administrative procedures created successfully!';
|
||||
|
||||
Reference in New Issue
Block a user