scheduler-node-models 1.1.37 → 1.1.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/package.json +6 -6
  2. package/general/emailer.d.ts +0 -1
  3. package/general/emailer.js +0 -31
  4. package/general/general.d.ts +0 -12
  5. package/general/general.js +0 -2
  6. package/general/index.d.ts +0 -5
  7. package/general/index.js +0 -21
  8. package/general/logger.d.ts +0 -10
  9. package/general/logger.js +0 -90
  10. package/general/report.d.ts +0 -25
  11. package/general/report.js +0 -76
  12. package/general/reportStyle.d.ts +0 -0
  13. package/general/reportStyle.js +0 -1
  14. package/general/viewstate.d.ts +0 -5
  15. package/general/viewstate.js +0 -9
  16. package/index.d.ts +0 -0
  17. package/index.js +0 -1
  18. package/metrics/images.d.ts +0 -22
  19. package/metrics/images.js +0 -33
  20. package/metrics/index.d.ts +0 -5
  21. package/metrics/index.js +0 -21
  22. package/metrics/mission.d.ts +0 -47
  23. package/metrics/mission.js +0 -81
  24. package/metrics/missionSensorOutage.d.ts +0 -11
  25. package/metrics/missionSensorOutage.js +0 -14
  26. package/metrics/missionsensor.d.ts +0 -67
  27. package/metrics/missionsensor.js +0 -128
  28. package/metrics/outage.d.ts +0 -43
  29. package/metrics/outage.js +0 -55
  30. package/metrics/reports/drawSummary.d.ts +0 -24
  31. package/metrics/reports/drawSummary.js +0 -311
  32. package/metrics/reports/index.d.ts +0 -5
  33. package/metrics/reports/index.js +0 -21
  34. package/metrics/reports/missionDay.d.ts +0 -8
  35. package/metrics/reports/missionDay.js +0 -23
  36. package/metrics/reports/missionSummary.d.ts +0 -25
  37. package/metrics/reports/missionSummary.js +0 -421
  38. package/metrics/reports/missionType.d.ts +0 -20
  39. package/metrics/reports/missionType.js +0 -314
  40. package/metrics/reports/outageDay.d.ts +0 -8
  41. package/metrics/reports/outageDay.js +0 -23
  42. package/metrics/systemdata/classifications.d.ts +0 -18
  43. package/metrics/systemdata/classifications.js +0 -23
  44. package/metrics/systemdata/communications.d.ts +0 -21
  45. package/metrics/systemdata/communications.js +0 -40
  46. package/metrics/systemdata/dcgs.d.ts +0 -19
  47. package/metrics/systemdata/dcgs.js +0 -29
  48. package/metrics/systemdata/exploitations.d.ts +0 -18
  49. package/metrics/systemdata/exploitations.js +0 -23
  50. package/metrics/systemdata/groundSystems.d.ts +0 -86
  51. package/metrics/systemdata/groundSystems.js +0 -143
  52. package/metrics/systemdata/index.d.ts +0 -7
  53. package/metrics/systemdata/index.js +0 -23
  54. package/metrics/systemdata/platform.d.ts +0 -124
  55. package/metrics/systemdata/platform.js +0 -176
  56. package/metrics/systemdata/systeminfo.d.ts +0 -28
  57. package/metrics/systemdata/systeminfo.js +0 -64
  58. package/scheduler/employees/assignment.d.ts +0 -139
  59. package/scheduler/employees/assignment.js +0 -304
  60. package/scheduler/employees/balance.d.ts +0 -35
  61. package/scheduler/employees/balance.js +0 -39
  62. package/scheduler/employees/companyinfo.d.ts +0 -16
  63. package/scheduler/employees/companyinfo.js +0 -6
  64. package/scheduler/employees/contact.d.ts +0 -36
  65. package/scheduler/employees/contact.js +0 -40
  66. package/scheduler/employees/employee.d.ts +0 -427
  67. package/scheduler/employees/employee.js +0 -1887
  68. package/scheduler/employees/employeename.d.ts +0 -48
  69. package/scheduler/employees/employeename.js +0 -97
  70. package/scheduler/employees/index.d.ts +0 -14
  71. package/scheduler/employees/index.js +0 -30
  72. package/scheduler/employees/labor.d.ts +0 -31
  73. package/scheduler/employees/labor.js +0 -39
  74. package/scheduler/employees/leave.d.ts +0 -58
  75. package/scheduler/employees/leave.js +0 -73
  76. package/scheduler/employees/leaverequest.d.ts +0 -105
  77. package/scheduler/employees/leaverequest.js +0 -226
  78. package/scheduler/employees/specialty.d.ts +0 -35
  79. package/scheduler/employees/specialty.js +0 -40
  80. package/scheduler/employees/variation.d.ts +0 -80
  81. package/scheduler/employees/variation.js +0 -132
  82. package/scheduler/employees/web.d.ts +0 -6
  83. package/scheduler/employees/web.js +0 -2
  84. package/scheduler/employees/work.d.ts +0 -96
  85. package/scheduler/employees/work.js +0 -133
  86. package/scheduler/employees/workday.d.ts +0 -91
  87. package/scheduler/employees/workday.js +0 -170
  88. package/scheduler/labor/index.d.ts +0 -2
  89. package/scheduler/labor/index.js +0 -18
  90. package/scheduler/labor/laborcode.d.ts +0 -33
  91. package/scheduler/labor/laborcode.js +0 -55
  92. package/scheduler/labor/workcode.d.ts +0 -28
  93. package/scheduler/labor/workcode.js +0 -35
  94. package/scheduler/reports/chargeStatus.d.ts +0 -66
  95. package/scheduler/reports/chargeStatus.js +0 -752
  96. package/scheduler/reports/cofsReports.d.ts +0 -11
  97. package/scheduler/reports/cofsReports.js +0 -36
  98. package/scheduler/reports/enterpriseSchedule.d.ts +0 -18
  99. package/scheduler/reports/enterpriseSchedule.js +0 -159
  100. package/scheduler/reports/index.d.ts +0 -6
  101. package/scheduler/reports/index.js +0 -22
  102. package/scheduler/reports/leaveReport.d.ts +0 -52
  103. package/scheduler/reports/leaveReport.js +0 -755
  104. package/scheduler/reports/leaves.d.ts +0 -24
  105. package/scheduler/reports/leaves.js +0 -110
  106. package/scheduler/reports/scheduleReport.d.ts +0 -17
  107. package/scheduler/reports/scheduleReport.js +0 -311
  108. package/scheduler/sites/index.d.ts +0 -1
  109. package/scheduler/sites/index.js +0 -17
  110. package/scheduler/sites/reports/cofsReport.d.ts +0 -41
  111. package/scheduler/sites/reports/cofsReport.js +0 -104
  112. package/scheduler/sites/reports/forecast.d.ts +0 -57
  113. package/scheduler/sites/reports/forecast.js +0 -205
  114. package/scheduler/sites/reports/index.d.ts +0 -4
  115. package/scheduler/sites/reports/index.js +0 -20
  116. package/scheduler/sites/reports/period.d.ts +0 -11
  117. package/scheduler/sites/reports/period.js +0 -27
  118. package/scheduler/sites/reports/section.d.ts +0 -63
  119. package/scheduler/sites/reports/section.js +0 -186
  120. package/scheduler/sites/site.d.ts +0 -39
  121. package/scheduler/sites/site.js +0 -68
  122. package/scheduler/sites/workcenters/index.d.ts +0 -3
  123. package/scheduler/sites/workcenters/index.js +0 -19
  124. package/scheduler/sites/workcenters/position.d.ts +0 -27
  125. package/scheduler/sites/workcenters/position.js +0 -36
  126. package/scheduler/sites/workcenters/shift.d.ts +0 -32
  127. package/scheduler/sites/workcenters/shift.js +0 -47
  128. package/scheduler/sites/workcenters/workcenter.d.ts +0 -43
  129. package/scheduler/sites/workcenters/workcenter.js +0 -123
  130. package/scheduler/teams/company/company.d.ts +0 -99
  131. package/scheduler/teams/company/company.js +0 -256
  132. package/scheduler/teams/company/holiday.d.ts +0 -61
  133. package/scheduler/teams/company/holiday.js +0 -116
  134. package/scheduler/teams/company/index.d.ts +0 -3
  135. package/scheduler/teams/company/index.js +0 -19
  136. package/scheduler/teams/company/modperiod.d.ts +0 -21
  137. package/scheduler/teams/company/modperiod.js +0 -24
  138. package/scheduler/teams/contact.d.ts +0 -18
  139. package/scheduler/teams/contact.js +0 -23
  140. package/scheduler/teams/index.d.ts +0 -3
  141. package/scheduler/teams/index.js +0 -19
  142. package/scheduler/teams/specialty.d.ts +0 -18
  143. package/scheduler/teams/specialty.js +0 -23
  144. package/scheduler/teams/team.d.ts +0 -95
  145. package/scheduler/teams/team.js +0 -351
  146. package/users/index.d.ts +0 -2
  147. package/users/index.js +0 -18
  148. package/users/user.d.ts +0 -130
  149. package/users/user.js +0 -256
  150. package/users/web.d.ts +0 -48
  151. package/users/web.js +0 -2
