212 lines
7.4 KiB
JavaScript
212 lines
7.4 KiB
JavaScript
|
|
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)
|
|
}); |