import './Sales.html';
import '/imports/util/selectize/selectize.js'
import ResizeSensor from '/imports/util/resize/ResizeSensor.js';
let QUERY_LIMIT = 20;
let PREFIX = "Sales.";
Meteor.subscribe("products");
Tracker.autorun(function() {
Meteor.subscribe("sales", Session.get(PREFIX + 'searchQuery'), QUERY_LIMIT, Session.get(PREFIX + 'skipCount'));
Session.set(PREFIX + 'saleCount', Meteor.call('getSalesCount', Session.get(PREFIX + 'searchQuery')));
});
Template.Sales.helpers({
sales: function() {
return Meteor.collections.Sales.find({}, {sort: {date: -1, createdAt: -1}});
},
disablePrev: function() {
return (Session.get(PREFIX + 'skipCount') || 0) == 0;
},
disableNext: function() {
return Session.get(PREFIX + 'saleCount') - (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT <= 0;
}
});
Template.Sales.events({
'click .prevButton': function(event, template) {
if(!$(event.target).hasClass('disabled'))
Session.set(PREFIX + 'skipCount', Math.max(0, (Session.get(PREFIX + 'skipCount') || 0) - QUERY_LIMIT));
},
'click .nextButton': function(event, template) {
if(!$(event.target).hasClass('disabled'))
Session.set(PREFIX + 'skipCount', (Session.get(PREFIX + 'skipCount') || 0) + QUERY_LIMIT);
}
});
Template.Sale.onCreated(function() {
});
Template.Sale.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;
},
formatDate: function(date) {
return moment(date).format("MM/DD/YYYY (w)");
},
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;
}
});
Template.Sale.events({
"click .saleRemove": function(event, template) {
let _this = this;
bootbox.confirm({
message: "Delete the sale?",
buttons: {confirm: {label: "Yes", className: 'btn-success'}, cancel: {label: "No", className: "btn-danger"}},
callback: function(result) {
if(result) {
// Meteor.collections.Sales.remove(_this._id);
Meteor.call('deleteSale', _this._id);
}
}
});
}
});
Template.SaleSearch.helpers({
searchValue: function() {
let searchFields = Session.get(PREFIX + 'searchFields');
return (searchFields && searchFields[this.columnName]) ? searchFields[this.columnName] : '';
}
});
Template.SaleSearch.events({
"keyup .searchInput": _.throttle(function(event, template) {
let searchQuery = Session.get(PREFIX + 'searchQuery') || {};
let searchFields = Session.get(PREFIX + 'searchFields') || {};
let searchValue = template.$('.searchInput').val();
if(searchValue) {
if(this.number) searchValue = parseFloat(searchValue);
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);
}, 500)
});
Template.InsertSale.onCreated(function() {
// $('#insertSale').validator();
// $('#insertSale').data('bs.validator');
// this.products = new ReactiveVar([]);
this.selectedDate = new ReactiveVar();
this.selectedProduct = new ReactiveVar();
this.selectedVenue = new ReactiveVar();
});
Template.InsertSale.onRendered(function() {
this.$('.insertSaleForm').validator();
// this.$('[name="product"]').
// this.autorun(function() {
// this.$('[name="product"]').buildCombo(Meteor.collections.Products.find({}).fetch(), {textAttr: 'name', listClass: 'comboList'});
// });
//TODO: Highlight deactivated products in combo
//TODO: Default the price for each size product based on the date.
this.$('[name="product"]').buildCombo({cursor: Meteor.collections.Products.find({$or: [{hidden: false}, {hidden: {$exists:false}}]}), selection: this.selectedProduct, textAttr: 'name', listClass: 'comboList', getClasses: function(data) {
return (data && data.deactivated) ? "deactivated" : "";
}});
this.$('[name="venue"]').buildCombo({cursor: Meteor.collections.Venues.find({}), selection: this.selectedVenue, textAttr: 'name', listClass: 'comboList'});
// this.autorun(function(){
// this.products.set(Meteor.collections.Products.find({}));
// }.bind(this));
});
Template.InsertSale.events({
'change input[name="product"]': function(event, template) {
let selectedId = template.$('input[name="product"]').val();
let selected = Meteor.collections.Products.findOne(selectedId);
template.selectedProduct.set(selected);
},
'change input[name="date"]': function(event, template) {
template.selectedDate.set(moment(event.target.value, "YYYY-MM-DD").toDate());
},
'click input[type="submit"]': function(event, template) {
event.preventDefault();
template.$('.insertSaleForm').data('bs.validator').validate(function(isValid) {
if(isValid) {
let sales = [];
let sale = {
date: moment(template.find("[name='date']").value, "YYYY-MM-DD").toDate(),
productId: template.selectedProduct.get()._id,
venueId: template.selectedVenue.get()._id
};
let insertSaleMeasures = template.$(".insertSaleMeasure");
for(let next = 0; next < insertSaleMeasures.length; next++) {
let nextMeasure = $(insertSaleMeasures[next]);
let measureId = nextMeasure.find(".measureId").val();
let price = parseFloat(nextMeasure.find(".price").val()).toFixed(2);
let amount = parseFloat(nextMeasure.find(".amount").val()).toFixed(2);
if(amount > 0) {
let nextSale = _.clone(sale);
nextSale.measureId = measureId;
nextSale.price = price;
nextSale.amount = amount;
sales.push(nextSale);
}
}
for(let index = 0; index < sales.length; index++) {
let next = sales[index];
//console.log("Inserting: " + JSON.stringify(next));
Meteor.call('insertSale', next, function(error) {
if(error) sAlert.error("Failed to insert the sale!\n" + error);
else sAlert.success("Sale Created");
});
}
}
});
}
});
Template.InsertSale.helpers({
products: function() {
return [{label: "Hermies", value: 1}, {label: "Ralfe", value: 2}, {label: "Bob", value: 3}];
},
productMeasures: function() {
let product = Template.instance().selectedProduct.get();
let result = product ? product.measures : [];
for(let i = 0; i < result.length; i++) {
result[i] = Meteor.collections.Measures.findOne(result[i]);
}
// if(product) console.log("Found " + result.length + " measures for the product " + product.name);
// else console.log("No product!");
return result;
},
venues: function() {
return Meteor.collections.Venues.find({});
}
});
Template.InsertSaleMeasure.onCreated(function() {
let _this = this;
this.price = new ReactiveVar(0);
this.amount = new ReactiveVar(0);
Tracker.autorun(function() {
let date = _this.parentTemplate().selectedDate.get();
let prices = _this.parentTemplate().selectedProduct.get().prices;
let priceData;
let price = 0;
if(prices) priceData = prices[_this.data._id];
//If this product has pricing data for the given measure, then either use the price, or the previousPrice (if there is one and the effectiveDate is after the sale date).
if(priceData) {
if(priceData.effectiveDate && date && moment(priceData.effectiveDate).isAfter(date))
price = priceData.previousPrice;
else
price = priceData.price
}
_this.price.set(price);
});
});
Template.InsertSaleMeasure.events({
'change .price': function(event, template) {
template.price.set(parseFloat($(event.target).val()));
},
'change .amount': function(event, template) {
template.amount.set(parseFloat($(event.target).val()));
}
});
Template.InsertSaleMeasure.helpers({
price: function() {
return Template.instance().price.get().toFixed(2);
},
total: function() {
let template = Template.instance();
return (template.price.get() * template.amount.get()).toFixed(2);
},
amount: function() {
return Template.instance().amount.get();
}
});