@@ -1,752 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ChargeStatusReport = void 0;
4
- const exceljs_1 = require("exceljs");
5
- const general_1 = require("../../general");
6
- const sites_1 = require("../sites");
7
- const labor_1 = require("../labor");
8
- const employees_1 = require("../employees");
9
- class ChargeStatusReport extends general_1.Report {
10
- site;
11
- workcodes;
12
- lastWorked;
13
- fonts;
14
- fills;
15
- borders;
16
- alignments;
17
- numformats;
18
- constructor(isite, workcodes) {
19
- super();
20
- this.site = new sites_1.Site(isite);
21
- this.workcodes = new Map();
22
- workcodes.forEach(wc => {
23
- const wCode = new labor_1.Workcode(wc);
24
- this.workcodes.set(wCode.id, wCode);
25
- });
26
- this.lastWorked = new Date(0);
27
- this.fonts = new Map();
28
- this.fills = new Map();
29
- this.borders = new Map();
30
- this.alignments = new Map();
31
- this.numformats = new Map();
32
- }
33
- create(user, iEmps, companyID, reqDate) {
34
- const workbook = new exceljs_1.Workbook();
35
- workbook.creator = user.getFullName();
36
- workbook.created = new Date();
37
- // determine the lastworked date for the report
38
- const employees = [];
39
- this.lastWorked = new Date(0);
40
- iEmps.forEach(iEmp => {
41
- const emp = new employees_1.Employee(iEmp);
42
- const last = emp.getLastWorkday();
43
- if (emp.companyinfo.company.toLowerCase() === companyID
44
- && emp.isActive(reqDate)) {
45
- if (last.getTime() > this.lastWorked.getTime()) {
46
- this.lastWorked = new Date(last);
47
- }
48
- }
49
- employees.push(emp);
50
- });
51
- employees.sort((a, b) => a.compareTo(b));
52
- this.createStyles();
53
- // create the statistics sheet first, so the other sheets can feed it data
54
- const stats = this.createStatisticsSheet(workbook);
55
- let statsRow = 3;
56
- // step through the forecast reports, to see if valid, create current and forecast
57
- // sheets.
58
- this.site.forecasts.forEach(rpt => {
59
- if (rpt.use(reqDate, companyID)) {
60
- let row = this.addReport(workbook, 'Current', rpt, employees, stats, statsRow);
61
- if (row) {
62
- statsRow = row;
63
- }
64
- row = this.addReport(workbook, 'Forecast', rpt, employees, stats, statsRow);
65
- if (row) {
66
- statsRow = row;
67
- }
68
- }
69
- });
70
- return workbook;
71
- }
72
- /**
73
- * This function will create the basic style information to be used within the sheet
74
- * cells, which consists for font styles, cell fill styles, borders, and alignments for
75
- * the text within the cell. Plus a late addition of the various number formats to
76
- * present.
77
- */
78
- createStyles() {
79
- // set fonts
80
- this.fonts.set("bold18", { bold: true, size: 14, color: { argb: 'ff000000' } });
81
- this.fonts.set("bold14", { bold: true, size: 14, color: { argb: 'ff000000' } });
82
- this.fonts.set("bold12", { bold: true, size: 12, color: { argb: 'ff000000' } });
83
- this.fonts.set("white12", { bold: false, size: 12, color: { argb: 'ffffffff' } });
84
- this.fonts.set("blue12", { bold: true, size: 12, color: { argb: 'ff0000ff' } });
85
- this.fonts.set("nobold9", { bold: false, size: 9, color: { argb: 'ff000000' } });
86
- this.fonts.set('notnorm', { bold: false, size: 9, color: { argb: 'ff0070c0' } });
87
- // set fills
88
- this.fills.set('black', { type: 'pattern', pattern: 'solid', fgColor: { argb: 'ff000000' } });
89
- this.fills.set('white', { type: 'pattern', pattern: 'solid', fgColor: { argb: 'ffffffff' } });
90
- this.fills.set('blue', { type: 'pattern', pattern: 'solid', fgColor: { argb: 'ff99ccff' } });
91
- this.fills.set('ltblue', { type: 'pattern', pattern: 'solid', fgColor: { argb: 'ffccffff' } });
92
- this.fills.set('green', { type: 'pattern', pattern: 'solid', fgColor: { argb: 'ff99cc00' } });
93
- this.fills.set('ltgreen', { type: 'pattern', pattern: 'solid', fgColor: { argb: 'ffccffcc' } });
94
- this.fills.set('dkblush', { type: 'pattern', pattern: 'solid', fgColor: { argb: 'ffda9694' } });
95
- this.fills.set('yellow', { type: 'pattern', pattern: 'solid', fgColor: { argb: 'ffffff00' } });
96
- this.fills.set('ltbrown', { type: 'pattern', pattern: 'solid', fgColor: { argb: 'fffcd5b4' } });
97
- this.fills.set('gray', { type: 'pattern', pattern: 'solid', fgColor: { argb: 'ffc0c0c0' } });
98
- this.fills.set('ltgray', { type: 'pattern', pattern: 'solid', fgColor: { argb: 'ffbfbfbf' } });
99
- // set borders
100
- this.borders.set('blackthin', {
101
- top: { style: 'thin', color: { argb: 'ff000000' } },
102
- left: { style: 'thin', color: { argb: 'ff000000' } },
103
- bottom: { style: 'thin', color: { argb: 'ff000000' } },
104
- right: { style: 'thin', color: { argb: 'ff000000' } }
105
- });
106
- this.borders.set('blacktotal', {
107
- top: { style: 'thick', color: { argb: 'ff000000' } },
108
- left: { style: 'thin', color: { argb: 'ff000000' } },
109
- bottom: { style: 'thick', color: { argb: 'ff000000' } },
110
- right: { style: 'thin', color: { argb: 'ff000000' } }
111
- });
112
- this.borders.set('blackthinNoRight', {
113
- top: { style: 'thin', color: { argb: 'ff000000' } },
114
- left: { style: 'thin', color: { argb: 'ff000000' } },
115
- bottom: { style: 'thin', color: { argb: 'ff000000' } },
116
- right: { style: 'thin', color: { argb: 'ffffffff' } }
117
- });
118
- this.borders.set('blackthinNoLeft', {
119
- top: { style: 'thin', color: { argb: 'ff000000' } },
120
- left: { style: 'thin', color: { argb: 'ffffffff' } },
121
- bottom: { style: 'thin', color: { argb: 'ff000000' } },
122
- right: { style: 'thin', color: { argb: 'ff000000' } }
123
- });
124
- // set alignments
125
- this.alignments.set('center', { horizontal: 'center', vertical: 'middle', wrapText: true });
126
- this.alignments.set('leftctr', { horizontal: 'left', vertical: 'middle', wrapText: true });
127
- this.alignments.set('rightctr', { horizontal: 'right', vertical: 'middle', wrapText: true });
128
- this.alignments.set('centerslant', { horizontal: 'center', vertical: 'middle',
129
- wrapText: false, textRotation: 45 });
130
- // set number formats
131
- this.numformats.set('sum', '##0.0;[Red]##0.0;-;@');
132
- this.numformats.set('monthsum', '_(* #,##0.0_);_(* (#,##0.0);_(* \"-\"??_);_(@_)');
133
- this.numformats.set('pct', '##0.0%;[Red]##0.0%;-;@');
134
- }
135
- /**
136
- * This function will create the various pages of the workbook which hold the actual
137
- * data for the workbook. They will consist of a header section, then list the
138
- * employee's work/forecast work hours by labor code. lastly, if the stats worksheet
139
- * is provided, it will add the statistics formulas to the rows of data on this sheet,
140
- * by report type (current or forecast);
141
- * @param workbook A reference to the workbook object so worksheet creation is possible
142
- * @param type A string value to indicate if the report is for current or forecast data
143
- * @param report The forecast object used to define the period and labor codes for use
144
- * @param employees The list of site employees used for the report.
145
- * @param stats A reference to the statistics worksheet to allow this to add the
146
- * correct formulas to it.
147
- * @param statsRow The numeric value for the last row used in the statistics worksheet.
148
- * @return The numeric value for the last row used in the statistics worksheet.
149
- */
150
- addReport(workbook, type, report, employees, stats, statsRow) {
151
- const current = (type.toLowerCase() === 'current');
152
- const sheetLabel = `${report.name}_${type}`;
153
- // add a worksheet to the workbook and set the page options (landscape, etc)
154
- const sheet = workbook.addWorksheet(sheetLabel, {
155
- pageSetup: {
156
- paperSize: undefined,
157
- orientation: 'landscape',
158
- fitToHeight: 1,
159
- fitToWidth: 1,
160
- blackAndWhite: false,
161
- fitToPage: true,
162
- showGridLines: false,
163
- horizontalCentered: true,
164
- verticalCentered: true
165
- },
166
- properties: {
167
- defaultRowHeight: 20,
168
- defaultColWidth: 4,
169
- outlineLevelCol: 0
170
- },
171
- views: [{
172
- state: 'frozen',
173
- xSplit: 7
174
- }]
175
- });
176
- // set column widths
177
- const widths = [8, 10.57, 9, 14.57, 10.57, 20, 18.14, 17.57, 14.57, 14.57, 14.57, 55.14];
178
- const hidden = [true, true, true, true, true, false, false, true, true, true, true, true];
179
- const months = ['January', 'Febuary', 'March', 'April', 'May', 'June', 'July',
180
- 'August', 'September', 'October', 'November', 'December'];
181
- widths.forEach((width, w) => {
182
- sheet.getColumn(w + 1).width = width;
183
- sheet.getColumn(w + 1).hidden = hidden[w];
184
- });
185
- let columns = 12;
186
- report.periods.forEach(period => {
187
- const sumCol = columns + 1;
188
- const startCol = columns + 2;
189
- const endCol = startCol + (period.periods.length - 1);
190
- sheet.getColumn(sumCol).width = 12;
191
- sheet.getColumn(sumCol).outlineLevel = 0;
192
- for (let i = startCol; i <= endCol; i++) {
193
- sheet.getColumn(i).width = 9;
194
- sheet.getColumn(i).outlineLevel = 1;
195
- }
196
- columns = endCol;
197
- });
198
- sheet.getColumn(columns + 1).width = 15.43;
199
- sheet.getColumn(columns + 1).outlineLevel = 0;
200
- // add page's headers
201
- let style = {
202
- fill: this.fills.get('white'),
203
- font: this.fonts.get("bold18"),
204
- alignment: this.alignments.get("leftctr"),
205
- border: this.borders.get("blackthin")
206
- };
207
- this.setCell(sheet, "A1", "G1", style, `FFP Labor: CLIN ${report.laborCodes[0].clin}`
208
- + ` SUMMARY`);
209
- const formatter = new Intl.DateTimeFormat('en-US', {
210
- month: '2-digit',
211
- day: '2-digit',
212
- year: 'numeric'
213
- });
214
- this.setCell(sheet, "A2", "G2", style, `${report.name} Year - `
215
- + `${formatter.format(report.startDate)} - ${formatter.format(report.endDate)}`);
216
- style.font = this.fonts.get('bold14');
217
- this.setCell(sheet, "L1", "L1", style, "Weeks Per Accounting Month");
218
- this.setCell(sheet, "L2", "L2", style, "Accounting Month");
219
- this.setCell(sheet, "L3", "L3", style, "Week Ending");
220
- // Set headers for the employee information columns
221
- style = {
222
- fill: this.fills.get('black'),
223
- font: this.fonts.get('white12'),
224
- alignment: this.alignments.get('center'),
225
- border: this.borders.get('blackthin')
226
- };
227
- this.setCell(sheet, "A4", "A4", style, "CLIN");
228
- this.setCell(sheet, "B4", "B4", style, "SLIN");
229
- this.setCell(sheet, "C4", "C4", style, "Company");
230
- this.setCell(sheet, "D4", "D4", style, "Location");
231
- this.setCell(sheet, "E4", "E4", style, "WBS");
232
- this.setCell(sheet, "F4", "F4", style, "Labor NWA");
233
- this.setCell(sheet, "G4", "G4", style, "Last Name");
234
- this.setCell(sheet, "H4", "H4", style, "Labor Category");
235
- this.setCell(sheet, "I4", "I4", style, "Employee ID");
236
- this.setCell(sheet, "J4", "J4", style, "PeopleSoft ID");
237
- this.setCell(sheet, "K4", "K4", style, "Cost Center");
238
- this.setCell(sheet, "L4", "L4", style, "Comments/Remarks");
239
- // set headers for periods and sub-periods
240
- columns = 11;
241
- report.periods.forEach(period => {
242
- columns++;
243
- style = {
244
- fill: this.fills.get('white'),
245
- font: this.fonts.get('bold14'),
246
- alignment: this.alignments.get('center'),
247
- border: this.borders.get('blackthin')
248
- };
249
- this.setCell(sheet, this.getCellID(columns, 1), this.getCellID(columns, 1), style, period.periods.length);
250
- this.setCell(sheet, this.getCellID(columns, 2), this.getCellID(columns + period.periods.length, 2), style, months[period.month.getMonth()].toUpperCase());
251
- style.font = this.fonts.get('bold14');
252
- this.setCell(sheet, this.getCellID(columns, 3), this.getCellID(columns, 3), style, "Month Total");
253
- style = {
254
- fill: this.fills.get('dkblush'),
255
- font: this.fonts.get('bold12'),
256
- alignment: this.alignments.get('center'),
257
- border: this.borders.get('blackthin')
258
- };
259
- const dFormat = new Intl.DateTimeFormat('en-US', {
260
- month: 'short',
261
- day: '2-digit'
262
- });
263
- this.setCell(sheet, this.getCellID(columns, 4), this.getCellID(columns, 4), style, dFormat.format(period.month));
264
- const dtStyle = {
265
- fill: this.fills.get('white'),
266
- font: this.fonts.get('bold14'),
267
- alignment: this.alignments.get('center'),
268
- border: this.borders.get('blackthin')
269
- };
270
- const wkStyle = {
271
- fill: this.fills.get('yellow'),
272
- font: this.fonts.get('bold12'),
273
- alignment: this.alignments.get('center'),
274
- border: this.borders.get('blackthin')
275
- };
276
- period.periods.forEach((prd, p) => {
277
- let cellID = this.getCellID(columns + p + 1, 3);
278
- this.setCell(sheet, cellID, cellID, dtStyle, dFormat.format(prd));
279
- cellID = this.getCellID(columns + p + 1, 4);
280
- this.setCell(sheet, cellID, cellID, wkStyle, `Week ${p + 1}`);
281
- });
282
- columns += period.periods.length;
283
- });
284
- // Add a totals column header for the overall totals
285
- style = {
286
- fill: this.fills.get('white'),
287
- font: this.fonts.get('bold12'),
288
- alignment: this.alignments.get('center'),
289
- border: this.borders.get('blackthin')
290
- };
291
- let cellID = this.getCellID(columns + 1, 4);
292
- this.setCell(sheet, cellID, cellID, style, 'EAC');
293
- // create list of leave and work codes for comparison to determine working or
294
- // not working criteria
295
- let row = 4;
296
- let lastWorked = new Date(0);
297
- let column = 0;
298
- // this report is listed by labor code, then employees with hours
299
- report.laborCodes.forEach(lCode => {
300
- // step through the employees to see if they have hours for this labor code
301
- employees.forEach(emp => {
302
- if (emp.getLastWorkday().getTime() > lastWorked.getTime()) {
303
- lastWorked = new Date(emp.getLastWorkday());
304
- }
305
- });
306
- employees.forEach(emp => {
307
- // employee has used this labor code, if they have some actual or forecast hours.
308
- const actual = emp.getWorkedHours(report.startDate, report.endDate, lCode.chargeNumber, lCode.extension);
309
- const forecast = emp.getForecastHours(lCode, report.startDate, report.endDate, this.workcodes);
310
- if (actual > 0 || forecast > 0) {
311
- row++;
312
- const col = this.employeeRow(sheet, lCode, row, emp, report, current, this.workcodes, lastWorked);
313
- if (col > column) {
314
- column = col;
315
- }
316
- }
317
- });
318
- });
319
- // add totals row for each column on the sheet.
320
- column = 11;
321
- const sumRow = row + 1;
322
- let formula = '';
323
- report.periods.forEach(period => {
324
- style = {
325
- fill: this.fills.get('dkblush'),
326
- font: this.fonts.get('bold12'),
327
- alignment: this.alignments.get('center'),
328
- border: this.borders.get('blacktotal'),
329
- numFmt: this.numformats.get('monthsum')
330
- };
331
- column++;
332
- formula = `SUM(${this.getCellID(column, 5)}:${this.getCellID(column, row)})`;
333
- cellID = this.getCellID(column, sumRow);
334
- this.setCell(sheet, cellID, cellID, style, new general_1.Formula(formula));
335
- period.periods.forEach(prd => {
336
- column++;
337
- style = {
338
- fill: this.fills.get('ltgray'),
339
- font: this.fonts.get('bold12'),
340
- alignment: this.alignments.get('center'),
341
- border: this.borders.get('blacktotal'),
342
- numFmt: this.numformats.get('sum')
343
- };
344
- formula = `SUM(${this.getCellID(column, 5)}:${this.getCellID(column, row)})`;
345
- cellID = this.getCellID(column, sumRow);
346
- this.setCell(sheet, cellID, cellID, style, new general_1.Formula(formula));
347
- });
348
- });
349
- column++;
350
- style = {
351
- fill: this.fills.get('dkblush'),
352
- font: this.fonts.get('bold12'),
353
- alignment: this.alignments.get('center'),
354
- border: this.borders.get('blacktotal'),
355
- numFmt: this.numformats.get('monthsum')
356
- };
357
- formula = `SUM(${this.getCellID(column, 5)}:${this.getCellID(column, row)})`;
358
- cellID = this.getCellID(column, sumRow);
359
- this.setCell(sheet, cellID, cellID, style, new general_1.Formula(formula));
360
- if (stats && statsRow) {
361
- // this is used to create the dates in the statistics labor rows
362
- const dFormat = new Intl.DateTimeFormat('en-US', {
363
- month: '2-digit',
364
- day: '2-digit',
365
- year: 'numeric'
366
- });
367
- for (let l = 0; l < report.laborCodes.length; l++) {
368
- const lCode = report.laborCodes[l];
369
- const codeText = `${lCode.chargeNumber} ${lCode.extension}`;
370
- // determine the period to date total hours that should have been used based
371
- // upon an even spread of hours throughout the period.
372
- let codeHours = 0.0;
373
- let totalHours = 0.0;
374
- if (lCode.startDate && lCode.endDate) {
375
- const days = Math.ceil((lCode.endDate.getTime() - lCode.startDate.getTime())
376
- / (24 * 3600000));
377
- let daysToNow = 0.0;
378
- if (lastWorked.getTime() > lCode.startDate.getTime()) {
379
- daysToNow = Math.ceil((lastWorked.getTime() - lCode.startDate.getTime())
380
- / (24 * 3600000));
381
- }
382
- if (lCode.hoursPerEmployee && lCode.minimumEmployees) {
383
- totalHours = lCode.hoursPerEmployee * lCode.minimumEmployees;
384
- }
385
- let perDay = 0.0;
386
- if (daysToNow > 0) {
387
- perDay = totalHours / days;
388
- }
389
- codeHours = perDay * daysToNow;
390
- }
391
- let style = {
392
- fill: this.fills.get('white'),
393
- font: this.fonts.get('bold12'),
394
- alignment: this.alignments.get("center"),
395
- border: this.borders.get('blackthin')
396
- };
397
- if (current) {
398
- // this branch will add the labor codes and start and end dates, plus the
399
- // current formulas to the statistics worksheet. It will modify the statsRow
400
- // value to reflect each row used by labor code. Rows need to alternate fills,
401
- // so that rows are easier to delinate. Columns A to G.
402
- statsRow++;
403
- style.numFmt = undefined;
404
- const bLight = (statsRow % 2) === 0;
405
- // labor code, and dates cells first three columns
406
- if (bLight) {
407
- style.fill = this.fills.get('gray');
408
- }
409
- else {
410
- style.fill = this.fills.get('white');
411
- }
412
- this.setCell(stats, this.getCellID(0, statsRow), this.getCellID(0, statsRow), style, codeText);
413
- this.setCell(stats, this.getCellID(1, statsRow), this.getCellID(1, statsRow), style, dFormat.format(lCode.startDate));
414
- this.setCell(stats, this.getCellID(2, statsRow), this.getCellID(2, statsRow), style, dFormat.format(lCode.endDate));
415
- // next current information next four columns, hours to date, total worked
416
- // hours, +/- hours, percentage of hours to date.
417
- if (bLight) {
418
- style.fill = this.fills.get('blue');
419
- }
420
- else {
421
- style.fill = this.fills.get('ltblue');
422
- }
423
- style.numFmt = this.numformats.get('sum');
424
- this.setCell(stats, this.getCellID(3, statsRow), this.getCellID(3, statsRow), style, codeHours);
425
- let formula = `SUMIF(${sheetLabel}!${this.getCellID(5, 5)}:`
426
- + `${this.getCellID(5, row)}, "*${codeText}*", ${sheetLabel}!`
427
- + `${this.getCellID(column, 5)}:${this.getCellID(column, row)})`;
428
- this.setCell(stats, this.getCellID(4, statsRow), this.getCellID(4, statsRow), style, new general_1.Formula(formula));
429
- formula = `${this.getCellID(4, statsRow)} - ${this.getCellID(3, statsRow)}`;
430
- this.setCell(stats, this.getCellID(5, statsRow), this.getCellID(5, statsRow), style, new general_1.Formula(formula));
431
- formula = `IFERROR(${this.getCellID(4, statsRow)}/`
432
- + `${this.getCellID(3, statsRow)},"N/A")`;
433
- style.numFmt = this.numformats.get('pct');
434
- this.setCell(stats, this.getCellID(6, statsRow), this.getCellID(6, statsRow), style, new general_1.Formula(formula));
435
- }
436
- else {
437
- // this branch will add only the forecast data formulas to the statistics. It
438
- // will first find the correct row based on the labor code, then determine the
439
- // fill style to use, then add the formula. Columns H to K
440
- let srow = 0;
441
- for (let r = 3; r <= statsRow && srow === 0; r++) {
442
- const cell = stats.getCell(r, 1);
443
- if (cell.text.toLowerCase() === codeText.toLowerCase()) {
444
- srow = r;
445
- }
446
- }
447
- // row greater than zero means the labor code was found and
448
- if (srow > 0) {
449
- const bLight = (srow % 2) === 0;
450
- // forecast information next four columns, total hours, total forecasted
451
- // hours, +/- hours, percentage of hours to date.
452
- if (bLight) {
453
- style.fill = this.fills.get('green');
454
- }
455
- else {
456
- style.fill = this.fills.get('ltgreen');
457
- }
458
- style.numFmt = this.numformats.get('sum');
459
- this.setCell(stats, this.getCellID(7, srow), this.getCellID(7, srow), style, totalHours);
460
- let formula = `SUMIF(${sheetLabel}!${this.getCellID(5, 5)}:`
461
- + `${this.getCellID(5, row)}, "*${codeText}*", ${sheetLabel}!`
462
- + `${this.getCellID(column, 5)}:${this.getCellID(column, row)})`;
463
- this.setCell(stats, this.getCellID(8, srow), this.getCellID(8, srow), style, new general_1.Formula(formula));
464
- formula = `${this.getCellID(8, srow)} - ${this.getCellID(7, srow)}`;
465
- this.setCell(stats, this.getCellID(9, srow), this.getCellID(9, srow), style, new general_1.Formula(formula));
466
- style.numFmt = this.numformats.get('pct');
467
- const oformula = new general_1.Formula(`IFERROR(${this.getCellID(8, row)}/`
468
- + `${this.getCellID(7, row)},"N/A")`);
469
- this.setCell(stats, this.getCellID(10, srow), this.getCellID(10, srow), style, oformula);
470
- }
471
- }
472
- }
473
- }
474
- return statsRow;
475
- }
476
- /**
477
- * This function focuses on an employee, who has hours in the labor code provided. This
478
- * will create a row of data on the worksheet for this employee's work in this
479
- * category
480
- * @param sheet The reference to the worksheet to add a row of data to.
481
- * @param lCode The labor code object, which allows the work to focus on a single code.
482
- * @param row The numeric value for the worksheet row to use in filling in the data
483
- * @param emp The employee object to pull the work data.
484
- * @param report The forecast report object which provides the periods and other data
485
- * used in constructing the employee's row.
486
- * @param current The boolean value which signifies whether only actual work performed
487
- * or add in forecast work hours in this report sheet.
488
- * @param compare A map of workcode array, used to determine leaves and other non-work
489
- * periods.
490
- */
491
- employeeRow(sheet, lCode, row, emp, report, current, compare, lastWorked) {
492
- // create two style objects for filling in the employee's employment information as
493
- // pertains to the object
494
- let style = {
495
- fill: this.fills.get('white'),
496
- font: this.fonts.get('bold12'),
497
- alignment: this.alignments.get('center'),
498
- border: this.borders.get('blackthin'),
499
- numFmt: this.numformats.get('sum')
500
- };
501
- // lstyle is used for a section of the employee's information which highlights the
502
- // individual as working in a liaison capability.
503
- const lStyle = {
504
- fill: this.fills.get('white'),
505
- font: this.fonts.get('bold12'),
506
- alignment: this.alignments.get('leftctr'),
507
- border: this.borders.get('blackthin')
508
- };
509
- if (emp.companyinfo.jobtitle
510
- && emp.companyinfo.jobtitle?.toLowerCase().indexOf('liaison') >= 0) {
511
- style.fill = this.fills.get('ltbrown');
512
- lStyle.fill = this.fills.get('ltbrown');
513
- }
514
- sheet.getRow(row).height = 15;
515
- // this section sets the various required columns with information about the
516
- // employment in the labor code.
517
- this.setCell(sheet, this.getCellID(0, row), this.getCellID(0, row), style, (lCode.clin) ? lCode.clin : '');
518
- this.setCell(sheet, this.getCellID(1, row), this.getCellID(1, row), style, (lCode.slin) ? lCode.slin : '');
519
- this.setCell(sheet, this.getCellID(2, row), this.getCellID(2, row), style, (emp.companyinfo.division) ? emp.companyinfo.division.toUpperCase() : '');
520
- this.setCell(sheet, this.getCellID(3, row), this.getCellID(3, row), style, (lCode.location) ? lCode.location : '');
521
- this.setCell(sheet, this.getCellID(4, row), this.getCellID(4, row), style, (lCode.wbs) ? lCode.wbs : '');
522
- this.setCell(sheet, this.getCellID(5, row), this.getCellID(5, row), style, `${lCode.chargeNumber} ${lCode.extension}`);
523
- this.setCell(sheet, this.getCellID(6, row), this.getCellID(6, row), lStyle, emp.name.lastname);
524
- this.setCell(sheet, this.getCellID(7, row), this.getCellID(7, row), style, (emp.companyinfo.rank) ? emp.companyinfo.rank : '');
525
- this.setCell(sheet, this.getCellID(8, row), this.getCellID(8, row), style, emp.companyinfo.employeeid);
526
- this.setCell(sheet, this.getCellID(9, row), this.getCellID(9, row), style, (emp.companyinfo.alternateid) ? emp.companyinfo.alternateid : '');
527
- this.setCell(sheet, this.getCellID(10, row), this.getCellID(10, row), style, (emp.companyinfo.costcenter) ? emp.companyinfo.costcenter : '');
528
- this.setCell(sheet, this.getCellID(11, row), this.getCellID(11, row), style, "");
529
- // This section steps though the forecast report periods to provide the hours worked/
530
- // or forecasted to work, in the period. Each period corresponds to an accounting
531
- // month and its weekly periods. These are determined by the contract administrator
532
- // and put in the forecast report object.
533
- let column = 11;
534
- const sumlist = []; // used to provide a total hours from the monthly values
535
- report.periods.forEach(period => {
536
- column++;
537
- style = {
538
- fill: this.fills.get('dkblush'),
539
- font: this.fonts.get('bold12'),
540
- alignment: this.alignments.get('rightctr'),
541
- border: this.borders.get('blackthin'),
542
- numFmt: this.numformats.get('sum')
543
- };
544
- // create the formula to obtain the monthly total of hours and set the formula to
545
- // the summary cell.
546
- let formula = '';
547
- if (period.periods.length > 1) {
548
- formula = `SUM(${this.getCellID(column + 1, row)}:`
549
- + `${this.getCellID(column + period.periods.length, row)})`;
550
- }
551
- else {
552
- formula = `${this.getCellID(column + 1, row)}`;
553
- }
554
- let cellID = this.getCellID(column, row);
555
- this.setCell(sheet, cellID, cellID, style, new general_1.Formula(formula));
556
- sumlist.push(cellID);
557
- // step through the weekly periods to get the employee's work hours.
558
- period.periods.forEach(prd => {
559
- column++;
560
- let last = new Date(prd);
561
- let first = new Date(last.getTime() - (6 * 24 * 3600000));
562
- if (first.getTime() < report.startDate.getTime()) {
563
- first = new Date(Date.UTC(report.startDate.getFullYear(), report.startDate.getMonth(), report.startDate.getDate()));
564
- }
565
- if (last.getTime() > report.endDate.getTime()) {
566
- last = new Date(Date.UTC(report.endDate.getFullYear(), report.endDate.getMonth(), report.endDate.getDate()));
567
- }
568
- style = {
569
- fill: this.fills.get('ltgray'),
570
- font: this.fonts.get('bold12'),
571
- alignment: this.alignments.get('center'),
572
- border: this.borders.get('blackthin')
573
- };
574
- let hours = emp.getWorkedHours(first, last, lCode.chargeNumber, lCode.extension);
575
- // if the worksheet displays forecast data and the last date is after the
576
- // employee's last recorded actual workday, show as a forecast value and get the
577
- // forecast hours added to the actual hours.
578
- if (!current) {
579
- if (last.getTime() > lastWorked.getTime()) {
580
- style.font = this.fonts.get('blue12');
581
- }
582
- hours += emp.getForecastHours(lCode, first, last, this.workcodes);
583
- }
584
- let cellID = this.getCellID(column, row);
585
- this.setCell(sheet, cellID, cellID, style, hours);
586
- // this sets an excel conditional formatting relationship for if the resultant
587
- // value is equal to zero (0), changes fill color and displays a dash.
588
- sheet.addConditionalFormatting({
589
- ref: `${cellID}:${cellID}`,
590
- rules: [
591
- {
592
- type: 'cellIs',
593
- priority: 1,
594
- operator: 'equal',
595
- formulae: [0],
596
- style: {
597
- fill: { type: 'pattern', pattern: 'solid', bgColor: { argb: `ffffb5b5` } },
598
- font: { bold: true, size: 12, color: { argb: `ff000000` } },
599
- alignment: { horizontal: 'center', vertical: 'middle', wrapText: true },
600
- numFmt: "##0.0;[Red]##0.0;-;@"
601
- }
602
- }
603
- ]
604
- });
605
- });
606
- });
607
- // lastly, set the totals column and conditional style format
608
- style = {
609
- fill: this.fills.get('dkblush'),
610
- font: this.fonts.get('bold12'),
611
- alignment: this.alignments.get('center'),
612
- border: this.borders.get('blackthin'),
613
- numFmt: this.numformats.get('monthsum')
614
- };
615
- column++;
616
- let cellID = this.getCellID(column, row);
617
- let formula = '';
618
- sumlist.forEach(c => {
619
- if (formula !== '') {
620
- formula += "+";
621
- }
622
- formula += c;
623
- });
624
- this.setCell(sheet, cellID, cellID, style, new general_1.Formula(formula));
625
- // these conditional formatting provides fill color change for if the employee
626
- // works more than his/her alloted hours or less than alloted hours.
627
- sheet.addConditionalFormatting({
628
- ref: `${cellID}`,
629
- rules: [
630
- {
631
- type: 'cellIs',
632
- priority: 1,
633
- operator: 'greaterThan',
634
- formulae: [lCode.hoursPerEmployee],
635
- style: {
636
- fill: { type: 'pattern', pattern: 'solid', bgColor: { argb: `ffffb5b5` } },
637
- font: { bold: true, size: 12, color: { argb: `ff000000` } },
638
- alignment: { horizontal: 'center', vertical: 'middle', wrapText: true },
639
- border: {
640
- top: { style: 'thin', color: { argb: 'ff000000' } },
641
- left: { style: 'thin', color: { argb: 'ff000000' } },
642
- bottom: { style: 'thin', color: { argb: 'ff000000' } },
643
- right: { style: 'thin', color: { argb: 'ff000000' } }
644
- },
645
- numFmt: "##0.0;[Red]##0.0;-;@"
646
- }
647
- }
648
- ]
649
- });
650
- sheet.addConditionalFormatting({
651
- ref: `${cellID}`,
652
- rules: [
653
- {
654
- type: 'cellIs',
655
- priority: 1,
656
- operator: 'lessThan',
657
- formulae: [lCode.hoursPerEmployee],
658
- style: {
659
- fill: { type: 'pattern', pattern: 'solid', bgColor: { argb: `ff99cc00` } },
660
- font: { bold: true, size: 12, color: { argb: `ff000000` } },
661
- alignment: { horizontal: 'center', vertical: 'middle', wrapText: true },
662
- border: {
663
- top: { style: 'thin', color: { argb: 'ff000000' } },
664
- left: { style: 'thin', color: { argb: 'ff000000' } },
665
- bottom: { style: 'thin', color: { argb: 'ff000000' } },
666
- right: { style: 'thin', color: { argb: 'ff000000' } }
667
- },
668
- numFmt: "##0.0;[Red]##0.0;-;@"
669
- }
670
- }
671
- ]
672
- });
673
- return column;
674
- }
675
- /**
676
- * This function will create the statistics page for the cover of the workbook, which
677
- * will hold all the formulas for overall labor usage.
678
- * @param workbook The excel workbook object use for creating worksheets within it.
679
- * @returns The reference to the statistics worksheet to allow other functions to fill
680
- * in the formulas to use.
681
- */
682
- createStatisticsSheet(workbook) {
683
- // Create the sheet just like the others but with the label statistics
684
- const sheetname = "Statistics";
685
- const sheet = workbook.addWorksheet(sheetname, {
686
- pageSetup: {
687
- paperSize: undefined,
688
- orientation: 'landscape',
689
- fitToHeight: 1,
690
- fitToWidth: 1,
691
- blackAndWhite: false,
692
- fitToPage: true,
693
- showGridLines: false,
694
- horizontalCentered: true,
695
- verticalCentered: true
696
- }
697
- });
698
- // set the width of all the columns
699
- sheet.getColumn("A").width = 30;
700
- for (let i = 2; i < 12; i++) {
701
- sheet.getColumn(i).width = 12;
702
- }
703
- // this is used to create the current as of date on the sheet
704
- const dFormat = new Intl.DateTimeFormat('en-US', {
705
- day: '2-digit',
706
- month: 'short',
707
- year: 'numeric'
708
- });
709
- let style = {
710
- fill: this.fills.get('white'),
711
- font: this.fonts.get('bold18'),
712
- alignment: this.alignments.get('center'),
713
- border: this.borders.get('blackthin'),
714
- };
715
- const now = new Date();
716
- this.setCell(sheet, "A1", "K1", style, `Current As Of ${dFormat.format(now)}`);
717
- sheet.getRow(1).height = 20;
718
- sheet.getRow(2).height = 77;
719
- style = {
720
- fill: this.fills.get('white'),
721
- font: this.fonts.get('bold12'),
722
- alignment: this.alignments.get('centerslant'),
723
- border: this.borders.get("blackthin")
724
- };
725
- // Set the column headers with column B & C, inclusive dates in white/slanted 45
726
- this.setCell(sheet, "B2", "B2", style, "Start");
727
- this.setCell(sheet, "C2", "C2", style, "End");
728
- // To Date section headers in a blue/slant 45
729
- style.fill = this.fills.get('blue');
730
- this.setCell(sheet, "D2", "D2", style, "Alloted");
731
- this.setCell(sheet, "E2", "E2", style, "Used");
732
- this.setCell(sheet, "F2", "F2", style, "Over/Under");
733
- this.setCell(sheet, "G2", "G2", style, "Percent");
734
- // Overall/Projected section headers in a blue/slant 45
735
- style.fill = this.fills.get('green');
736
- this.setCell(sheet, "H2", "H2", style, "Alloted");
737
- this.setCell(sheet, "I2", "I2", style, "Used");
738
- this.setCell(sheet, "J2", "J2", style, "Over/Under");
739
- this.setCell(sheet, "K2", "K2", style, "Percent");
740
- // labels for the sections
741
- style.fill = this.fills.get('white');
742
- style.alignment = this.alignments.get('center');
743
- this.setCell(sheet, "A3", "A3", style, "Contract No/Ext");
744
- this.setCell(sheet, "B3", "C3", style, "Contract Period");
745
- style.fill = this.fills.get('blue');
746
- this.setCell(sheet, "D3", "G3", style, "Current");
747
- style.fill = this.fills.get('green');
748
- this.setCell(sheet, "H3", "K3", style, "Forecast");
749
- return sheet;
750
- }
751
- }
752
- exports.ChargeStatusReport = ChargeStatusReport;