-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSummary.gs
More file actions
129 lines (115 loc) · 4.17 KB
/
Copy pathSummary.gs
File metadata and controls
129 lines (115 loc) · 4.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
* Aggregation script: updates a "Summary" sheet with total AM, PM, and hours per student.
* Uses menu trigger for easy access and is parameterizable for testing.
*/
/**
* Main: Reads NAME and SCHOOL from a summary sheet, computes totals from each SCHOOL sheet,
* and writes back TOTAL_AM_MINUTES, TOTAL_PM_MINUTES, TOTAL_HOURS in columns C, D, E.
* @param {string=} summarySheetName Optional name of summary sheet; defaults to SUMMARY_SHEET
*/
function updateSummaryTotals(summarySheetName = SUMMARY_SHEET) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const summary = ss.getSheetByName(summarySheetName);
if (!summary) throw new Error(`Sheet '${summarySheetName}' not found.`);
const lastRow = summary.getLastRow();
if (lastRow < 2) return;
// Read NAME (col A) and SCHOOL (col B)
const entries = summary.getRange(2, 1, lastRow - 1, 2).getValues();
entries.forEach((row, i) => {
const [studentName, schoolName] = row;
const sourceSheet = ss.getSheetByName(schoolName);
if (!sourceSheet) {
// highlight school cell if sheet missing
summary.getRange(i + 2, 2).setBackground("red");
return;
}
// compute totals for this student
const { amTotal, pmTotal, hrsTotal } = getStudentTotalsInSheet(
sourceSheet,
studentName
);
// Write into columns C, D, E
const targetRow = i + 2;
summary.getRange(targetRow, 3).setValue(amTotal);
summary.getRange(targetRow, 4).setValue(pmTotal);
summary.getRange(targetRow, 5).setValue(hrsTotal);
// Clear any previous highlight
summary.getRange(targetRow, 2).setBackground(null);
});
}
/**
* Compute sum of AM_MINUTES, PM_MINUTES, TOTAL_HRS for a specific student in a sheet.
* @param {Sheet} sheet Source sheet with data columns: NAME (col A), AM_MINUTES (G), PM_MINUTES (H), TOTAL_HRS (I)
* @param {string} studentName
* @return {{amTotal: number, pmTotal: number, hrsTotal: number}}
*/
function getStudentTotalsInSheet(sheet, studentName) {
const lastRow = sheet.getLastRow();
if (lastRow < 2) return { amTotal: 0, pmTotal: 0, hrsTotal: 0 };
// Read NAME col A, AM_MINUTES col G, PM_MINUTES col H, TOTAL_HRS col I
const data = sheet.getRange(2, 1, lastRow - 1, 9).getValues();
return data.reduce(
(acc, row) => {
if (row[0] === studentName) {
acc.amTotal += Number(row[6]) || 0;
acc.pmTotal += Number(row[7]) || 0;
acc.hrsTotal += Number(row[8]) || 0;
}
return acc;
},
{ amTotal: 0, pmTotal: 0, hrsTotal: 0 }
);
}
/**
* Test function to verify aggregation logic.
* Creates temporary sheets, populates sample data, runs updateSummaryTotals on testSummary,
* and logs the summary results for manual verification.
*/
function testAggregation() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
// Setup TestSource sheet
const testSourceName = "TestSource";
let testSource = ss.getSheetByName(testSourceName);
if (testSource) ss.deleteSheet(testSource);
testSource = ss.insertSheet(testSourceName);
testSource
.getRange(1, 1, 1, 9)
.setValues([
[
"NAME",
"DATE",
"TIME_IN_AM",
"TIME_OUT_AM",
"TIME_IN_PM",
"TIME_OUT_PM",
"AM_MINUTES",
"PM_MINUTES",
"TOTAL_HRS",
],
]);
testSource.getRange(2, 1, 3, 9).setValues([
["Alice", "", "", "", "", "", 60, 120, 3],
["Bob", "", "", "", "", "", 30, 60, 1.5],
["Alice", "", "", "", "", "", 90, 30, 2],
]);
// Setup TestSummary sheet
const testSummaryName = "TestSummary";
let testSummary = ss.getSheetByName(testSummaryName);
if (testSummary) ss.deleteSheet(testSummary);
testSummary = ss.insertSheet(testSummaryName);
testSummary
.getRange(1, 1, 1, 5)
.setValues([
["NAME", "SCHOOL", "TOTAL_AM_MINUTES", "TOTAL_PM_MINUTES", "TOTAL_HOURS"],
]);
testSummary.getRange(2, 1, 2, 2).setValues([
["Alice", testSourceName],
["Bob", testSourceName],
]);
// Run aggregation on TestSummary
updateSummaryTotals(testSummaryName);
// Read and log results (columns A-E)
const resultRows = testSummary.getRange(2, 1, 2, 5).getValues();
Logger.log("Aggregation Test Results:");
resultRows.forEach((row) => Logger.log(row));
}