2022-06-13 07:42:26 -07:00
|
|
|
import {Mongo} from "meteor/mongo";
|
|
|
|
|
import {Meteor} from "meteor/meteor";
|
2022-06-20 08:24:35 -07:00
|
|
|
import { Roles } from 'meteor/alanning:roles';
|
2022-07-23 23:42:23 -07:00
|
|
|
import {check} from "meteor/check";
|
|
|
|
|
import {Sites} from "/imports/api/sites";
|
|
|
|
|
import {parse} from "csv-parse";
|
2022-08-14 17:07:14 -07:00
|
|
|
import { ReactiveAggregate } from 'meteor/tunguska:reactive-aggregate';
|
2022-06-13 07:42:26 -07:00
|
|
|
|
2022-08-15 07:01:20 -07:00
|
|
|
// console.log("Setting Up Staff...")
|
|
|
|
|
|
2022-06-20 08:24:35 -07:00
|
|
|
export const Staff = new Mongo.Collection('staff');
|
2022-06-13 07:42:26 -07:00
|
|
|
|
|
|
|
|
if (Meteor.isServer) {
|
|
|
|
|
// This code only runs on the server
|
2022-06-20 08:24:35 -07:00
|
|
|
Meteor.publish('staff', function(siteId) {
|
|
|
|
|
return Staff.find({siteId});
|
2022-06-13 07:42:26 -07:00
|
|
|
});
|
2022-08-14 17:07:14 -07:00
|
|
|
Meteor.publish('staffWithAssetAssignments', function(query) {
|
|
|
|
|
ReactiveAggregate(this, Staff, {$lookup: {
|
|
|
|
|
from: 'assetAssignments',
|
|
|
|
|
localField: '_id',
|
|
|
|
|
foreignField: 'assigneeId',
|
|
|
|
|
as: 'assignments'
|
|
|
|
|
}}, {});
|
|
|
|
|
//Note: The options can use {clientCollection: 'your_name_here'} as the options to change the collection name on the client.
|
|
|
|
|
});
|
2022-06-13 07:42:26 -07:00
|
|
|
}
|
|
|
|
|
Meteor.methods({
|
2022-06-20 08:24:35 -07:00
|
|
|
'staff.add'(firstName, lastName, email, siteId) {
|
2022-06-13 07:42:26 -07:00
|
|
|
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
|
2022-06-20 08:24:35 -07:00
|
|
|
Staff.insert({firstName, lastName, email, siteId});
|
2022-06-13 07:42:26 -07:00
|
|
|
}
|
|
|
|
|
},
|
2022-06-20 08:24:35 -07:00
|
|
|
'staff.remove'(_id) {
|
2022-06-13 07:42:26 -07:00
|
|
|
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
|
2022-06-20 08:24:35 -07:00
|
|
|
//TODO: Need to first verify there are no checked out assets to the staff member.
|
2022-06-13 07:42:26 -07:00
|
|
|
}
|
|
|
|
|
},
|
2022-07-23 23:42:23 -07:00
|
|
|
/**
|
|
|
|
|
* Assumes that the ID field is a unique ID that never changes for staff.
|
|
|
|
|
* This must be true in order for duplicate staff to be avoided.
|
|
|
|
|
* Will automatically update staff data, including the site he/she is associated with.
|
|
|
|
|
*
|
|
|
|
|
* Expects the CSV string to contain comma delimited data in the form:
|
|
|
|
|
* ID, email, first name, last name
|
|
|
|
|
*
|
|
|
|
|
* The query in Aeries is: `LIST STF ID FN LN EM PSC`.
|
|
|
|
|
* A more complete Aeries query: `LIST STF ID FN LN EM BY FN IF PSC = 5`
|
|
|
|
|
* Note that you will want to run this query for each school, and the district. The example above sets the school to #5 (PSC).
|
|
|
|
|
* Run the query in Aeries as a `Report`, select TXT, and upload here.
|
|
|
|
|
*
|
|
|
|
|
* Aeries adds a header per 'page' of data (I think 35 entries per page).
|
|
|
|
|
* Example:
|
|
|
|
|
* Anderson Valley Jr/Sr High School,6/11/2022
|
|
|
|
|
* 2021-2022,Page 1
|
|
|
|
|
* StuEmail,Student ID,First Name,Last Name,Grade,First Name Alias,Last Name Alias
|
|
|
|
|
* @type: Currently only supports 'CSV' or 'Aeries Text Report'
|
|
|
|
|
*/
|
|
|
|
|
'staff.loadCsv'(csv, type, siteId) {
|
|
|
|
|
if(Roles.userIsInRole(Meteor.userId(), "admin", {anyScope:true})) {
|
|
|
|
|
check(csv, String);
|
|
|
|
|
check(siteId, String);
|
|
|
|
|
|
|
|
|
|
let site = Sites.findOne({_id: siteId});
|
|
|
|
|
|
|
|
|
|
if(site) {
|
|
|
|
|
let cleanCsv;
|
|
|
|
|
let lines = csv.split(/\r?\n/);
|
|
|
|
|
let pageHeader = type === 'Aeries Text Report' ? lines[0] : null; // Skip the repeating header lines for an Aeries text report.
|
|
|
|
|
let skip = type === 'CSV' ? 1 : 0; // Skip the first line of a CSV file (headers).
|
|
|
|
|
|
|
|
|
|
// Remove headers from the CSV.
|
|
|
|
|
for(const line of lines) {
|
|
|
|
|
if (skip > 0) skip--;
|
|
|
|
|
else if (pageHeader && line === pageHeader) {
|
|
|
|
|
skip = 2;
|
|
|
|
|
} else {
|
|
|
|
|
if(!cleanCsv) cleanCsv = "";
|
|
|
|
|
else cleanCsv += '\r\n';
|
|
|
|
|
cleanCsv += line;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//console.log(cleanCsv);
|
|
|
|
|
|
|
|
|
|
// Note: This doesn't work because some values are quoted and contain commas as a value character.
|
|
|
|
|
// Parse the CSV (now without any headers).
|
|
|
|
|
// lines = cleanCsv.split(/\r\n/);
|
|
|
|
|
// for(const line of lines) {
|
|
|
|
|
// let values = line.split(/\s*,\s*/);
|
|
|
|
|
//
|
|
|
|
|
// if(values.length >= 5) {
|
|
|
|
|
// let id = values[0];
|
|
|
|
|
// let email = values[1];
|
|
|
|
|
// let firstName = values[2];
|
|
|
|
|
// let lastName = values[3];
|
|
|
|
|
// let grade = parseInt(values[4], 10);
|
|
|
|
|
// let firstNameAlias = "";
|
|
|
|
|
// let active = true;
|
|
|
|
|
//
|
|
|
|
|
// if(values.length > 5) firstNameAlias = values[5];
|
|
|
|
|
//
|
|
|
|
|
// let student = {siteId, email, id, firstName, lastName, grade, firstNameAlias, active};
|
|
|
|
|
//
|
|
|
|
|
// // console.log(student);
|
|
|
|
|
// // Update or insert in the db.
|
|
|
|
|
// console.log("Upserting: " + student);
|
|
|
|
|
// Students.upsert({id}, {$set: student});
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
const bound = Meteor.bindEnvironment((callback) => {callback();});
|
|
|
|
|
|
|
|
|
|
parse(cleanCsv, {}, function(err, records) {
|
|
|
|
|
bound(() => {
|
|
|
|
|
if(err) console.error(err);
|
|
|
|
|
else {
|
|
|
|
|
let foundIds = new Set();
|
|
|
|
|
let duplicates = [];
|
|
|
|
|
console.log("Found " + records.length + " records.");
|
|
|
|
|
|
|
|
|
|
for(const values of records) {
|
|
|
|
|
let id = values[0];
|
|
|
|
|
let email = values[1];
|
|
|
|
|
let firstName = values[2];
|
|
|
|
|
let lastName = values[3];
|
|
|
|
|
let grade = parseInt(values[4], 10);
|
|
|
|
|
let firstNameAlias = "";
|
|
|
|
|
let active = true;
|
|
|
|
|
|
|
|
|
|
if(values.length > 5) firstNameAlias = values[5];
|
|
|
|
|
|
|
|
|
|
let staff = {siteId, email, id, firstName, lastName, active};
|
|
|
|
|
|
|
|
|
|
// Track the staff ID's and record duplicates. This is used to ensure our counts are accurate later.
|
|
|
|
|
if(foundIds.has(staff.id)) {
|
|
|
|
|
duplicates.push(staff.id);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
foundIds.add(staff.id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//console.log(staff);
|
|
|
|
|
try {
|
|
|
|
|
Staff.upsert({id: staff.id}, {$set: staff});
|
|
|
|
|
}
|
|
|
|
|
catch(err) {
|
|
|
|
|
console.error(err);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log(duplicates.length + " records were duplicates:");
|
|
|
|
|
console.log(duplicates);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
console.log("Failed to find the site with the ID: " + siteId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-06-13 07:42:26 -07:00
|
|
|
});
|
|
|
|
|
|
2022-08-15 07:01:20 -07:00
|
|
|
// console.log("Staff setup.")
|