Started adding async calls for upgrading to Meteor 3.0. Numerous other fixes.
This commit is contained in:
@@ -1,9 +1,20 @@
|
||||
import {Mongo} from "meteor/mongo";
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { check } from 'meteor/check';
|
||||
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||
import 'meteor/aldeed:collection2/static'
|
||||
import SimpleSchema from 'meteor/aldeed:simple-schema';
|
||||
import Products from "./Product";
|
||||
import Measures from "./Measure";
|
||||
|
||||
Barcodes = new Mongo.Collection('Barcodes');
|
||||
let Barcodes = new Mongo.Collection('Barcodes');
|
||||
|
||||
if(Meteor.isServer) {
|
||||
//Set MongoDB indexes (or remove them) here.
|
||||
try {
|
||||
Barcodes.rawCollection().createIndex({barcodeId: -1}, {unique: true})
|
||||
Barcodes.rawCollection().createIndex({productAndMeasureId: -1}, {unique: true})
|
||||
} catch(e) {console.log("Caught exception while setting indexes in MongoDB"); console.error(e)}
|
||||
}
|
||||
|
||||
// A simple mapping between a concatenation of the product & measure ID and a unique sequential number for the barcode. This allows us to have a small number to keep our barcodes simple, while maintaining the more traditional MongoDB ID's for the Product and Measure.
|
||||
const BarcodesSchema = new SimpleSchema({
|
||||
@@ -11,15 +22,15 @@ const BarcodesSchema = new SimpleSchema({
|
||||
type: Number,
|
||||
label: "Barcode ID",
|
||||
optional: false,
|
||||
index: 1,
|
||||
unique: true
|
||||
//index: 1,
|
||||
//unique: true
|
||||
},
|
||||
productAndMeasureId: { //Just the two ids jammed together with a single space between them.
|
||||
type: String,
|
||||
label: "Product And Measure ID",
|
||||
optional: false,
|
||||
index: 1,
|
||||
unique: true
|
||||
//index: 1,
|
||||
//unique: true
|
||||
}
|
||||
});
|
||||
|
||||
@@ -29,15 +40,15 @@ if(Meteor.isServer) {
|
||||
//});
|
||||
|
||||
Meteor.methods({
|
||||
getBarcodeId: function(productId, measureId) {
|
||||
getBarcodeId: async function(productId, measureId) {
|
||||
check(productId, String);
|
||||
check(measureId, String);
|
||||
|
||||
let hasProduct = Meteor.collections.Products.findOne({_id: productId}, {fields: {}});
|
||||
let hasMeasure = Meteor.collections.Measures.findOne({_id: measureId}, {fields: {}});
|
||||
let hasProduct = await Meteor.collections.Products.findOneAsync({_id: productId}, {fields: {}});
|
||||
let hasMeasure = await Meteor.collections.Measures.findOneAsync({_id: measureId}, {fields: {}});
|
||||
|
||||
if(hasProduct && hasMeasure) {
|
||||
let existing = Barcodes.findOne({productAndMeasureId: productId + ' ' + measureId});
|
||||
let existing = await Barcodes.findOneAsync({productAndMeasureId: productId + ' ' + measureId});
|
||||
|
||||
if(existing) {
|
||||
return existing.barcodeId;
|
||||
@@ -48,10 +59,12 @@ if(Meteor.isServer) {
|
||||
//Try a thousand times before failing. Should never fail, should also not ever need to try a thousand times (unless we somehow automate label generation to the point where a 1000 processes at once are requesting labels that have never been generated before - highly unlikely).
|
||||
while(c++ < 1000) {
|
||||
//Lookup the most likely next barcode id from the db, then attempt to insert with it. If it fails due to duplication, then increment and repeat.
|
||||
let cursor = Products.find({}, {barcodeId: 1}).sort({barcodeId: -1}).limit(1); //Since currently products are never removed, we shouldn't need to detect sequence gaps and fill them in (odds are we will never use more than 10k numbers anyway).
|
||||
let barcodeId = cursor.hasNext() ? cursor.next().barcodeId + 1 : 1;
|
||||
//let cursor = Products.find({}, {barcodeId: 1}).sort({barcodeId: -1}).limit(1); //Since currently products are never removed, we shouldn't need to detect sequence gaps and fill them in (odds are we will never use more than 10k numbers anyway).
|
||||
//let barcodeId = cursor.hasNext() ? cursor.next().barcodeId + 1 : 1;
|
||||
let product = await Products.findOneAsync({barcodeId: {$exists: true}}, {sort: {barcodeId: -1}})
|
||||
let barcodeId = product ? product.barcodeId : 1;
|
||||
|
||||
Barcodes.insert({productAndMeasureId: productId + ' ' + measureId, barcodeId}, function(err, id) {
|
||||
await Barcodes.insertAsync({productAndMeasureId: productId + ' ' + measureId, barcodeId}, function(err, id) {
|
||||
if(err) console.log(err);
|
||||
else return barcodeId;
|
||||
});
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Mongo } from 'meteor/mongo';
|
||||
import { check } from 'meteor/check';
|
||||
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||
import 'meteor/aldeed:collection2/static'
|
||||
import SimpleSchema from 'meteor/aldeed:simple-schema';
|
||||
import Measures from "./Measure";
|
||||
|
||||
/**
|
||||
* Notes:
|
||||
@@ -10,12 +12,24 @@ import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||
*/
|
||||
|
||||
let Batches = new Mongo.Collection('Batches');
|
||||
|
||||
if(Meteor.isServer) {
|
||||
//Set MongoDB indexes (or remove them) here.
|
||||
try {
|
||||
Batches.rawCollection().createIndex({date: -1}, {unique: false})
|
||||
Batches.rawCollection().createIndex({measureId: -1}, {unique: false})
|
||||
Batches.rawCollection().createIndex({productId: -1}, {unique: false})
|
||||
Batches.rawCollection().createIndex({cookId: -1}, {unique: false})
|
||||
Batches.rawCollection().createIndex({cannerId: -1}, {unique: false})
|
||||
} catch(e) {console.log("Caught exception while setting indexes in MongoDB"); console.error(e)}
|
||||
}
|
||||
|
||||
let BatchesSchema = new SimpleSchema({
|
||||
date: {
|
||||
type: Number, // A number in the format of YYYYMMDD to allow for searching using greater and less than, and to prevent timezones from messing everything up.
|
||||
label: "Date",
|
||||
optional: false,
|
||||
index: 1
|
||||
//index: 1
|
||||
},
|
||||
timestamp: { //This is based off the date with zero for the time and set to GMT (Zulu time).
|
||||
type: Date,
|
||||
@@ -31,21 +45,21 @@ let BatchesSchema = new SimpleSchema({
|
||||
type: Number,
|
||||
label: "Amount",
|
||||
optional: false,
|
||||
decimal: true
|
||||
//decimal: true
|
||||
},
|
||||
measureId: {
|
||||
type: String,
|
||||
label: "Measure Id",
|
||||
trim: false,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
index: 1
|
||||
//index: 1
|
||||
},
|
||||
productId: {
|
||||
type: String,
|
||||
label: "Product Id",
|
||||
trim: false,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
index: 1,
|
||||
//index: 1,
|
||||
optional: false
|
||||
},
|
||||
cookId: {
|
||||
@@ -53,14 +67,14 @@ let BatchesSchema = new SimpleSchema({
|
||||
label: "Cook Worker Id",
|
||||
trim: false,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
index: 1
|
||||
//index: 1
|
||||
},
|
||||
cannerId: {
|
||||
type: String,
|
||||
label: "Canner Worker Id",
|
||||
trim: false,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
index: 1,
|
||||
//index: 1,
|
||||
optional: false
|
||||
},
|
||||
hasLabels: {
|
||||
@@ -134,11 +148,11 @@ if(Meteor.isServer) {
|
||||
});
|
||||
|
||||
Meteor.methods({
|
||||
getBatchCount: function(query) {
|
||||
getBatchCount: async function(query) {
|
||||
//TODO: Validate the query?
|
||||
return Batches.find(query).count();
|
||||
return await Batches.countDocuments(query);
|
||||
},
|
||||
insertBatches: function(batches) { //Insert one or more batches (if one, you can pass just the batch).
|
||||
insertBatches: async function(batches) { //Insert one or more batches (if one, you can pass just the batch).
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
//Force it to be an array if it isn't.
|
||||
if(!Array.isArray(batches)) batches = [batches];
|
||||
@@ -170,37 +184,37 @@ if(Meteor.isServer) {
|
||||
}
|
||||
|
||||
for(let batch of batches) {
|
||||
Batches.insert(batch, function(err, id) {
|
||||
await Batches.insertAsync(batch, function(err, id) {
|
||||
if(err) console.log(err);
|
||||
}, {bypassCollection2: true});
|
||||
}
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
deleteBatch: function(id) { //Does not actually delete the batch, but rather just marks it for deleting by applying a deletion date.
|
||||
deleteBatch: async function(id) { //Does not actually delete the batch, but rather just marks it for deleting by applying a deletion date.
|
||||
check(id, String);
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
let deletedAt = new Date();
|
||||
|
||||
//Batches.remove(id);
|
||||
Batches.update(id, {$set: {deletedAt}}, function(err, id) {
|
||||
await Batches.updateAsync(id, {$set: {deletedAt}}, function(err, id) {
|
||||
if(err) console.log(err);
|
||||
});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
undeleteBatch: function(id) { //Revokes the previous deletion.
|
||||
undeleteBatch: async function(id) { //Revokes the previous deletion.
|
||||
check(id, String);
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Batches.update(id, {$unset: {deletedAt:""}}, function(err, id) {
|
||||
await Batches.updateAsync(id, {$unset: {deletedAt:""}}, function(err, id) {
|
||||
if(err) console.log(err);
|
||||
});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
//editBatchComment: function(id, comment) {
|
||||
//editBatchComment: async function(id, comment) {
|
||||
// check(id, String);
|
||||
// check(comment, String);
|
||||
// //Trim and convert empty comment to undefined.
|
||||
@@ -211,19 +225,19 @@ if(Meteor.isServer) {
|
||||
// console.log("Changed comment of " + id + " to: " + comment);
|
||||
//
|
||||
// if(comment) {
|
||||
// Batches.update(id, {$set: {comment}}, function(error, count) {
|
||||
// await Batches.updateAsync(id, {$set: {comment}}, function(error, count) {
|
||||
// if(error) throw new Meteor.Error(400, "Unexpected database error: " + error);
|
||||
// });
|
||||
// }
|
||||
// else {
|
||||
// Batches.update(id, {$unset: {comment: ""}}, function(error, count) {
|
||||
// await Batches.updateAsync(id, {$unset: {comment: ""}}, function(error, count) {
|
||||
// if(error) throw new Meteor.Error(400, "Unexpected database error: " + error);
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// else throw new Meteor.Error(403, "Not authorized.");
|
||||
//},
|
||||
updateBatch: function(id, amount, comment) {
|
||||
updateBatch: async function(id, amount, comment) {
|
||||
check(id, String);
|
||||
check(amount, Number);
|
||||
check(comment, Match.OneOf(String, undefined));
|
||||
@@ -237,13 +251,13 @@ if(Meteor.isServer) {
|
||||
//let weekOfYear = timestamp.getWeek().toString();
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Batches.update(id, {$set: {comment, amount}}, function(err, id) {
|
||||
await Batches.updateAsync(id, {$set: {comment, amount}}, function(err, id) {
|
||||
if(err) console.log(err);
|
||||
}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
setBatchHasLabels: function(id, hasLabels) {
|
||||
setBatchHasLabels: async function(id, hasLabels) {
|
||||
//console.log(id);
|
||||
//console.log(hasLabels);
|
||||
//check(id, Meteor.validators.ObjectID);
|
||||
@@ -251,7 +265,7 @@ if(Meteor.isServer) {
|
||||
check(hasLabels, Boolean);
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Batches.update(id, {$set: {hasLabels}}, function(err, id) {
|
||||
await Batches.updateAsync(id, {$set: {hasLabels}}, function(err, id) {
|
||||
if(err) console.log(err);
|
||||
}, {bypassCollection2: true});
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Mongo } from 'meteor/mongo';
|
||||
import { check } from 'meteor/check';
|
||||
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||
import 'meteor/aldeed:collection2/static'
|
||||
import SimpleSchema from 'meteor/aldeed:simple-schema';
|
||||
import LabelFormats from '/imports/LabelFormats.js';
|
||||
|
||||
|
||||
@@ -36,13 +37,13 @@ if(Meteor.isServer) {
|
||||
});
|
||||
|
||||
//Returns a JSON containing a denormalized list of products {product_id, measure_id, product_name, measure_name, price, }
|
||||
WebApp.connectHandlers.use("/labels/GetBarCodeData", (req, res, next) => {
|
||||
WebApp.connectHandlers.use("/labels/GetBarCodeData", async (req, res, next) => {
|
||||
try {
|
||||
let barcodes = Meteor.collections.Barcodes.find({}, {fields: {_id: 0, barcodeId: 1, productAndMeasureId: 1}});
|
||||
let measures = Meteor.collections.Measures.find({}, {fields: {_id: 1, name: 1}, sort: {order: 1}}).fetch();
|
||||
let measures = await Meteor.collections.Measures.find({}, {fields: {_id: 1, name: 1}, sort: {order: 1}}).fetchAsync();
|
||||
//Note: Price data looks like this: {XZ5Z3CM49NDrJNADA /* MeasureID */: {price: 10.5, effectiveDate: ISODate("2017-01-12T13:14:18.876-08:00"), previousPrice: 9}, ...}
|
||||
//Measures is an array of MeasureIDs valid for this product.
|
||||
let products = Meteor.collections.Products.find({}, {fields: {_id: 1, name: 1, measures: 1, prices: 1}, sort: {order: 1}}).fetch();
|
||||
let products = await Meteor.collections.Products.find({}, {fields: {_id: 1, name: 1, measures: 1, prices: 1}, sort: {order: 1}}).fetchAsync();
|
||||
let measuresById = {};
|
||||
let barcodesByProductAndMeasureIds = {};
|
||||
let result = {};
|
||||
|
||||
@@ -6,7 +6,7 @@ import { LoggerMongo } from 'meteor/ostrio:loggermongo';
|
||||
// The logging tool is primarily for managing administrative functions such that administrators can view the app logs and issue commands that might generate administrative logging.
|
||||
|
||||
Meteor.log = new Logger();
|
||||
Logs = new Mongo.Collection('Logs');
|
||||
let Logs = new Mongo.Collection('Logs');
|
||||
|
||||
let logMongo = new LoggerMongo(Meteor.log, {
|
||||
collection: Logs
|
||||
@@ -23,8 +23,8 @@ if(Meteor.isServer) {
|
||||
return Logs.find({}, {limit: 10000});
|
||||
});
|
||||
Meteor.methods({
|
||||
clearLogs: function() {
|
||||
return Logs.remove({}, function(err) {
|
||||
clearLogs: async function() {
|
||||
return await Logs.removeAsync({}, function(err) {
|
||||
if(err) Meteor.log.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Mongo } from 'meteor/mongo';
|
||||
import { check } from 'meteor/check';
|
||||
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||
import 'meteor/aldeed:collection2/static'
|
||||
import SimpleSchema from 'meteor/aldeed:simple-schema';
|
||||
|
||||
let Measures = new Mongo.Collection('Measures');
|
||||
|
||||
if(Meteor.isServer) {
|
||||
//Set MongoDB indexes (or remove them) here.
|
||||
try {
|
||||
Measures.rawCollection().createIndex({name: -1}, {unique: true})
|
||||
} catch(e) {console.log("Caught exception while setting indexes in MongoDB"); console.error(e)}
|
||||
}
|
||||
|
||||
Measures.attachSchema(new SimpleSchema({
|
||||
name: {
|
||||
type: String,
|
||||
label: "Name",
|
||||
optional: false,
|
||||
trim: true,
|
||||
index: 1,
|
||||
unique: true
|
||||
// index: 1, Requires aldeed:schema-index which requires an older version fo aldeed:collection2 (3.5.0 vs 4.0.2) This can be achieved by adding indexes to MongoDB directly.
|
||||
//unique: true
|
||||
},
|
||||
postfix: {
|
||||
type: String,
|
||||
@@ -63,39 +72,39 @@ if(Meteor.isServer) Meteor.publish('measures', function() {
|
||||
|
||||
if(Meteor.isServer) {
|
||||
Meteor.methods({
|
||||
createMeasure: function(name, postfix, order) {
|
||||
createMeasure: async function(name, postfix, order) {
|
||||
check(name, String);
|
||||
check(postfix, String);
|
||||
check(order, Number);
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Measures.insert({name, postfix, order, createdAt: new Date()});
|
||||
await Measures.insertAsync({name, postfix, order, createdAt: new Date()});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
deactivateMeasure: function(id) {
|
||||
deactivateMeasure: async function(id) {
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
//Measures.remove(id);
|
||||
Measures.update(id, {$set: {deactivated: true}}, {bypassCollection2: true});
|
||||
await Measures.updateAsync(id, {$set: {deactivated: true}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
reactivateMeasure: function(id) {
|
||||
reactivateMeasure: async function(id) {
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Measures.update(id, {$set: {deactivated: false}}, {bypassCollection2: true});
|
||||
await Measures.updateAsync(id, {$set: {deactivated: false}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
hideMeasure: function(id) { //One step past deactivated - will only show in the measures list if hidden measures are enabled.
|
||||
hideMeasure: async function(id) { //One step past deactivated - will only show in the measures list if hidden measures are enabled.
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
//Measures.remove(id);
|
||||
Measures.update(id, {$set: {hidden: true}}, {bypassCollection2: true});
|
||||
await Measures.updateAsync(id, {$set: {hidden: true}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
showMeasure: function(id) { //Returns the measure to being simply deactivated. Will again show in lists.
|
||||
showMeasure: async function(id) { //Returns the measure to being simply deactivated. Will again show in lists.
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Measures.update(id, {$set: {hidden: false}}, {bypassCollection2: true});
|
||||
await Measures.updateAsync(id, {$set: {hidden: false}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
@@ -106,14 +115,14 @@ if(Meteor.isServer) {
|
||||
// }
|
||||
// else throw new Meteor.Error(403, "Not authorized.");
|
||||
//},
|
||||
updateMeasure: function(id, name, postfix, order) {
|
||||
updateMeasure: async function(id, name, postfix, order) {
|
||||
check(id, String);
|
||||
check(name, String);
|
||||
check(postfix, String);
|
||||
check(order, Number);
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Measures.update(id, {$set: {name, postfix, order, updatedAt: new Date()}});
|
||||
await Measures.updateAsync(id, {$set: {name, postfix, order, updatedAt: new Date()}});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Mongo } from 'meteor/mongo';
|
||||
import { check } from 'meteor/check';
|
||||
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||
import 'meteor/aldeed:collection2/static'
|
||||
import SimpleSchema from 'meteor/aldeed:simple-schema';
|
||||
import Measures from "./Measure";
|
||||
|
||||
/**
|
||||
* Notes:
|
||||
@@ -16,21 +18,31 @@ import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||
|
||||
let Products = new Mongo.Collection('Products');
|
||||
|
||||
if(Meteor.isServer) {
|
||||
//Set MongoDB indexes (or remove them) here.
|
||||
try {
|
||||
Products.rawCollection().createIndex({name: -1}, {unique: true})
|
||||
} catch(e) {console.log("Caught exception while setting indexes in MongoDB"); console.error(e)}
|
||||
}
|
||||
|
||||
const ProductsSchema = new SimpleSchema({
|
||||
name: {
|
||||
type: String,
|
||||
label: "Name",
|
||||
optional: false,
|
||||
trim: true,
|
||||
index: 1,
|
||||
unique: true
|
||||
//index: 1,
|
||||
//unique: true
|
||||
},
|
||||
tags: { //An array of ProductTag names. Note that we are not using the ProductTag ID's because I want a looser connection (if a ProductTag is deleted, it isn't a big deal if it isn't maintained in the Product records).
|
||||
type: [String],
|
||||
type: Array, //[String],
|
||||
label: "Tags",
|
||||
optional: false,
|
||||
defaultValue: []
|
||||
},
|
||||
'tags.$': {
|
||||
type: String,
|
||||
},
|
||||
measures: { //A JSON array of Measure ID's.
|
||||
type: Array,
|
||||
label: "Measures",
|
||||
@@ -181,7 +193,7 @@ if(Meteor.isServer) {
|
||||
});
|
||||
|
||||
Meteor.methods({
|
||||
createProduct: function(name, tags, aliases, measures) {
|
||||
createProduct: async function(name, tags, aliases, measures) {
|
||||
check(name, String);
|
||||
if(tags) check(tags, [String]);
|
||||
if(aliases) check(aliases, [String]);
|
||||
@@ -192,48 +204,48 @@ if(Meteor.isServer) {
|
||||
//let cursor = Products.find({}, {barCodeId: 1}).sort({barCodeId: -1}).limit(1); //Since currently products are never removed, we shouldn't need to detect sequence gaps and fill them in (odds are we will never use more than 10k numbers anyway).
|
||||
//let barCodeId = cursor.hasNext() ? cursor.next().barCodeId : 1;
|
||||
//
|
||||
Products.insert({name, tags, aliases, measures, createdAt: new Date()}, {bypassCollection2: true}, function(err, id) {
|
||||
await Products.insertAsync({name, tags, aliases, measures, createdAt: new Date()}, {bypassCollection2: true}, function(err, id) {
|
||||
if(err) console.log(err);
|
||||
});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
convertProduct: function(productId, alternateProductId) {
|
||||
convertProduct: async function(productId, alternateProductId) {
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
check(productId, String);
|
||||
check(alternateProductId, String);
|
||||
// Replace all sale references to the given ID with the provided alternate product ID.
|
||||
Meteor.collections.Sales.update({productId: productId}, {$set: {productId: alternateProductId}}, {multi: true});
|
||||
await Meteor.collections.Sales.updateAsync({productId: productId}, {$set: {productId: alternateProductId}}, {multi: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
deactivateProduct: function(id) {
|
||||
deactivateProduct: async function(id) {
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
//Products.remove(id);
|
||||
Products.update(id, {$set: {deactivated: true}}, {bypassCollection2: true});
|
||||
await Products.updateAsync(id, {$set: {deactivated: true}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
reactivateProduct: function(id) {
|
||||
reactivateProduct: async function(id) {
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Products.update(id, {$set: {deactivated: false}}, {bypassCollection2: true});
|
||||
await Products.updateAsync(id, {$set: {deactivated: false}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
hideProduct: function(id) { //One step past deactivated - will only show in the products list if hidden products are enabled.
|
||||
hideProduct: async function(id) { //One step past deactivated - will only show in the products list if hidden products are enabled.
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
//Products.remove(id);
|
||||
Products.update(id, {$set: {hidden: true}}, {bypassCollection2: true});
|
||||
await Products.updateAsync(id, {$set: {hidden: true}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
showProduct: function(id) { //Returns the product to being simply deactivated. Will again show in lists.
|
||||
showProduct: async function(id) { //Returns the product to being simply deactivated. Will again show in lists.
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Products.update(id, {$set: {hidden: false}}, {bypassCollection2: true});
|
||||
await Products.updateAsync(id, {$set: {hidden: false}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
updateProduct: function(id, name, tags, aliases, measures) {
|
||||
updateProduct: async function(id, name, tags, aliases, measures) {
|
||||
check(id, String);
|
||||
check(name, String);
|
||||
if(tags) check(tags, [String]);
|
||||
@@ -241,22 +253,22 @@ if(Meteor.isServer) {
|
||||
if(measures) check(measures, [String]);
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Products.update(id, {$set: {name: name, tags: tags, aliases: aliases, measures: measures, updatedAt: new Date()}}, {bypassCollection2: true});
|
||||
await Products.updateAsync(id, {$set: {name: name, tags: tags, aliases: aliases, measures: measures, updatedAt: new Date()}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
clearProductPrice: function(productIds, measureId) {
|
||||
clearProductPrice: async function(productIds, measureId) {
|
||||
check(productIds, [String]);
|
||||
check(measureId, String);
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
let attr = "prices." + measureId;
|
||||
|
||||
Products.update({_id: {$in: productIds}}, {$unset: {[attr]: true}}, {validate: false, bypassCollection2: true});
|
||||
|
||||
await Products.updateAsync({_id: {$in: productIds}}, {$unset: {[attr]: true}}, {validate: false, bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
setProductPrice: function(productIds, measureId, price, setPrevious, effectiveDate) {
|
||||
setProductPrice: async function(productIds, measureId, price, setPrevious, effectiveDate) {
|
||||
check(productIds, [String]);
|
||||
check(measureId, String);
|
||||
check(price, Number);
|
||||
@@ -283,14 +295,14 @@ if(Meteor.isServer) {
|
||||
measurePriceData.price = price;
|
||||
|
||||
if(ProductsSchema.newContext().isValid()) {
|
||||
Products.update(product._id, {$set: {prices: prices, updateAt: new Date()}}, {validate: false, bypassCollection2: true});
|
||||
await Products.updateAsync(product._id, {$set: {prices: prices, updateAt: new Date()}}, {validate: false, bypassCollection2: true});
|
||||
}
|
||||
else console.log("Invalid schema for product");
|
||||
}
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
tagProducts: function(productIds, tagId) {
|
||||
tagProducts: async function(productIds, tagId) {
|
||||
//Tags the products if any products don't have the tag, otherwise removes the tag from all products.
|
||||
check(productIds, [String]);
|
||||
check(tagId, String);
|
||||
@@ -299,10 +311,10 @@ if(Meteor.isServer) {
|
||||
let productsWithTag = Products.find({_id: {$in: productIds}, tags: {$all: [tagId]}}).count();
|
||||
|
||||
if(productsWithTag == productIds.length) {
|
||||
Products.update({_id: {$in: productIds}}, {$pullAll: {tags: [tagId]}}, {bypassCollection2: true, multi: true});
|
||||
await Products.updateAsync({_id: {$in: productIds}}, {$pullAll: {tags: [tagId]}}, {bypassCollection2: true, multi: true});
|
||||
}
|
||||
else {
|
||||
Products.update({_id: {$in: productIds}}, {$addToSet: {tags: tagId}}, {bypassCollection2: true, multi: true});
|
||||
await Products.updateAsync({_id: {$in: productIds}}, {$addToSet: {tags: tagId}}, {bypassCollection2: true, multi: true});
|
||||
}
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Mongo } from 'meteor/mongo';
|
||||
import { check } from 'meteor/check'
|
||||
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||
import 'meteor/aldeed:collection2/static'
|
||||
import SimpleSchema from 'meteor/aldeed:simple-schema';
|
||||
import Measures from "./Measure";
|
||||
|
||||
ProductTags = new Mongo.Collection('ProductTags', {
|
||||
let ProductTags = new Mongo.Collection('ProductTags', {
|
||||
schema: new SimpleSchema({
|
||||
name: {
|
||||
type: String,
|
||||
label: "Name",
|
||||
optional: false,
|
||||
trim: true,
|
||||
index: 1,
|
||||
unique: true
|
||||
//index: 1,
|
||||
//unique: true
|
||||
},
|
||||
createdAt: {
|
||||
type: Date,
|
||||
@@ -26,6 +28,13 @@ ProductTags = new Mongo.Collection('ProductTags', {
|
||||
})
|
||||
});
|
||||
|
||||
if(Meteor.isServer) {
|
||||
//Set MongoDB indexes (or remove them) here.
|
||||
try {
|
||||
ProductTags.rawCollection().createIndex({name: -1}, {unique: true})
|
||||
} catch(e) {console.log("Caught exception while setting indexes in MongoDB"); console.error(e)}
|
||||
}
|
||||
|
||||
//Allows the client to do DB interaction without calling server side methods, while still retaining control over whether the user can make changes.
|
||||
ProductTags.allow({
|
||||
insert: function() {return false;},
|
||||
@@ -39,23 +48,23 @@ if(Meteor.isServer) {
|
||||
});
|
||||
|
||||
Meteor.methods({
|
||||
insertProductTag: function(productTag) {
|
||||
insertProductTag: async function(productTag) {
|
||||
check(productTag, String);
|
||||
productTag = {name: productTag, createdAt: new Date()};
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
ProductTags.insert(productTag, function(err, id) {
|
||||
await ProductTags.insertAsync(productTag, function(err, id) {
|
||||
if(err) console.log(err);
|
||||
});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
deleteProductTag: function(id) {
|
||||
deleteProductTag: async function(id) {
|
||||
check(id, String);
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
//Remove all references to the tag in the products.
|
||||
Meteor.collections.Products.update({tags: {$all: [id]}}, {$pullAll: {tags: [id]}}, {bypassCollection2: true, multi: true});
|
||||
await Meteor.collections.Products.updateAsync({tags: {$all: [id]}}, {$pullAll: {tags: [id]}}, {bypassCollection2: true, multi: true});
|
||||
// let products = Meteor.collections.Products.find({tags: {$all: [id]}}, {_id: 1, tags: 1}).fetch();
|
||||
//
|
||||
// //Try to remove all tags from products. Log/Ignore any errors.
|
||||
@@ -73,17 +82,17 @@ if(Meteor.isServer) {
|
||||
// }
|
||||
// }
|
||||
|
||||
ProductTags.remove(id);
|
||||
await ProductTags.removeAsync(id);
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
updateProductTag: function(tag) {
|
||||
updateProductTag: async function(tag) {
|
||||
check(tag, {
|
||||
_id: String,
|
||||
name: String
|
||||
});
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
ProductTags.update(tag._id, {$set: {name: tag.name, updatedAt: new Date()}});
|
||||
await ProductTags.updateAsync(tag._id, {$set: {name: tag.name, updatedAt: new Date()}});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ if(Meteor.isServer) {
|
||||
}
|
||||
}]);
|
||||
|
||||
result.toArray().then(function(result) {
|
||||
result.toArray().then(async function(result) {
|
||||
let totalByYear = {};
|
||||
|
||||
//Create a map of maps: year -> measure id -> sales count.
|
||||
@@ -80,7 +80,7 @@ if(Meteor.isServer) {
|
||||
}
|
||||
|
||||
//Create a list of ordered measures. We could use a map, but then getting the ordering correct would be difficult.
|
||||
let measures = Meteor.collections.Measures.find({}, {fields: {_id: 1, name: 1}, sort: {order: 1}}).fetch();
|
||||
let measures = await Meteor.collections.Measures.find({}, {fields: {_id: 1, name: 1}, sort: {order: 1}}).fetchAsync();
|
||||
|
||||
//Collect the years in ascending oder.
|
||||
let years = Object.keys(totalByYear).sort(function(a, b) {return parseInt(a) - parseInt(b);});
|
||||
@@ -130,7 +130,7 @@ if(Meteor.isServer) {
|
||||
}
|
||||
}]);
|
||||
|
||||
result.toArray().then(function(result) {
|
||||
result.toArray().then(async function(result) {
|
||||
let productSalesTotalsMapByYear = {};
|
||||
|
||||
//Create a map of maps: year -> product id -> sales totals.
|
||||
@@ -145,7 +145,7 @@ if(Meteor.isServer) {
|
||||
|
||||
//Now create a mapping between the tag id's and tag names for later use.
|
||||
let tagIdToTagNameMap = {};
|
||||
let tags = Meteor.collections.ProductTags.find({}, {fields: {_id: 1, name: 1}}).fetch();
|
||||
let tags = await Meteor.collections.ProductTags.find({}, {fields: {_id: 1, name: 1}}).fetchAsync();
|
||||
|
||||
for(let tag of tags) {
|
||||
tagIdToTagNameMap[tag._id] = tag.name;
|
||||
@@ -153,7 +153,7 @@ if(Meteor.isServer) {
|
||||
|
||||
//Now create a map between tag names -> [product ids] so that we can build a table below.
|
||||
let tagProductIdsMap = {};
|
||||
let products = Meteor.collections.Products.find({}, {fields: {_id: 1, tags: 1}}).fetch();
|
||||
let products = await Meteor.collections.Products.find({}, {fields: {_id: 1, tags: 1}}).fetchAsync();
|
||||
|
||||
for(let product of products) {
|
||||
for(let tagId of product.tags) {
|
||||
@@ -234,7 +234,7 @@ if(Meteor.isServer) {
|
||||
}
|
||||
}]);
|
||||
|
||||
result.toArray().then(function(result) {
|
||||
result.toArray().then(async function(result) {
|
||||
let totalByYear = {};
|
||||
|
||||
//Create a map of maps: year -> product id -> measure id -> sales count.
|
||||
@@ -252,10 +252,10 @@ if(Meteor.isServer) {
|
||||
}
|
||||
|
||||
//Create a list of ordered measures. We could use a map, but then getting the ordering correct would be difficult.
|
||||
let measures = Meteor.collections.Measures.find({}, {fields: {_id: 1, name: 1}, sort: {order: 1}}).fetch();
|
||||
let measures = await Meteor.collections.Measures.find({}, {fields: {_id: 1, name: 1}, sort: {order: 1}}).fetcAsync();
|
||||
|
||||
//Now create a mapping between the product id's and product names for later use.
|
||||
let products = Meteor.collections.Products.find({}, {fields: {_id: 1, name: 1}, sort: {name: 1}}).fetch();
|
||||
let products = await Meteor.collections.Products.find({}, {fields: {_id: 1, name: 1}, sort: {name: 1}}).fetcAsync();
|
||||
|
||||
//Collect the years in ascending oder.
|
||||
let years = Object.keys(totalByYear).sort(function(a, b) {return parseInt(a) - parseInt(b);});
|
||||
@@ -367,7 +367,7 @@ if(Meteor.isServer) {
|
||||
}
|
||||
}]);
|
||||
|
||||
result.toArray().then(function(result) {
|
||||
result.toArray().then(async function(result) {
|
||||
let totalByYear = {};
|
||||
|
||||
//Create a map of maps: year -> product id -> measure id -> sales count.
|
||||
@@ -385,11 +385,11 @@ if(Meteor.isServer) {
|
||||
}
|
||||
|
||||
//Create a list of ordered measures. We could use a map, but then getting the ordering correct would be difficult.
|
||||
let measures = Meteor.collections.Measures.find({}, {fields: {_id: 1, name: 1}, sort: {order: 1}}).fetch();
|
||||
let measures = await Meteor.collections.Measures.find({}, {fields: {_id: 1, name: 1}, sort: {order: 1}}).fetcAsync();
|
||||
|
||||
//Now create a mapping between the tag id's and tag names for later use.
|
||||
let tagIdToTagNameMap = {};
|
||||
let tags = Meteor.collections.ProductTags.find({}, {fields: {_id: 1, name: 1}}).fetch();
|
||||
let tags = await Meteor.collections.ProductTags.find({}, {fields: {_id: 1, name: 1}}).fetcAsync();
|
||||
|
||||
for(let tag of tags) {
|
||||
tagIdToTagNameMap[tag._id] = tag.name;
|
||||
@@ -397,7 +397,7 @@ if(Meteor.isServer) {
|
||||
|
||||
//Now create a map between tag names -> [product ids] so that we can build a table below.
|
||||
let tagProductIdsMap = {};
|
||||
let products = Meteor.collections.Products.find({}, {fields: {_id: 1, tags: 1}}).fetch();
|
||||
let products = await Meteor.collections.Products.find({}, {fields: {_id: 1, tags: 1}}).fetcAsync();
|
||||
|
||||
for(let product of products) {
|
||||
for(let tagId of product.tags) {
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
import { Roles } from 'meteor/alanning:roles'
|
||||
|
||||
if(Meteor.isServer) {
|
||||
Meteor.publish('roles', function() {
|
||||
//console.log("Checking if user is in the manage role: " + Meteor.userId() + " === " + Roles.userIsInRole(this.userId, ['manage']))
|
||||
if(Roles.userIsInRole(this.userId, ['manage'])) {
|
||||
return Meteor.roles.find({}, {fields: {name: 1}});
|
||||
//Meteor.roles.find({}, {fields: {name: 1}}).fetchAsync().then(roles => {console.log(roles)})
|
||||
//return Meteor.roles.find({}, {fields: {name: 1}});
|
||||
return Meteor.roles.find({});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized to view roles.");
|
||||
});
|
||||
Meteor.publish("roleAssignments", function() {
|
||||
if(Roles.userIsInRole(this.userId, ['manage'])) {
|
||||
return Meteor.roleAssignment.find({});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized to view roles.");
|
||||
})
|
||||
}
|
||||
|
||||
let ROLE_MANAGE = "manage";
|
||||
@@ -13,5 +23,12 @@ let ROLE_UPDATE = "update";
|
||||
|
||||
Meteor.UserRoles = {ROLE_MANAGE, ROLE_UPDATE};
|
||||
|
||||
// This is the collection that maps users to roles (v3 of alanning:roles).
|
||||
//Meteor.roleAssignment
|
||||
// This is where you will find the roles defained in MongoDB:
|
||||
//Meteor.roles
|
||||
|
||||
Roles.createRoleAsync(ROLE_MANAGE)
|
||||
Roles.createRoleAsync(ROLE_UPDATE)
|
||||
|
||||
export default Meteor.roles;
|
||||
@@ -1,21 +1,34 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Mongo } from 'meteor/mongo';
|
||||
import { check } from 'meteor/check';
|
||||
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||
import 'meteor/aldeed:collection2/static'
|
||||
import SimpleSchema from 'meteor/aldeed:simple-schema';
|
||||
import Batches from "./Batch";
|
||||
import Measures from "./Measure";
|
||||
|
||||
/**
|
||||
* Notes:
|
||||
* The Sale object has a date field which stores the date as a number in the format YYYYMMDD. Converting this number into a local date is done with moment(sale.date.toString(), "YYYYMMDD").toDate(), and converting it to a number from a date can be accomplished with ~~(moment(date).format("YYYYMMDD")), where the ~~ is a bitwise not and converts a string to a number quickly and reliably.
|
||||
*/
|
||||
|
||||
Sales = new Mongo.Collection('Sales');
|
||||
let Sales = new Mongo.Collection('Sales');
|
||||
|
||||
if(Meteor.isServer) {
|
||||
//Set MongoDB indexes (or remove them) here.
|
||||
try {
|
||||
Sales.rawCollection().createIndex({date: -1}, {unique: false})
|
||||
Sales.rawCollection().createIndex({productId: -1}, {unique: false})
|
||||
Sales.rawCollection().createIndex({measureId: -1}, {unique: false})
|
||||
Sales.rawCollection().createIndex({venueId: -1}, {unique: false})
|
||||
} catch(e) {console.log("Caught exception while setting indexes in MongoDB"); console.error(e)}
|
||||
}
|
||||
|
||||
let SalesSchema = new SimpleSchema({
|
||||
date: {
|
||||
type: Number, // A number in the format of YYYYMMDD to allow for searching using greater and less than, and to prevent timezones from messing everything up.
|
||||
label: "Date",
|
||||
optional: false,
|
||||
index: 1
|
||||
//index: 1
|
||||
},
|
||||
timestamp: {
|
||||
type: Date,
|
||||
@@ -31,7 +44,7 @@ let SalesSchema = new SimpleSchema({
|
||||
type: Number,
|
||||
label: "Amount",
|
||||
optional: false,
|
||||
decimal: true
|
||||
//decimal: true
|
||||
},
|
||||
price: {
|
||||
type: Number,
|
||||
@@ -39,28 +52,29 @@ let SalesSchema = new SimpleSchema({
|
||||
optional: false,
|
||||
min: 0,
|
||||
exclusiveMin: true,
|
||||
decimal: true
|
||||
//decimal: true
|
||||
},
|
||||
measureId: {
|
||||
type: String,
|
||||
label: "Measure Id",
|
||||
trim: false,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
index: 1
|
||||
//index: 1
|
||||
},
|
||||
productId: {
|
||||
type: String,
|
||||
label: "Product Id",
|
||||
trim: false,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
index: 1
|
||||
//index: 1
|
||||
},
|
||||
venueId: {
|
||||
type: String,
|
||||
label: "Vendor Id",
|
||||
trim: false,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
index: 1
|
||||
//index: 1
|
||||
|
||||
// autoform: {
|
||||
// type: 'relation',
|
||||
// settings: {
|
||||
@@ -280,11 +294,11 @@ if(Meteor.isServer) {
|
||||
});
|
||||
|
||||
Meteor.methods({
|
||||
getSalesCount: function(query) {
|
||||
getSalesCount: async function(query) {
|
||||
//TODO: Validate the query?
|
||||
return Sales.find(query).count();
|
||||
return await Sales.countDocuments(query);
|
||||
},
|
||||
insertSale: function(sale) {
|
||||
insertSale: async function(sale) {
|
||||
check(sale, {
|
||||
date: Number, // TODO: Check that the format is YYYYMMDD
|
||||
amount: Match.Where(function(x) {
|
||||
@@ -308,21 +322,21 @@ if(Meteor.isServer) {
|
||||
sale.weekOfYear = sale.timestamp.getWeek().toString();
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Sales.insert(sale, function(err, id) {
|
||||
await Sales.insertAsync(sale, function(err, id) {
|
||||
if(err) console.log(err);
|
||||
}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
deleteSale: function(id) {
|
||||
deleteSale: async function(id) {
|
||||
check(id, String);
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Sales.remove(id);
|
||||
await Sales.removeAsync(id);
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
editSaleComment: function(id, comment) {
|
||||
editSaleComment: async function(id, comment) {
|
||||
check(id, String);
|
||||
check(comment, String);
|
||||
//Trim and convert empty comment to undefined.
|
||||
@@ -333,19 +347,19 @@ if(Meteor.isServer) {
|
||||
console.log("Changed comment of " + id + " to: " + comment);
|
||||
|
||||
if(comment) {
|
||||
Sales.update(id, {$set: {comment}}, function(error, count) {
|
||||
await Sales.updateAsync(id, {$set: {comment}}, function(error, count) {
|
||||
if(error) throw new Meteor.Error(400, "Unexpected database error: " + error);
|
||||
});
|
||||
}
|
||||
else {
|
||||
Sales.update(id, {$unset: {comment: ""}}, function(error, count) {
|
||||
await Sales.updateAsync(id, {$unset: {comment: ""}}, function(error, count) {
|
||||
if(error) throw new Meteor.Error(400, "Unexpected database error: " + error);
|
||||
});
|
||||
}
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
updateSale: function(id, date, venueId, price, amount) {
|
||||
updateSale: async function(id, date, venueId, price, amount) {
|
||||
check(id, String);
|
||||
check(date, Number); // TODO: Check that the format is YYYYMMDD
|
||||
check(venueId, String);
|
||||
@@ -357,45 +371,45 @@ if(Meteor.isServer) {
|
||||
let weekOfYear = timestamp.getWeek().toString();
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Sales.update(id, {$set: {date, venueId, price, amount, timestamp, weekOfYear}}, function(err, id) {
|
||||
await Sales.updateAsync(id, {$set: {date, venueId, price, amount, timestamp, weekOfYear}}, function(err, id) {
|
||||
if(err) console.log(err);
|
||||
}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
countSales: function() {
|
||||
countSales: async function() {
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
return Sales.find({}).count();
|
||||
return await Sales.countDocuments({});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
removeDuplicateSales: function(id, justOne) { // Expects the id of the sale that has duplicates and an optional boolean flag (justOne) indicating whether just one duplicate should be removed, or all of them (default).
|
||||
removeDuplicateSales: async function(id, justOne) { // Expects the id of the sale that has duplicates and an optional boolean flag (justOne) indicating whether just one duplicate should be removed, or all of them (default).
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
// Remove either one or all of the duplicates of the Sale with the given ID.
|
||||
if(justOne) {
|
||||
let sale = Sales.findOne({isDuplicateOf: id});
|
||||
let sale = await Sales.findOneAsync({isDuplicateOf: id});
|
||||
|
||||
if(sale) {
|
||||
Sales.remove({_id: sale._id});
|
||||
await Sales.removeAsync({_id: sale._id});
|
||||
}
|
||||
}
|
||||
else {
|
||||
Sales.remove({isDuplicateOf: id});
|
||||
await Sales.removeAsync({isDuplicateOf: id});
|
||||
}
|
||||
}
|
||||
},
|
||||
ignoreDuplicateSales: function(id) { // Expects the id of the sale that has duplicates. Will mark this sale and all duplicates to be ignored in future duplicate checks.
|
||||
ignoreDuplicateSales: async function(id) { // Expects the id of the sale that has duplicates. Will mark this sale and all duplicates to be ignored in future duplicate checks.
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
// Mark to ignore duplicates for this Sale (id) and all its duplicates, and clear any duplicate counts and references.
|
||||
//Sales.update({$or: [{_id: id}, {isDuplicateOf: id}]}, {$set: {ignoreDuplicates: true}, $unset: {isDuplicateOf: "", duplicateCount: ""}});
|
||||
|
||||
// Mark to ignore duplicates for this Sale (id). We will leave the duplicate count and references so that the duplicates will show in a query if we want to revisit those marked as ignored.
|
||||
Sales.update({$or: [{_id: id}, {isDuplicateOf: id}]}, {$set: {ignoreDuplicates: true}});
|
||||
await Sales.updateAsync({$or: [{_id: id}, {isDuplicateOf: id}]}, {$set: {ignoreDuplicates: true}});
|
||||
}
|
||||
},
|
||||
markDuplicateSales: function() {
|
||||
markDuplicateSales: async function() {
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
let sales = Sales.find({}, {sort: {date: 1, venueId: 1, productId: 1, price: 1, amount: 1, measureId: 1, createdAt: 1}}).fetch();
|
||||
let sales = await Sales.find({}, {sort: {date: 1, venueId: 1, productId: 1, price: 1, amount: 1, measureId: 1, createdAt: 1}}).fetchAsync();
|
||||
|
||||
// Iterate over all the sales looking for sales that have duplicates.
|
||||
// Since the sales are sorted by sale date, venueId, productId, price, amount, and measureId which all must be identical to be considered a possible duplicate sale, we only have to check subsequent sales until a non-duplicate is found.
|
||||
@@ -405,7 +419,7 @@ if(Meteor.isServer) {
|
||||
// If this is marked as a duplicate of another sale, but we got to this point in the loop then the sale it is a duplicate of must have been removed or marked to ignore duplicates.
|
||||
if(sale.isDuplicateOf) {
|
||||
delete sale.isDuplicateOf;
|
||||
Sales.update(sale._id, {$unset: {isDuplicateOf: ""}}, function(err, id) {
|
||||
await Sales.updateAsync(sale._id, {$unset: {isDuplicateOf: ""}}, function(err, id) {
|
||||
if(err) console.log(err);
|
||||
}, {bypassCollection2: true});
|
||||
}
|
||||
@@ -426,7 +440,7 @@ if(Meteor.isServer) {
|
||||
if(checkSale && sale.productId === checkSale.productId && sale.venueId === checkSale.venueId && sale.price === checkSale.price && sale.amount === checkSale.amount && sale.measureId === checkSale.measureId) {
|
||||
// Mark the next sale as a duplicate of the currently examined sale.
|
||||
checkSale.isDuplicateOf = sale._id;
|
||||
Sales.update(checkSale._id, {$set: {isDuplicateOf: checkSale.isDuplicateOf}}, function(err, id) {
|
||||
await Sales.updateAsync(checkSale._id, {$set: {isDuplicateOf: checkSale.isDuplicateOf}}, function(err, id) {
|
||||
if(err) console.log(err);
|
||||
}, {bypassCollection2: true});
|
||||
duplicateCount++;
|
||||
@@ -442,7 +456,7 @@ if(Meteor.isServer) {
|
||||
if(sale.duplicateCount !== duplicateCount) {
|
||||
// Update the sale's duplicate count.
|
||||
sale.duplicateCount = duplicateCount;
|
||||
Sales.update(sale._id, {$set: {duplicateCount: sale.duplicateCount}}, function(err, id) {
|
||||
await Sales.updateAsync(sale._id, {$set: {duplicateCount: sale.duplicateCount}}, function(err, id) {
|
||||
if(err) console.log(err);
|
||||
}, {bypassCollection2: true});
|
||||
}
|
||||
@@ -450,7 +464,7 @@ if(Meteor.isServer) {
|
||||
else if(sale.duplicateCount) {
|
||||
// Remove the duplicate count if it is set.
|
||||
delete sale.duplicateCount;
|
||||
Sales.update(sale._id, {$unset: {duplicateCount: ""}}, function(err, id) {
|
||||
await Sales.updateAsync(sale._id, {$unset: {duplicateCount: ""}}, function(err, id) {
|
||||
if(err) console.log(err);
|
||||
}, {bypassCollection2: true});
|
||||
}
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Mongo } from 'meteor/mongo';
|
||||
import { check } from 'meteor/check';
|
||||
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||
import 'meteor/aldeed:collection2/static'
|
||||
import SimpleSchema from 'meteor/aldeed:simple-schema';
|
||||
import Measures from "./Measure";
|
||||
|
||||
SalesSheets = new Mongo.Collection('SalesSheets');
|
||||
let SalesSheets = new Mongo.Collection('SalesSheets');
|
||||
|
||||
if(Meteor.isServer) {
|
||||
//Set MongoDB indexes (or remove them) here.
|
||||
try {
|
||||
SalesSheets.rawCollection().createIndex({name: -1}, {unique: false})
|
||||
} catch(e) {console.log("Caught exception while setting indexes in MongoDB"); console.error(e)}
|
||||
}
|
||||
|
||||
const SalesSheetSchema = new SimpleSchema({
|
||||
name: {
|
||||
@@ -11,8 +20,8 @@ const SalesSheetSchema = new SimpleSchema({
|
||||
label: "Name",
|
||||
optional: false,
|
||||
trim: true,
|
||||
index: 1,
|
||||
unique: false
|
||||
//index: 1,
|
||||
//unique: false
|
||||
},
|
||||
products: { //An ordered array of product id's included on the sheet.
|
||||
type: Array,
|
||||
@@ -27,7 +36,7 @@ const SalesSheetSchema = new SimpleSchema({
|
||||
label: "Name",
|
||||
optional: false,
|
||||
trim: true,
|
||||
unique: false
|
||||
//unique: false
|
||||
},
|
||||
productId: { //Note: Will be non-existent for headings.
|
||||
type: String,
|
||||
@@ -37,10 +46,13 @@ const SalesSheetSchema = new SimpleSchema({
|
||||
optional: true
|
||||
},
|
||||
measureIds: { //Note: Will be non-existent for headings.
|
||||
type: [String],
|
||||
type: Array, //[String],
|
||||
label: "Measure IDs",
|
||||
optional: true
|
||||
}
|
||||
},
|
||||
'measureIds.$': {
|
||||
type: String,
|
||||
},
|
||||
//measureIds: {
|
||||
// type: Array,
|
||||
// label: "Measure IDs",
|
||||
@@ -74,11 +86,11 @@ if(Meteor.isServer) {
|
||||
});
|
||||
|
||||
Meteor.methods({
|
||||
createSalesSheet: function(name) {
|
||||
createSalesSheet: async function(name) {
|
||||
check(name, String);
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
return SalesSheets.insert({name, products: [], createdAt: new Date()});
|
||||
return await SalesSheets.insertAsync({name, products: [], createdAt: new Date()});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
@@ -98,7 +110,7 @@ if(Meteor.isServer) {
|
||||
//updateSalesSheet_updateProduct_removeMeasure: function(id, productId, productName, productMeasures) {
|
||||
//
|
||||
//},
|
||||
updateSalesSheet: function(id, name, products) {
|
||||
updateSalesSheet: async function(id, name, products) {
|
||||
check(id, String);
|
||||
check(name, String);
|
||||
check(products, [{
|
||||
@@ -128,7 +140,7 @@ if(Meteor.isServer) {
|
||||
//console.log("db.SalesSheet.update({_id: '" + id + "'}, {$set: {name: '" + name + "', updatedAt: " + new Date() + "}, $pull: {$exists: true}, $pushAll: [" + productList + "]})");
|
||||
|
||||
// Forces the object to be re-written, versus piecemeal updated.
|
||||
SalesSheets.update({_id: id}, {$set: {name: name, products: products, updatedAt: new Date()}}, {validate: false}, function(err, count) {
|
||||
await SalesSheets.updateAsync({_id: id}, {$set: {name: name, products: products, updatedAt: new Date()}}, {validate: false}, function(err, count) {
|
||||
if(err) console.log(err);
|
||||
});
|
||||
|
||||
@@ -146,11 +158,11 @@ if(Meteor.isServer) {
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
removeSalesSheet: function(id) {
|
||||
removeSalesSheet: async function(id) {
|
||||
check(id, String);
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
SalesSheets.remove(id);
|
||||
await SalesSheets.removeAsync(id);
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
}
|
||||
|
||||
@@ -9,12 +9,13 @@ if(Meteor.isServer) {
|
||||
});
|
||||
|
||||
Meteor.methods({
|
||||
"insertUser": function(user) {
|
||||
"insertUser": function(user, roles) {
|
||||
check(user, {
|
||||
username: String,
|
||||
emails: [{address: String, verified: Match.Maybe(Boolean)}],
|
||||
roles: [String]
|
||||
//roles: [String]
|
||||
});
|
||||
check(roles, [String])
|
||||
|
||||
//Verify the currently logged in user has authority to manage users.
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_MANAGE])) {
|
||||
@@ -33,7 +34,7 @@ if(Meteor.isServer) {
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized to add users.");
|
||||
},
|
||||
"updateUser": function(user) {
|
||||
"updateUser": async function(user, roles) {
|
||||
check(user, {
|
||||
_id: String,
|
||||
username: String,
|
||||
@@ -41,15 +42,36 @@ if(Meteor.isServer) {
|
||||
address: String,
|
||||
verified: Boolean
|
||||
}],
|
||||
roles: [String]
|
||||
//roles: [String]
|
||||
});
|
||||
check(roles, [String])
|
||||
|
||||
//Verify the currently logged in user has authority to manage users.
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_MANAGE])) {
|
||||
//Verify the user name isn't already used with a different ID.
|
||||
if(Meteor.collections.Users.findOne({username: user.username, _id: {$ne: user._id}}) == undefined) {
|
||||
//Update the user. Note: I am using direct mongo modification, versus attempting to go through the Accounts and Roles objects. This could cause problems in the future if these packages change their data structures.
|
||||
Meteor.collections.Users.update(user._id, {$set: {username: user.username, emails: user.emails, roles: user.roles}});
|
||||
await Meteor.collections.Users.updateAsync(user._id, {$set: {username: user.username, emails: user.emails/*, roles: user.roles*/}});
|
||||
|
||||
let currentRoles = await Roles.getRolesForUserAsync(user._id)
|
||||
|
||||
//console.log(currentRoles)
|
||||
//console.log(roles)
|
||||
|
||||
//TODO: Figure out which roles to add, and which roles to remove.
|
||||
|
||||
// Add roles not in the database already.
|
||||
//console.log("Adding the user " + user._id + " to the following roles: ")
|
||||
//for(let next of roles) console.log(next)
|
||||
|
||||
let rolesToAdd = roles.filter(x => !currentRoles.includes(x))
|
||||
let rolesToRemove = currentRoles.filter(x => !roles.includes(x))
|
||||
|
||||
console.log('Roles to remove: ' + rolesToRemove)
|
||||
console.log('Roles to add: ' + rolesToAdd)
|
||||
|
||||
if(rolesToAdd.length) Roles.addUsersToRoles([user._id], rolesToAdd)
|
||||
if(rolesToRemove.length) Roles.removeUsersFromRoles([user._id], rolesToRemove)
|
||||
}
|
||||
else {
|
||||
throw new Meteor.Error(400, "User name already exists.");
|
||||
@@ -57,10 +79,10 @@ if(Meteor.isServer) {
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized to update users.");
|
||||
},
|
||||
"deleteUser": function(id) {
|
||||
"deleteUser": async function(id) {
|
||||
check(id, String);
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_MANAGE])) {
|
||||
Meteor.collections.Users.remove(id);
|
||||
await Meteor.collections.Users.removeAsync(id);
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized to remove users.");
|
||||
}
|
||||
|
||||
@@ -1,20 +1,30 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Mongo } from 'meteor/mongo';
|
||||
import { check } from 'meteor/check';
|
||||
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||
import 'meteor/aldeed:collection2/static'
|
||||
import SimpleSchema from 'meteor/aldeed:simple-schema';
|
||||
import Measures from "./Measure";
|
||||
|
||||
const TYPES = ['Retail', "Farmer's Market", "Restaurant", "Mail"];
|
||||
const FREQUENCIES = ['Daily', 'Weekly'];
|
||||
|
||||
let Venues = new Mongo.Collection('Venues');
|
||||
|
||||
if(Meteor.isServer) {
|
||||
//Set MongoDB indexes (or remove them) here.
|
||||
try {
|
||||
Venues.rawCollection().createIndex({name: -1}, {unique: true})
|
||||
} catch(e) {console.log("Caught exception while setting indexes in MongoDB"); console.error(e)}
|
||||
}
|
||||
|
||||
let VenuesSchema = new SimpleSchema({
|
||||
name: {
|
||||
type: String,
|
||||
label: "Name",
|
||||
optional: false,
|
||||
trim: true,
|
||||
index: 1,
|
||||
unique: true
|
||||
//index: 1,
|
||||
//unique: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
@@ -70,13 +80,13 @@ if(Meteor.isServer) {
|
||||
//});
|
||||
|
||||
Meteor.methods({
|
||||
createVenue: function(name, type, frequency) {
|
||||
createVenue: async function(name, type, frequency) {
|
||||
check(name, String);
|
||||
check(type, String);
|
||||
check(frequency, String);
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Venues.insert({name, type, frequency, createdAt: new Date()});
|
||||
await Venues.insertAsync({name, type, frequency, createdAt: new Date()});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
@@ -86,40 +96,40 @@ if(Meteor.isServer) {
|
||||
// }
|
||||
// else throw new Meteor.Error(403, "Not authorized.");
|
||||
//},
|
||||
updateVenue: function(id, name, type, frequency) {
|
||||
updateVenue: async function(id, name, type, frequency) {
|
||||
check(id, String);
|
||||
check(name, String);
|
||||
check(type, String);
|
||||
check(frequency, String);
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Venues.update(id, {$set: {name, type, frequency, updatedAt: new Date()}});
|
||||
await Venues.updateAsync(id, {$set: {name, type, frequency, updatedAt: new Date()}});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
deactivateVenue: function(id) {
|
||||
deactivateVenue: async function(id) {
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
//Venues.remove(id);
|
||||
Venues.update(id, {$set: {deactivated: true}}, {bypassCollection2: true});
|
||||
await Venues.updateAsync(id, {$set: {deactivated: true}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
reactivateVenue: function(id) {
|
||||
reactivateVenue: async function(id) {
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Venues.update(id, {$set: {deactivated: false}}, {bypassCollection2: true});
|
||||
await Venues.updateAsync(id, {$set: {deactivated: false}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
hideVenue: function(id) { //One step past deactivated - will only show in the venues list if hidden venues are enabled.
|
||||
hideVenue: async function(id) { //One step past deactivated - will only show in the venues list if hidden venues are enabled.
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
//Venues.remove(id);
|
||||
Venues.update(id, {$set: {hidden: true}}, {bypassCollection2: true});
|
||||
await Venues.updateAsync(id, {$set: {hidden: true}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
showVenue: function(id) { //Returns the venue to being simply deactivated. Will again show in lists.
|
||||
showVenue: async function(id) { //Returns the venue to being simply deactivated. Will again show in lists.
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Venues.update(id, {$set: {hidden: false}}, {bypassCollection2: true});
|
||||
await Venues.updateAsync(id, {$set: {hidden: false}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
}
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Mongo } from 'meteor/mongo';
|
||||
import { check } from 'meteor/check';
|
||||
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
|
||||
import 'meteor/aldeed:collection2/static'
|
||||
import SimpleSchema from 'meteor/aldeed:simple-schema';
|
||||
import Measures from "./Measure";
|
||||
|
||||
let Workers = new Mongo.Collection('Workers');
|
||||
|
||||
if(Meteor.isServer) {
|
||||
//Set MongoDB indexes (or remove them) here.
|
||||
try {
|
||||
Workers.rawCollection().createIndex({name: -1}, {unique: true})
|
||||
} catch(e) {console.log("Caught exception while setting indexes in MongoDB"); console.error(e)}
|
||||
}
|
||||
|
||||
let WORKER_ACTIVITIES = ['sales', 'prep', 'canning', 'farming'];
|
||||
let workersSchema = new SimpleSchema({
|
||||
name: {
|
||||
@@ -11,15 +21,18 @@ let workersSchema = new SimpleSchema({
|
||||
label: "Name",
|
||||
optional: false,
|
||||
trim: true,
|
||||
index: 1,
|
||||
unique: true
|
||||
//index: 1,
|
||||
//unique: true
|
||||
},
|
||||
activities: {
|
||||
type: [String],
|
||||
type: Array, //[String],
|
||||
label: "Activities",
|
||||
optional: false,
|
||||
trim: true
|
||||
},
|
||||
'activities.$': {
|
||||
type: String,
|
||||
},
|
||||
hourlyRate: {
|
||||
type: SimpleSchema.Integer,
|
||||
label: "HourlyRate",
|
||||
@@ -66,13 +79,13 @@ if(Meteor.isServer) Meteor.publish('workers', function() {
|
||||
|
||||
if(Meteor.isServer) {
|
||||
Meteor.methods({
|
||||
createWorker: function(name, activities, hourlyRate) {
|
||||
createWorker: async function(name, activities, hourlyRate) {
|
||||
check(name, String);
|
||||
check(activities, [String]);
|
||||
check(hourlyRate, Number);
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Workers.insert({name, activities, hourlyRate, createdAt: new Date()});
|
||||
await Workers.insertAsync({name, activities, hourlyRate, createdAt: new Date()});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
@@ -83,39 +96,39 @@ if(Meteor.isServer) {
|
||||
// }
|
||||
// else throw new Meteor.Error(403, "Not authorized.");
|
||||
//},
|
||||
updateWorker: function(id, name, activities, hourlyRate) {
|
||||
updateWorker: async function(id, name, activities, hourlyRate) {
|
||||
check(id, String);
|
||||
check(name, String);
|
||||
check(activities, [String]);
|
||||
check(hourlyRate, Number);
|
||||
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Workers.update(id, {$set: {name, activities, hourlyRate, updatedAt: new Date()}});
|
||||
await Workers.updateAsync(id, {$set: {name, activities, hourlyRate, updatedAt: new Date()}});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
deactivateWorker: function(id) {
|
||||
deactivateWorker: async function(id) {
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
//Workers.remove(id);
|
||||
Workers.update(id, {$set: {deactivated: true}}, {bypassCollection2: true});
|
||||
await Workers.updateAsync(id, {$set: {deactivated: true}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
reactivateWorker: function(id) {
|
||||
reactivateWorker: async function(id) {
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Workers.update(id, {$set: {deactivated: false}}, {bypassCollection2: true});
|
||||
await Workers.updateAsync(id, {$set: {deactivated: false}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
hideWorker: function(id) { //One step past deactivated - will only show in the Workers list if hidden Workers are enabled.
|
||||
hideWorker: async function(id) { //One step past deactivated - will only show in the Workers list if hidden Workers are enabled.
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Workers.update(id, {$set: {hidden: true}}, {bypassCollection2: true});
|
||||
await Workers.updateAsync(id, {$set: {hidden: true}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
},
|
||||
showWorker: function(id) { //Returns the measure to being simply deactivated. Will again show in lists.
|
||||
showWorker: async function(id) { //Returns the measure to being simply deactivated. Will again show in lists.
|
||||
if(Roles.userIsInRole(this.userId, [Meteor.UserRoles.ROLE_UPDATE])) {
|
||||
Workers.update(id, {$set: {hidden: false}}, {bypassCollection2: true});
|
||||
await Workers.updateAsync(id, {$set: {hidden: false}}, {bypassCollection2: true});
|
||||
}
|
||||
else throw new Meteor.Error(403, "Not authorized.");
|
||||
}
|
||||
|
||||
@@ -20,26 +20,28 @@ Meteor.collections = {Measures, Venues, Products, ProductTags, Sales, SalesSheet
|
||||
//If this is the server then setup the default admin user if none exist.
|
||||
if(Meteor.isServer) {
|
||||
//Change this to find admin users, create a default admin user if none exists.
|
||||
if(Users.find({}).count() === 0) {
|
||||
try {
|
||||
console.log("Creating a default admin user: admin/admin");
|
||||
|
||||
let id = Accounts.createUser({password: 'admin', username: 'admin'});
|
||||
//Requires the alanning:roles package.
|
||||
Roles.addUsersToRoles(id, [Meteor.UserRoles.ROLE_MANAGE, Meteor.UserRoles.ROLE_UPDATE]);
|
||||
Users.countDocuments({}).then((userCount) => {
|
||||
if(userCount === 0) {
|
||||
try {
|
||||
console.log("Creating a default admin user: admin/admin");
|
||||
|
||||
let id = Accounts.createUser({password: 'admin', username: 'admin'});
|
||||
//Requires the alanning:roles package.
|
||||
Roles.addUsersToRoles(id, [Meteor.UserRoles.ROLE_MANAGE, Meteor.UserRoles.ROLE_UPDATE]);
|
||||
}
|
||||
catch(err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
|
||||
Meteor.validators = {};
|
||||
Meteor.validators.ObjectID = Match.Where(function(id) {
|
||||
if(id instanceof Mongo.ObjectID) {
|
||||
id = id._str;
|
||||
}
|
||||
|
||||
check(id, String);
|
||||
return /[0-9a-fA-F]{24}/.test(id);
|
||||
});
|
||||
|
||||
Meteor.validators = {};
|
||||
Meteor.validators.ObjectID = Match.Where(function(id) {
|
||||
if(id instanceof Mongo.ObjectID) {
|
||||
id = id._str;
|
||||
}
|
||||
|
||||
check(id, String);
|
||||
return /[0-9a-fA-F]{24}/.test(id);
|
||||
});
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user