2017-01-15 11:33:37 -08:00
import './Sales.html' ;
2017-02-03 09:20:29 -08:00
import '/imports/util/selectize/selectize.js' ;
2017-05-09 13:51:26 -07:00
import swal from 'sweetalert2' ;
2017-10-08 08:56:15 -07:00
//import 'malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.concat.min.js';
//import 'jquery-mousewheel';
//import 'malihu-custom-scrollbar-plugin';
2017-01-15 11:33:37 -08:00
2017-05-26 11:17:32 -07:00
/ * *
* 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 .
* /
2017-01-17 22:31:43 -08:00
let QUERY _LIMIT = 20 ;
let PREFIX = "Sales." ;
2017-01-15 11:33:37 -08:00
2017-05-26 11:17:32 -07:00
Template . Sales . onCreated ( function ( ) {
Session . set ( PREFIX + "displayNewSale" , false ) ;
2017-05-09 13:51:26 -07:00
2017-05-26 11:17:32 -07:00
Meteor . subscribe ( "products" ) ;
Session . set ( PREFIX + "sortOption" , "date" ) ;
Session . set ( PREFIX + "showOnlyComments" , false ) ;
2017-05-09 13:51:26 -07:00
2017-05-26 11:17:32 -07:00
Tracker . autorun ( function ( ) {
let sortOption = Session . get ( PREFIX + "sortOption" ) ;
let sort = sortOption == 'createdAt' ? { createdAt : - 1 } : { date : - 1 , createdAt : - 1 } ;
let showOnlyComments = Session . get ( PREFIX + "showOnlyComments" ) ;
let query = _ . clone ( Session . get ( PREFIX + 'searchQuery' ) ) ;
if ( showOnlyComments ) {
if ( ! query ) query = { } ;
query . comment = { $exists : true } ;
}
//if(Template.Sales.salesSubscription) Template.Sales.salesSubscription.stop();
Template . Sales . salesSubscription = Meteor . subscribe ( "sales" , query , sort , 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
} ) ;
2017-10-08 08:56:15 -07:00
Template . Sales . onRendered ( function ( ) {
$ ( ".tableContainer" ) . mCustomScrollbar ( {
2017-10-20 14:54:58 -07:00
scrollButtons : { enable : true } ,
theme : "light-thick" ,
scrollbarPosition : "outside" ,
scrollEasing : "linear"
2017-10-08 08:56:15 -07:00
} ) ;
} ) ;
2017-05-26 11:17:32 -07:00
Template . Sales . onDestroyed ( function ( ) {
if ( Template . Sales . salesSubscription ) {
Template . Sales . salesSubscription . stop ( ) ;
}
2017-05-09 13:51:26 -07:00
} ) ;
2017-01-15 11:33:37 -08:00
Template . Sales . helpers ( {
2017-05-09 13:51:26 -07:00
displayNewSale : function ( ) {
return Session . get ( PREFIX + "displayNewSale" ) ;
} ,
2017-01-15 11:33:37 -08:00
sales : function ( ) {
2017-05-09 13:51:26 -07:00
let sortOption = Session . get ( PREFIX + "sortOption" ) ;
return Meteor . collections . Sales . find ( { } , { sort : ( sortOption == 'createdAt' ? { createdAt : - 1 } : { date : - 1 , createdAt : - 1 } ) } ) ;
2017-01-17 22:31:43 -08:00
} ,
disablePrev : function ( ) {
return ( Session . get ( PREFIX + 'skipCount' ) || 0 ) == 0 ;
} ,
disableNext : function ( ) {
return Session . get ( PREFIX + 'saleCount' ) - ( Session . get ( PREFIX + 'skipCount' ) || 0 ) - QUERY _LIMIT <= 0 ;
2017-05-09 13:51:26 -07:00
} ,
editing : function ( ) {
let editedSale = Session . get ( PREFIX + "editedSale" ) ;
return editedSale == this . _id ;
2017-01-17 22:31:43 -08:00
}
} ) ;
Template . Sales . events ( {
2017-05-09 13:51:26 -07:00
'click .newSaleButton' : function ( event , template ) {
if ( template . $ ( '.newSaleButton' ) . hasClass ( 'active' ) ) {
Session . set ( PREFIX + 'displayNewSale' , false ) ;
}
else {
Session . set ( PREFIX + 'displayNewSale' , true ) ;
Session . set ( PREFIX + "editedSale" , undefined ) ; //Clear the edited sale so that only one editor is open at a time.
2017-10-20 14:54:58 -07:00
//Set the focus to the date field of the form. Put this in a timeout so that it is queued for processing after the form is added to the DOM.
setTimeout ( function ( ) {
$ ( "form[name='insertSaleForm'] input[name='date']" ) . focus ( ) ;
} , 10 ) ;
2017-05-09 13:51:26 -07:00
}
template . $ ( '.newSaleButton' ) . toggleClass ( 'active' ) ;
} ,
2017-01-17 22:31:43 -08:00
'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-05-09 13:51:26 -07:00
} ,
'change select[name="sortSelect"]' : function ( event , template ) {
Session . get ( PREFIX + 'skipCount' , 0 ) ;
Session . set ( PREFIX + "sortOption" , $ ( event . target ) . val ( ) ) ;
} ,
'click .showOnlyComments' : function ( event , template ) {
let $button = $ ( event . target ) ;
Session . set ( PREFIX + "showOnlyComments" , ! $button . hasClass ( 'on' ) ) ;
$button . toggleClass ( 'on' ) ;
2017-05-26 11:17:32 -07:00
} ,
'click .showDuplicates' : function ( event , template ) {
FlowRouter . go ( 'SaleDuplicates' ) ;
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 ;
} ,
2017-10-20 14:54:58 -07:00
formatDateAndWeek : function ( date , weekOfYear ) {
return moment . utc ( date . toString ( ) , "YYYYMMDD" ) . utc ( ) . format ( "MM/DD/YYYY" ) + "(" + weekOfYear + ")" ;
2017-01-15 11:33:37 -08:00
} ,
2017-05-26 11:17:32 -07:00
formatDateTime : function ( date ) {
return moment . utc ( date ) . format ( "MM/DD/YYYY" ) ;
2017-05-09 13:51:26 -07:00
} ,
2017-01-15 11:33:37 -08:00
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-05-09 13:51:26 -07:00
} ,
commentClass : function ( ) {
return this . comment ? "hasComment" : "" ;
2017-01-15 11:33:37 -08:00
}
} ) ;
2017-01-17 22:31:43 -08:00
Template . Sale . events ( {
2017-05-09 13:51:26 -07:00
"click .actionEdit" : function ( event , template ) {
Session . set ( PREFIX + "editedSale" , this . _id ) ;
Session . set ( PREFIX + 'displayNewSale' , false ) ; //Ensure the new sale editor is closed.
2017-10-20 14:54:58 -07:00
template . parentTemplate ( ) . $ ( '.newSaleButton' ) . removeClass ( 'active' ) ;
2017-05-09 13:51:26 -07:00
} ,
2017-01-17 22:31:43 -08:00
"click .saleRemove" : function ( event , template ) {
let _this = this ;
2017-05-09 13:51:26 -07:00
swal ( {
title : "Are you sure?" ,
text : "This will permanently remove the sale." ,
type : "question" ,
showCancelButton : true ,
confirmButtonColor : "#DD6B55" ,
confirmButtonText : "Yes"
} ) . then (
function ( isConfirm ) {
if ( isConfirm ) {
2017-01-17 22:31:43 -08:00
// Meteor.collections.Sales.remove(_this._id);
Meteor . call ( 'deleteSale' , _this . _id ) ;
}
2017-05-09 13:51:26 -07:00
} ,
function ( dismiss ) {
}
) ;
} ,
"click .editComment" : function ( event , template ) {
let _this = this ;
swal ( {
title : "Sale Comment" ,
text : "Change the comment, or clear it to remove the comment." ,
input : "textarea" ,
showCancelButton : true ,
closeOnConfirm : true ,
closeOnCancel : true ,
animation : "slide-from-top" ,
inputPlaceholder : "Write a comment..." ,
allowEscapeKey : true ,
inputValue : _this . comment ? _this . comment : ""
} ) . then (
function ( text ) {
Meteor . call ( 'editSaleComment' , _this . _id , text ) ;
} ,
function ( dismiss ) { }
) ;
}
} ) ;
Template . SaleEditor . onCreated ( function ( ) {
this . product = Meteor . collections . Products . findOne ( { _id : this . data . productId } ) ;
2017-05-26 11:17:32 -07:00
this . selectedDate = new ReactiveVar ( moment ( this . data . date . toString ( ) , "YYYYMMDD" ) . toDate ( ) ) ;
2017-05-09 13:51:26 -07:00
this . selectedVenue = new ReactiveVar ( Meteor . collections . Venues . findOne ( { _id : this . data . venueId } ) ) ;
this . price = new ReactiveVar ( this . data . price ) ;
this . amount = new ReactiveVar ( this . data . amount ) ;
} ) ;
Template . SaleEditor . onRendered ( function ( ) {
this . $ ( 'form[name="editSaleForm"]' ) . validator ( ) ;
this . $ ( '[name="venue"]' ) . buildCombo ( { cursor : Meteor . collections . Venues . find ( { } ) , selection : this . selectedVenue , comparator : function ( a , b ) { return a . _id == b . _id ; } , textAttr : 'name' , listClass : 'comboList' } ) ;
this . $ ( 'input[name="date"]' ) . val ( moment ( this . selectedDate . get ( ) ) . format ( "YYYY-MM-DD" ) ) ;
} ) ;
Template . SaleEditor . helpers ( {
measureName : function ( id ) {
let measure = Meteor . collections . Measures . findOne ( { _id : id } , { fields : { name : 1 } } ) ;
return measure ? measure . name : "???" ;
} ,
productName : function ( ) {
let product = Template . instance ( ) . product ;
return product ? product . name : "???" ;
} ,
price : function ( ) {
return Template . instance ( ) . price . get ( ) ;
} ,
amount : function ( ) {
return Template . instance ( ) . amount . get ( ) ;
} ,
total : function ( ) {
let template = Template . instance ( ) ;
return ( template . price . get ( ) * template . amount . get ( ) ) . toFixed ( 2 ) ;
}
} ) ;
Template . SaleEditor . events ( {
'click .setDefaultPrice' : function ( event , template ) {
let date = template . selectedDate . get ( ) ;
let prices = template . product . prices ;
let priceData ;
let price = 0 ;
if ( prices ) priceData = prices [ template . data . measureId ] ;
//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 ) {
2017-05-26 11:17:32 -07:00
if ( priceData . effectiveDate && date && moment . utc ( priceData . effectiveDate . toString ( ) , "YYYYMMDD" ) . isAfter ( date ) )
2017-05-09 13:51:26 -07:00
price = priceData . previousPrice ;
else
price = priceData . price
}
template . price . set ( price ) ;
} ,
'change input[name="date"]' : function ( event , template ) {
template . selectedDate . set ( moment ( event . target . value , "YYYY-MM-DD" ) . toDate ( ) ) ;
} ,
'change .price' : function ( event , template ) {
template . price . set ( parseFloat ( $ ( event . target ) . val ( ) ) ) ;
} ,
'change .amount' : function ( event , template ) {
template . amount . set ( parseFloat ( $ ( event . target ) . val ( ) ) ) ;
} ,
"click .editorCancel" : function ( event , template ) {
Session . set ( PREFIX + "editedSale" , undefined ) ;
} ,
"click .editorApply" : function ( event , template ) {
template . $ ( 'form[name="editSaleForm"]' ) . data ( 'bs.validator' ) . validate ( function ( isValid ) {
if ( isValid ) {
let id = template . data . _id ;
2017-05-26 11:17:32 -07:00
let date = ~ ~ ( moment ( template . selectedDate . get ( ) ) . format ( "YYYYMMDD" ) ) ; // Note: The ~~ is a bitwise not that is a fast method of converting a string to a number.
2017-05-09 13:51:26 -07:00
let venue = template . selectedVenue . get ( ) ;
let price = template . price . get ( ) ;
let amount = template . amount . get ( ) ;
Meteor . call ( "updateSale" , id , date , venue . _id , price , amount , function ( error , result ) {
if ( error ) sAlert . error ( error ) ;
else {
sAlert . success ( "Sale updated." ) ;
Session . set ( PREFIX + "editedSale" , undefined ) ;
}
} ) ;
2017-01-17 22:31:43 -08:00
}
} ) ;
}
} ) ;
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-05-26 11:17:32 -07:00
let searchValue = template . $ ( event . target ) . val ( ) ;
2017-01-15 11:33:37 -08:00
if ( searchValue ) {
if ( this . number ) searchValue = parseFloat ( searchValue ) ;
2017-05-26 11:17:32 -07:00
// 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.
2017-01-15 11:33:37 -08:00
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 ) ;
2017-05-26 11:17:32 -07:00
Session . set ( PREFIX + 'searchFields' , searchFields ) ;
2017-02-03 09:20:29 -08:00
Session . set ( PREFIX + 'skipCount' , 0 ) ; //Reset the paging of the results.
2017-01-15 11:33:37 -08:00
} , 500 )
} ) ;
2017-05-26 11:17:32 -07:00
Template . DateRangeSearch . helpers ( {
startDate : function ( ) {
let searchFields = Session . get ( PREFIX + 'searchFields' ) ;
let searchValue = ( searchFields && searchFields [ this . columnName ] ) ? searchFields [ this . columnName ] : { } ;
return searchValue . start ? moment ( searchValue . start . toString ( ) , "YYYYMMDD" ) . format ( "MM/DD/YYYY" ) : "" ;
} ,
endDate : function ( ) {
let searchFields = Session . get ( PREFIX + 'searchFields' ) ;
let searchValue = ( searchFields && searchFields [ this . columnName ] ) ? searchFields [ this . columnName ] : { } ;
return searchValue . end ? moment ( searchValue . end . toString ( ) , "YYYYMMDD" ) . format ( "MM/DD/YYYY" ) : "" ;
}
} ) ;
Template . DateRangeSearch . events ( {
"change .searchDateStartInput" : function ( event , template ) { Template . DateRangeSearch . dateChanged ( true , event , template ) } ,
"keyup .searchDateStartInput" : _ . throttle ( function ( event , template ) { Template . DateRangeSearch . dateChanged ( true , event , template ) } , 500 ) ,
"change .searchDateEndInput" : function ( event , template ) { Template . DateRangeSearch . dateChanged ( false , event , template ) } ,
"keyup .searchDateEndInput" : _ . throttle ( function ( event , template ) { Template . DateRangeSearch . dateChanged ( false , event , template ) } , 500 )
} ) ;
Template . DateRangeSearch . dateChanged = function ( isStart , event , template ) {
let searchQuery = Session . get ( PREFIX + 'searchQuery' ) || { } ;
let searchFields = Session . get ( PREFIX + 'searchFields' ) || { } ;
let searchValue = template . $ ( event . target ) . val ( ) ;
let columnName = template . data . columnName ;
if ( searchValue ) {
let search = searchQuery [ columnName ] ;
// Create a search object and attach it to the searchFields and searchQuery objects if needed.
if ( ! search ) {
search = { type : 'dateRange' } ;
searchFields [ columnName ] = searchQuery [ columnName ] = search ;
}
// Use moment to parse date and convert it to YYYYMMDD for searching the database.
searchValue = ~ ~ ( moment ( searchValue , searchValue . includes ( "-" ) ? "YYYY-MM-DD" : "MM/DD/YYYY" ) . format ( "YYYYMMDD" ) ) ; // Note: ~~ performs a bitwise not which is a fast method of converting a string to a number.
// Save the search ending date.
isStart ? search . start = searchValue : search . end = searchValue ;
}
else {
if ( searchQuery [ columnName ] ) {
// Remove columns from the search query whose values are empty so we don't bother the database with them.
if ( isStart ) {
delete searchQuery [ columnName ] . start ;
delete searchFields [ columnName ] . start ;
}
else {
delete searchQuery [ columnName ] . end ;
delete searchFields [ columnName ] . end ;
}
}
}
Session . set ( PREFIX + 'searchQuery' , searchQuery ) ;
Session . set ( PREFIX + 'searchFields' , searchFields ) ;
Session . set ( PREFIX + 'skipCount' , 0 ) ; //Reset the paging of the results.
} ;
2017-01-15 11:33:37 -08:00
Template . InsertSale . onCreated ( function ( ) {
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-05-09 13:51:26 -07:00
//TODO: Make the query for products reactive, by putting it inside an autorun block.
//TODO: Fix the combo's change event firing. It does not fire a change event when selecting an item for the first time. It's $(input).val() call also returns the name of the thing selected instead of the selected object.
// Note: The combo will automatically update our selection reactive variable. No need to capture change events.
2017-01-17 22:31:43 -08:00
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' } ) ;
} ) ;
Template . InsertSale . events ( {
2017-05-09 13:51:26 -07:00
//'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);
//},
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 = [ ] ;
2017-05-09 13:51:26 -07:00
let insertSaleMeasures = template . $ ( ".insertSaleMeasure" ) ;
2017-01-15 11:33:37 -08:00
let sale = {
2017-05-26 11:17:32 -07:00
date : ~ ~ ( moment ( template . find ( "[name='date']" ) . value , "YYYY-MM-DD" ) . format ( "YYYYMMDD" ) ) , // Note: ~~ performs a bitwise not which is a fast method of converting a string to a number.
2017-01-15 11:33:37 -08:00
productId : template . selectedProduct . get ( ) . _id ,
venueId : template . selectedVenue . get ( ) . _id
} ;
2017-05-09 13:51:26 -07:00
//Iterate over the measures for the sale (based on the product chosen) and collection amounts and prices.
2017-01-15 11:33:37 -08:00
for ( let next = 0 ; next < insertSaleMeasures . length ; next ++ ) {
let nextMeasure = $ ( insertSaleMeasures [ next ] ) ;
let measureId = nextMeasure . find ( ".measureId" ) . val ( ) ;
2017-05-09 13:51:26 -07:00
let price = parseFloat ( nextMeasure . find ( ".price" ) . val ( ) ) ;
let amount = parseFloat ( nextMeasure . find ( ".amount" ) . val ( ) ) ;
2017-01-15 11:33:37 -08:00
if ( amount > 0 ) {
let nextSale = _ . clone ( sale ) ;
nextSale . measureId = measureId ;
nextSale . price = price ;
nextSale . amount = amount ;
sales . push ( nextSale ) ;
}
}
2017-05-09 13:51:26 -07:00
//Iterate over the product measures that have a quantity greater than zero and add them as a sale.
2017-01-15 11:33:37 -08:00
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 ) ;
2017-05-09 13:51:26 -07:00
else {
sAlert . success ( "Sale Created" ) ;
//Clear the measure quantity fields so the user can enter another sale without the quantities already set.
for ( let next = 0 ; next < insertSaleMeasures . length ; next ++ ) {
let nextMeasure = $ ( insertSaleMeasures [ next ] ) ;
nextMeasure . find ( ".amount" ) . val ( 0 ) ;
}
2017-10-20 14:54:58 -07:00
//Set the focus to the product field of the form.
$ ( "form[name='insertSaleForm'] input[name='product']" ) . focus ( ) ;
//Clear the product since it is highly unlikely the same product will be added twice for the same date and market.
$ ( "form[name='insertSaleForm'] input[name='product']" ) . val ( "" ) ;
2017-05-09 13:51:26 -07:00
}
2017-01-17 22:31:43 -08:00
} ) ;
2017-01-15 11:33:37 -08:00
}
}
} ) ;
}
} ) ;
Template . InsertSale . helpers ( {
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-05-09 13:51:26 -07:00
} ,
'focus input[name="amount"],input[name="price"]' : function ( event , template ) {
//See http://stackoverflow.com/questions/3150275/jquery-input-select-all-on-focus
//Handle selecting the text in the field on receipt of focus.
let $this = $ ( this )
. one ( 'mouseup.mouseupSelect' , function ( ) {
$this . select ( ) ;
return false ;
} )
. one ( 'mousedown' , function ( ) {
// compensate for untriggered 'mouseup' caused by focus via tab
$this . off ( 'mouseup.mouseupSelect' ) ;
} )
. select ( ) ;
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 ( ) ;
}
} ) ;