2017-01-15 11:33:37 -08:00
import './Sales.html' ;
import '/imports/util/selectize/selectize.js'
import ResizeSensor from '/imports/util/resize/ResizeSensor.js' ;
2017-01-17 22:31:43 -08:00
let QUERY _LIMIT = 20 ;
let PREFIX = "Sales." ;
2017-01-15 11:33:37 -08:00
2017-01-17 22:31:43 -08:00
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' ) ) ) ;
2017-01-15 11:33:37 -08:00
} ) ;
Template . Sales . helpers ( {
sales : function ( ) {
2017-01-17 22:31:43 -08:00
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 ) ;
2017-01-15 11:33:37 -08:00
}
} ) ;
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 ;
}
} ) ;
2017-01-17 22:31:43 -08:00
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 ) ;
}
}
} ) ;
}
} ) ;
2017-01-15 11:33:37 -08:00
2017-01-17 22:31:43 -08:00
Template . SaleSearch . helpers ( {
searchValue : function ( ) {
let searchFields = Session . get ( PREFIX + 'searchFields' ) ;
return ( searchFields && searchFields [ this . columnName ] ) ? searchFields [ this . columnName ] : '' ;
}
} ) ;
2017-01-15 11:33:37 -08:00
Template . SaleSearch . events ( {
"keyup .searchInput" : _ . throttle ( function ( event , template ) {
2017-01-17 22:31:43 -08:00
let searchQuery = Session . get ( PREFIX + 'searchQuery' ) || { } ;
let searchFields = Session . get ( PREFIX + 'searchFields' ) || { } ;
2017-01-15 11:33:37 -08:00
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 ] ;
}
2017-01-17 22:31:43 -08:00
Session . set ( PREFIX + 'searchQuery' , searchQuery ) ;
Session . set ( PREFIX + 'searchFields' , searchFields ) ;
2017-01-15 11:33:37 -08:00
} , 500 )
} ) ;
Template . InsertSale . onCreated ( function ( ) {
// $('#insertSale').validator();
// $('#insertSale').data('bs.validator');
// this.products = new ReactiveVar([]);
2017-01-17 22:31:43 -08:00
this . selectedDate = new ReactiveVar ( ) ;
2017-01-15 11:33:37 -08:00
this . selectedProduct = new ReactiveVar ( ) ;
this . selectedVenue = new ReactiveVar ( ) ;
} ) ;
Template . InsertSale . onRendered ( function ( ) {
2017-01-17 22:31:43 -08:00
this . $ ( '.insertSaleForm' ) . validator ( ) ;
2017-01-15 11:33:37 -08:00
// this.$('[name="product"]').
// this.autorun(function() {
// this.$('[name="product"]').buildCombo(Meteor.collections.Products.find({}).fetch(), {textAttr: 'name', listClass: 'comboList'});
// });
2017-01-17 22:31:43 -08:00
//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" : "" ;
} } ) ;
2017-01-15 11:33:37 -08:00
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 ( {
2017-01-17 22:31:43 -08:00
'change input[name="product"]' : function ( event , template ) {
let selectedId = template . $ ( 'input[name="product"]' ) . val ( ) ;
2017-01-15 11:33:37 -08:00
let selected = Meteor . collections . Products . findOne ( selectedId ) ;
template . selectedProduct . set ( selected ) ;
} ,
2017-01-17 22:31:43 -08:00
'change input[name="date"]' : function ( event , template ) {
template . selectedDate . set ( moment ( event . target . value , "YYYY-MM-DD" ) . toDate ( ) ) ;
} ,
2017-01-15 11:33:37 -08:00
'click input[type="submit"]' : function ( event , template ) {
event . preventDefault ( ) ;
2017-01-17 22:31:43 -08:00
template . $ ( '.insertSaleForm' ) . data ( 'bs.validator' ) . validate ( function ( isValid ) {
2017-01-15 11:33:37 -08:00
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 ] ;
2017-01-17 22:31:43 -08:00
//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" ) ;
} ) ;
2017-01-15 11:33:37 -08:00
}
}
} ) ;
}
} ) ;
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 ] ) ;
}
2017-01-17 22:31:43 -08:00
// if(product) console.log("Found " + result.length + " measures for the product " + product.name);
// else console.log("No product!");
2017-01-15 11:33:37 -08:00
return result ;
} ,
venues : function ( ) {
return Meteor . collections . Venues . find ( { } ) ;
}
} ) ;
Template . InsertSaleMeasure . onCreated ( function ( ) {
2017-01-17 22:31:43 -08:00
let _this = this ;
2017-01-15 11:33:37 -08:00
2017-01-17 22:31:43 -08:00
this . price = new ReactiveVar ( 0 ) ;
2017-01-15 11:33:37 -08:00
this . amount = new ReactiveVar ( 0 ) ;
2017-01-17 22:31:43 -08:00
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 ) ;
} ) ;
2017-01-15 11:33:37 -08:00
} ) ;
Template . InsertSaleMeasure . events ( {
'change .price' : function ( event , template ) {
2017-01-17 22:31:43 -08:00
template . price . set ( parseFloat ( $ ( event . target ) . val ( ) ) ) ;
2017-01-15 11:33:37 -08:00
} ,
'change .amount' : function ( event , template ) {
2017-01-17 22:31:43 -08:00
template . amount . set ( parseFloat ( $ ( event . target ) . val ( ) ) ) ;
2017-01-15 11:33:37 -08:00
}
} ) ;
Template . InsertSaleMeasure . helpers ( {
price : function ( ) {
2017-01-17 22:31:43 -08:00
return Template . instance ( ) . price . get ( ) . toFixed ( 2 ) ;
2017-01-15 11:33:37 -08:00
} ,
total : function ( ) {
let template = Template . instance ( ) ;
2017-01-17 22:31:43 -08:00
return ( template . price . get ( ) * template . amount . get ( ) ) . toFixed ( 2 ) ;
2017-01-15 11:33:37 -08:00
} ,
amount : function ( ) {
return Template . instance ( ) . amount . get ( ) ;
}
} ) ;