import './SaleDuplicates.html';
import '/imports/util/selectize/selectize.js';
import swal from 'sweetalert2';
/**
* 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.
*/
let PREFIX = "SaleDuplicates.";
let DuplicateSales = new Meteor.Collection("duplicateSales");
let duplicateSalesSubscription;
Template.SaleDuplicates.onCreated(function() {
let template = Template.instance();
//Tracker.autorun(function() {
// let query = _.clone(Session.get(PREFIX + 'searchQuery'));
//
// duplicateSalesSubscription = template.subscribe("duplicateSales", query, Session.get(PREFIX + "showHidden"));
//});
Tracker.autorun(function() {
duplicateSalesSubscription = template.subscribe("duplicateSales", null, Session.get(PREFIX + "showHidden"));
});
});
Template.SaleDuplicates.onDestroyed(function() {
if(duplicateSalesSubscription) {
duplicateSalesSubscription.stop();
}
});
Template.SaleDuplicates.helpers({
sales: function() {
let dbQuery = [];
let query = _.clone(Session.get(PREFIX + 'searchQuery'));
if(query) {
// Add each query requirement sent by the client.
_.each(_.keys(query), function(key) {
//if(_.isObject(query[key])) dbQuery.push({[key]: query[key]});
if(_.isObject(query[key])) {
if(query[key].type === 'dateRange') {
if(query[key].start && query[key].end)
dbQuery.push({[key]: {$gte: query[key].start, $lte: query[key].end}});
else if(query[key].start)
dbQuery.push({[key]: {$gte: query[key].start}});
else if(query[key].end)
dbQuery.push({[key]: {$lte: query[key].end}});
// Do nothing if a start and/or end are not provided.
}
else {
dbQuery.push({[key]: query[key]});
}
}
else if(_.isNumber(query[key])) dbQuery.push({[key]: query[key]});
else {
let searchValue = query[key];
let searches = searchValue && searchValue.length > 0 ? searchValue.split(/\s+/) : undefined;
for(let search of searches) {
dbQuery.push({[key]: {$regex: '\\b' + search, $options: 'i'}});
}
}
});
}
if(dbQuery.length > 1) dbQuery = {$and: dbQuery};
else if(dbQuery.length == 1) dbQuery = dbQuery[0];
else dbQuery = {};
return DuplicateSales.find(dbQuery, {sort: {date: -1, productName: 1}});
},
showHidden: function() {
return Session.get(PREFIX + "showHidden") ? "checked": "";
}
});
Template.SaleDuplicates.events({
'click .duplicateScan': function(event, template) {
Meteor.call("markDuplicateSales", function(err, result) {
Meteor.log.error(err);
});
},
'change input[name="showHidden"]': function(event, template) {
//console.log("changed " + $(event.target).prop('checked'));
Session.set(PREFIX + "showHidden", $(event.target).prop('checked'));
}
});
Template.SaleDuplicate.helpers({
//measureName: function(id) {
// return Meteor.collections.Measures.findOne({_id: id}, {fields: {name: 1}}).name;
//},
//venueName: function(id) {
// return Meteor.collections.Venues.findOne({_id: id}, {fields: {name: 1}}).name;
//},
//productName: function(id) {
// return Meteor.collections.Products.findOne({_id: id}, {fields: {name: 1}}).name;
//},
formatDateAndWeek: function(date) {
return moment.utc(date.toString(), "YYYYMMDD").utc().format("MM/DD/YYYY (w)");
},
formatDateTime: function(date) {
return moment.utc(date).format("MM/DD/YYYY");
},
formatPrice: function(price) {
return price.toLocaleString("en-US", {style: 'currency', currency: 'USD', minimumFractionDigits: 2});
},
formatTotalPrice: function(price, amount) {
return (price * amount).toLocaleString("en-US", {style: 'currency', currency: 'USD', minimumFractionDigits: 2});
},
showTotalPrice: function(amount) {
return amount > 1;
},
duplicateClasses: function() {
return this.ignoreDuplicates ? "hidden" : "";
}
});
Template.SaleDuplicate.events({
"click .ignoreDuplicatesButton": function(event, template) {
Meteor.call('ignoreDuplicateSales', this._id, function(err, result) {
if(err) sAlert.error(err);
//else sAlert.success("Duplicates Ignored");
});
},
"click .removeAllDuplicatesButton": function(event, template) {
let _this = this;
swal({
title: "Are you sure?",
text: "This will permanently remove ALL duplicate sales.",
type: "question",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "Yes"
}).then(
function(isConfirm) {
if(isConfirm) {
Meteor.call('removeDuplicateSales', _this._id, function(err, result) {
if(err) sAlert.error(err);
//else sAlert.success("Duplicates Removed");
});
}
},
function(dismiss) {
}
);
},
"click .removeOneDuplicateButton": function(event, template) {
let _this = this;
swal({
title: "Are you sure?",
text: "This will permanently remove ONE duplicate sale.",
type: "question",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "Yes"
}).then(
function(isConfirm) {
if(isConfirm) {
Meteor.call('removeDuplicateSales', _this._id, true, function(err, result) {
if(err) sAlert.error(err);
//else sAlert.success("Duplicates Removed");
});
}
},
function(dismiss) {
}
);
}
});
Template.SaleDuplicateSearch.helpers({
searchValue: function() {
let searchFields = Session.get(PREFIX + 'searchFields');
return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
}
});
Template.SaleDuplicateSearch.events({
"keyup .searchInput": _.throttle(function(event, template) {
let searchQuery = Session.get(PREFIX + 'searchQuery') || {};
let searchFields = Session.get(PREFIX + 'searchFields') || {};
let searchValue = template.$(event.target).val();
if(searchValue) {
if(this.number) searchValue = parseFloat(searchValue);
// A collection name will be provided if there is a related table of data that will contain the text provided and will map to an ID that is then searched for in the current table of data.
// For example we are displaying a table of Sales which has the ID of a Product. The Product table has a Name field and the search box searches for Product Names. The ID's of the Products found should be used to filter the Sales by Product ID.
if(this.collection) {
let ids = Meteor.collections[this.collection].find({[this.collectionQueryColumnName]: {$regex: searchValue, $options: 'i'}}, {fields: {[this.collectionResultColumnName]: 1}}).fetch();
//Convert the ids to an array of ids instead of an array of objects containing an id.
for(let i = 0; i < ids.length; i++) {ids[i] = ids[i]._id;}
searchQuery[this.columnName] = {$in: ids};
searchFields[this.columnName] = searchValue;
}
else {
searchFields[this.columnName] = searchQuery[this.columnName] = searchValue;
}
}
else {
//Remove columns from the search query whose values are empty so we don't bother the database with them.
delete searchQuery[this.columnName];
delete searchFields[this.columnName];
}
Session.set(PREFIX + 'searchQuery', searchQuery);
Session.set(PREFIX + 'searchFields', searchFields);
Session.set(PREFIX + 'skipCount', 0); //Reset the paging of the results.
}, 500)
});