2017-01-15 11:33:37 -08:00
import readCSV from '/imports/util/csv.js' ;
//Returns the ID of the created or found object.
//This is needed because for some crazy reason upsert only returns the affected document if a document is inserted, otherwise it does not return the ID of the affected document.
2025-07-02 11:18:09 -07:00
async function insertOrCreate ( collection , selector , object ) {
2017-01-15 11:33:37 -08:00
let id ;
2025-07-02 11:18:09 -07:00
let findResult = await collection . findOneAsync ( selector , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( findResult && findResult . _id ) id = findResult . _id ;
2025-07-02 11:18:09 -07:00
else id = await collection . insertAsync ( object ) ;
2017-01-15 11:33:37 -08:00
//
// let result = collection.upsert(selector, {$setOnInsert: object}, {multi: false});
//
// console.log("Upsert result: " + JSON.stringify(result));
//
// if(result && result.insertedId) id = result.insertedId;
// else id = collection.findOne(selector, {fields: {_id: 1}});
if ( ! id ) {
console . log ( "ERROR: Cannot get the ID for " + JSON . stringify ( selector ) ) ;
}
return id ;
}
Meteor . methods ( {
2025-07-02 11:18:09 -07:00
"importBasics" : async function ( ) {
2017-01-15 11:33:37 -08:00
const measures = [
{ name : "Jar 4oz" , postfix : "4oz" , order : 0 , createdAt : new Date ( ) } ,
{ name : "Jar 8oz" , postfix : "8oz" , order : 1 , createdAt : new Date ( ) } ,
{ name : "Jar 12oz" , postfix : "12oz" , order : 2 , createdAt : new Date ( ) } ,
{ name : "Jar 16oz" , postfix : "16oz" , order : 3 , createdAt : new Date ( ) } ,
{ name : "Jar 32oz" , postfix : "32oz" , order : 4 , createdAt : new Date ( ) } ,
{ name : "Pounds" , postfix : "lbs" , order : 5 , createdAt : new Date ( ) } ,
{ name : "Each" , postfix : "" , order : 6 , createdAt : new Date ( ) } ,
{ name : "Bags" , postfix : "bags" , order : 7 , createdAt : new Date ( ) } ,
{ name : "Dozen Large" , postfix : "12/lg" , order : 8 , createdAt : new Date ( ) } ,
{ name : "Dozen Small" , postfix : "12/sm" , order : 9 , createdAt : new Date ( ) } ,
{ name : "Half Dozen Large" , postfix : "6/lg" , order : 10 , createdAt : new Date ( ) } ,
{ name : "Half Dozen Small" , postfix : "6/sm" , order : 11 , createdAt : new Date ( ) }
] ;
const venues = [
{ name : "Boonville" , type : "Farmer's Market" , createdAt : new Date ( ) } ,
{ name : "Clement St" , type : "Farmer's Market" , createdAt : new Date ( ) } ,
{ name : "Ukiah" , type : "Farmer's Market" , createdAt : new Date ( ) } ,
{ name : "Mendocino" , type : "Farmer's Market" , createdAt : new Date ( ) } ,
{ name : "Ft Bragg" , type : "Farmer's Market" , createdAt : new Date ( ) } ,
{ name : "On Farm" , type : "Retail" , createdAt : new Date ( ) } ,
{ name : "Yorkville Market" , type : "Retail" , createdAt : new Date ( ) } ,
{ name : "Yorkville Cellars" , type : "Retail" , createdAt : new Date ( ) } ,
{ name : "Unknown Restaurant" , type : "Restaurant" , createdAt : new Date ( ) } ,
{ name : "Mail Order" , type : "Mail" , createdAt : new Date ( ) } ,
{ name : "Website Order" , type : "Mail" , createdAt : new Date ( ) }
] ;
2025-07-02 11:18:09 -07:00
await Measures . removeAsync ( { } ) ;
await Venues . removeAsync ( { } ) ;
2017-01-15 11:33:37 -08:00
for ( let next of measures ) {
2025-07-02 11:18:09 -07:00
await Measures . insertAsync ( next , function ( error , _id ) {
2017-01-15 11:33:37 -08:00
if ( error ) console . log ( "Failed to insert measure: " + JSON . stringify ( next ) + " ERROR: " + error ) ;
} ) ;
}
for ( let next of venues ) {
2025-07-02 11:18:09 -07:00
await Venues . insertAsync ( next , function ( error , _id ) {
2017-01-15 11:33:37 -08:00
if ( error ) console . log ( "Failed to insert venue: " + JSON . stringify ( next ) + " ERROR: " + error ) ;
} ) ;
}
} ,
2025-07-02 11:18:09 -07:00
"importItems" : async function ( ) {
2017-01-15 11:33:37 -08:00
let fileName = "importItems.csv" ;
//The mapping of model attributes to CSV columns. The oz sizes are arrays of columns since there are multiple.
let map = { } ;
//The id's in the db for the letious jar sizes.
let measureIdMap = { } ;
let hasError = false ;
{
let result ;
2025-07-02 11:18:09 -07:00
result = await Measures . findOneAsync ( { name : 'Jar 4oz' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) measureIdMap [ '4oz' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Jar 4oz" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Measures . findOneAsync ( { name : 'Jar 8oz' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) measureIdMap [ '8oz' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Jar 8oz" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Measures . findOneAsync ( { name : 'Jar 12oz' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) measureIdMap [ '12oz' ] = result . _id
else { console . log ( "Error: Couldn't find the _id for Jar 12oz" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Measures . findOneAsync ( { name : 'Jar 16oz' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) measureIdMap [ '16oz' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Jar 16oz" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Measures . findOneAsync ( { name : 'Jar 32oz' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) measureIdMap [ '32oz' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Jar 32oz" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Measures . findOneAsync ( { name : 'Each' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) measureIdMap [ 'Each' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Each" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Measures . findOneAsync ( { name : 'Bags' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) measureIdMap [ 'Bags' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Bags" ) ; hasError = true ; }
}
// console.log("MeasureIdMap: " + JSON.stringify(measureIdMap));
//Don't proceed if the necessary measures don't exist.
if ( ! hasError ) {
//Collect the metadata from the first row of the CSV data - make a mapping.
function collectMetadata ( firstRow ) {
const CATEGORY = 'category' ;
const SUBCATEGORY = 'subcategory' ;
const ITEM = 'item' ;
const OZ32 = '32 oz' ;
const OZ16 = '16 oz' ;
const OZ12 = '12 oz' ;
const OZ8 = '8 oz' ;
const OZ4 = '4 oz' ;
const BAGS = 'bags' ;
const EACH = 'each' ;
map . oz32 = [ ] ;
map . oz16 = [ ] ;
map . oz12 = [ ] ;
map . oz8 = [ ] ;
map . oz4 = [ ] ;
map . bags = [ ] ;
map . each = [ ] ;
//Data is an array of arrays. firstRow = array of headers. data[1] = first row of data.
//Iterate over the columns to create a mapping.
for ( let i = 0 ; i < firstRow . length ; i ++ ) {
let next = firstRow [ i ] ;
if ( next && next != '' ) {
switch ( next . toLowerCase ( ) ) {
case CATEGORY :
map . category = i ;
break ;
case SUBCATEGORY :
map . subcategory = i ;
break ;
case ITEM :
map . item = i ;
break ;
case OZ32 :
map . oz32 . push ( i ) ;
break ;
case OZ16 :
map . oz16 . push ( i ) ;
break ;
case OZ12 :
map . oz12 . push ( i ) ;
break ;
case OZ8 :
map . oz8 . push ( i ) ;
break ;
case OZ4 :
map . oz4 . push ( i ) ;
break ;
case BAGS :
map . bags . push ( i ) ;
break ;
case EACH :
map . each . push ( i ) ;
break ;
}
}
}
}
//Reads a single row of CSV data and adds it to the database.
2025-07-02 11:18:09 -07:00
async function readRow ( row ) {
2017-01-15 11:33:37 -08:00
let category = row [ map . category ] . trim ( ) ;
let subcategory = row [ map . subcategory ] . trim ( ) ;
let item = row [ map . item ] ;
let oz32 = 0 ;
let oz16 = 0 ;
let oz12 = 0 ;
let oz8 = 0 ;
let oz4 = 0 ;
let bags = 0 ;
let each = 0 ;
for ( let o = 0 ; o < map . oz32 . length ; o ++ ) {
oz32 += Math . max ( row [ map . oz32 [ o ] ] , 0 ) ;
}
for ( let o = 0 ; o < map . oz16 . length ; o ++ ) {
oz16 += Math . max ( row [ map . oz16 [ o ] ] , 0 ) ;
}
for ( let o = 0 ; o < map . oz12 . length ; o ++ ) {
oz12 += Math . max ( row [ map . oz12 [ o ] ] , 0 ) ;
}
for ( let o = 0 ; o < map . oz8 . length ; o ++ ) {
oz8 += Math . max ( row [ map . oz8 [ o ] ] , 0 ) ;
}
for ( let o = 0 ; o < map . oz4 . length ; o ++ ) {
oz4 += Math . max ( row [ map . oz4 [ o ] ] , 0 ) ;
}
for ( let o = 0 ; o < map . bags . length ; o ++ ) {
bags += Math . max ( row [ map . bags [ o ] ] , 0 ) ;
}
for ( let o = 0 ; o < map . each . length ; o ++ ) {
each += Math . max ( row [ map . each [ o ] ] , 0 ) ;
}
// categoryId = insertOrCreate(Categories, {name: category}, {name: category, createdAt: new Date()});
2025-07-02 11:18:09 -07:00
let categoryId = await insertOrCreate ( ProductTags , { name : category } , { name : category , createdAt : new Date ( ) } ) ;
2017-01-15 11:33:37 -08:00
if ( categoryId ) {
// subcategoryId = insertOrCreate(Subcategories, {name: subcategory}, {
// name: subcategory,
// categoryId: categoryId,
// createdAt: new Date()
// });
2025-07-02 11:18:09 -07:00
let subcategoryId = await insertOrCreate ( ProductTags , { name : subcategory } , { name : subcategory , createdAt : new Date ( ) } ) ;
2017-01-15 11:33:37 -08:00
if ( subcategoryId ) {
let weightedMeasures = [ ] ;
let measures = [ ] ;
if ( oz32 > 0 ) weightedMeasures . push ( { name : '32oz' , count : oz32 } ) ;
if ( oz16 > 0 ) weightedMeasures . push ( { name : '16oz' , count : oz16 } ) ;
if ( oz12 > 0 ) weightedMeasures . push ( { name : '12oz' , count : oz12 } ) ;
if ( oz8 > 0 ) weightedMeasures . push ( { name : '8oz' , count : oz8 } ) ;
if ( oz4 > 0 ) weightedMeasures . push ( { name : '4oz' , count : oz4 } ) ;
if ( bags > 0 ) weightedMeasures . push ( { name : 'bags' , count : bags } ) ;
if ( each > 0 ) weightedMeasures . push ( { name : 'each' , count : each } ) ;
if ( weightedMeasures . length == 0 ) {
measures . push ( measureIdMap [ 'Each' ] ) ;
}
else {
//Place the measure that had the most jars at the front of the list.
weightedMeasures . sort ( function ( a , b ) {
return a . count >= b . count ? 1 : - 1 ;
} ) ;
//Build the array of measure id's.
for ( let i = 0 ; i < weightedMeasures . length ; i ++ ) {
measures . push ( measureIdMap [ weightedMeasures [ i ] . name ] ) ;
}
}
//Here we can just insert since we don't care about the resulting ID.
let obj = { name : item , tags : [ categoryId , subcategoryId ] , measures : measures , createdAt : new Date ( ) } ;
2025-07-02 11:18:09 -07:00
await Products . insertAsync ( obj , function ( error ) {
2017-01-15 11:33:37 -08:00
if ( error ) console . log ( "Could not insert the Product: " + JSON . stringify ( obj ) + "\n ERROR: " + error ) ;
} ) ;
}
else {
console . log ( "SubcategoryID: " + subcategoryId ) ;
}
}
else {
console . log ( "CategoryID: " + categoryId ) ;
}
}
2025-07-02 11:18:09 -07:00
readCSV ( fileName , Meteor . bindEnvironment ( async function ( error , data ) {
2017-01-15 11:33:37 -08:00
//csv.read(fileName, function(error, csvData) {
if ( error ) console . log ( "Unable to read the importItems.csv file:" + error ) ;
else {
//Collect the mapping data.
collectMetadata ( data [ 0 ] ) ;
//Remove everything first.
// Items.remove({});
// Subcategories.remove({});
// Categories.remove({});
2025-07-02 11:18:09 -07:00
await Products . removeAsync ( { } ) ;
2017-01-15 11:33:37 -08:00
// console.log("CSV Column Mapping: " + JSON.stringify(map));
// readRow(data[1]);
for ( let i = 1 ; i < data . length ; i ++ ) {
2025-07-02 11:18:09 -07:00
await readRow ( data [ i ] ) ;
2017-01-15 11:33:37 -08:00
}
}
} ) ) ;
}
} ,
2025-07-02 11:18:09 -07:00
"importSales" : async function ( ) {
2017-01-15 11:33:37 -08:00
let fileName = "importSales.csv" ;
//The mapping of model attributes to CSV columns. The oz sizes are arrays of columns since there are multiple.
let map = { } ;
//The id's in the db for the letious jar sizes.
let measureIdMap = { } ;
let venueIdMap = { } ;
let itemIdMap = { } ;
let hasError = false ;
let priceMap = { } ;
let itemAliases = { } ;
//TODO: Trim and lowercase any names.
priceMap [ 2016 ] = {
oz4 : 7 ,
oz8 : 11 ,
oz12 : 13 ,
oz16 : 11 ,
oz32 : 15 ,
"pickled onion, spicy" : { oz16 : 12 } ,
"pickled onion, sweet" : { oz16 : 12 } ,
"pickled onion, fennel" : { oz16 : 12 } ,
"pickled beets" : { oz16 : 15 } ,
"prickly pear margarita mix" : { oz16 : 15 } ,
"prickly pear syrup" : { oz16 : 15 } ,
"tomato sauce" : { oz16 : 15 } , //TODO: Replace all 'tomato sauce, xxxx' with 'tomato sauce' for price lookup only.
"bone broth" : { oz16 : 20 } , //TODO: Replace all 'bone broth, xxxx' with 'bone broth' for price lookup only.
"fava bean soup" : { oz32 : 20 } ,
"pickles, bread butter" : { oz16 : 11 } ,
"kimchi" : { oz16 : 11 } ,
"kraut - red & white" : { oz16 : 11 } ,
"3packs" : { each : 21 } ,
"espelette, smoked" : { each : 1 } ,
"leather" : { each : 6 } ,
"leather, unspecified" : { each : 6 } ,
"leather, apple" : { each : 6 } ,
"leather, grape" : { each : 6 } ,
"leather, peach" : { each : 6 } ,
"leather, persimmon" : { each : 6 } ,
"leather, pumpkin" : { each : 6 } ,
"leather, strawberry" : { each : 6 } ,
"leather, quince" : { each : 6 } ,
"membrillo" : { each : 7 } ,
"membrillo candy" : { each : 2.5 } ,
"spices" : { each : 4 } ,
"spices, unspecified" : { each : 4 } ,
"spices, basil/corriander" : { each : 4 } ,
"spices, fennel" : { each : 4 } ,
"spices, other" : { each : 4 } ,
"spices, pepper" : { each : 4 } ,
"spices, smoked" : { each : 4 } ,
"baba ganoush" : { bags : 8 , oz4 : 8 } ,
"dried, pear" : { bags : 6 } , //Price??
"dried, tomatillo" : { bags : 6 } , //Price??
"dried, strawberry" : { bags : 7.5 } ,
"pesto" : { bags : 8 , each : 8 } ,
"pesto, cilantro jalapeno" : { bags : 8 , each : 8 } ,
"pesto, eggplant" : { bags : 8 , each : 8 } ,
"pesto, mint" : { bags : 8 , each : 8 } ,
"pesto, jalapeno" : { bags : 8 , each : 8 } ,
"jalapeno candy" : { bags : 5 } ,
"dried, tomato" : { bags : 7 } ,
"tomato, dried" : { bags : 7 } ,
"dried tomato" : { bags : 7 } ,
"chipotle peppers" : { each : 5 , bags : 5 } ,
//Fresh
"persimmons" : { lbs : 5 , bags : 5 } ,
"persimmon, frozen" : { lbs : 5 , bags : 5 } ,
"dried, persimmon" : { lbs : 5 , bags : 5 } ,
"eggs" : { each : 11 }
} ;
priceMap [ 2015 ] = {
oz4 : 6 ,
oz8 : 10 ,
oz12 : 13 ,
oz16 : 10 ,
oz32 : 15 ,
"blackberry jam" : { oz4 : 7 , oz8 : 12 } ,
"raspberry jam" : { oz4 : 7 , oz8 : 12 } ,
"blackberry vanilla" : { oz4 : 7 , oz8 : 12 } ,
"bloody mary mix" : { oz16 : 13 } ,
"pickled beets" : { oz16 : 15 } ,
"tomato juice cocktail" : { oz16 : 8 } ,
"fava bean soup" : { oz32 : 20 } ,
"kimchi" : { oz16 : 10 } ,
"kraut - red & white" : { oz16 : 10 } ,
"bread & butter pickles" : { oz16 : 10 } ,
"pickled eggs" : { oz16 : 15 } ,
"3packs" : { each : 18 } ,
"leather" : { each : 6 } ,
"leather, unspecified" : { each : 6 } ,
"leather, apple" : { each : 6 } ,
"leather, grape" : { each : 6 } ,
"leather, peach" : { each : 6 } ,
"leather, persimmon" : { each : 6 } ,
"leather, pumpkin" : { each : 6 , bags : 6 } ,
"leather, strawberry" : { each : 6 , bags : 6 } ,
"leather, quince" : { each : 6 } ,
"membrillo" : { each : 6 } ,
"membrillo candy" : { each : 2.5 , bags : 2.5 } ,
"popsicles" : { each : 5 , bags : 5 } ,
"spices" : { each : 4 } ,
"spices, unspecified" : { each : 4 } ,
"spices, basil/corriander" : { each : 4 } ,
"spices, fennel" : { each : 4 } ,
"spices, other" : { each : 4 } ,
"spices, pepper" : { each : 4 } ,
"spices, smoked" : { each : 4 } ,
"spices, smoked pepper" : { each : 4 } ,
"pesto, mint" : { each : 7 , bags : 7 } ,
"pesto, garlic scape" : { each : 7 , bags : 7 } ,
"pesto, eggplant" : { each : 7 , bags : 7 } ,
"jalapenos" : { each : 5 , bags : 5 } , //? Price guess - only one entry
"membrillo truffles" : { each : 5 , bags : 5 } , //? Price guess - only two entries
"baba ganoush" : { bags : 8 , oz4 : 8 } ,
"dried, pear" : { bags : 6 } , //Price??
"dried, tomatillo" : { bags : 6 } , //Price??
"dried, strawberry" : { bags : 7.5 , each : 7.5 } ,
"dried, tomato" : { bags : 7 } ,
"dried tomato" : { bags : 7 } ,
"jalapeno candy" : { bags : 5 , each : 5 } ,
"eggs" : { each : 10 } ,
} ;
priceMap [ 2014 ] = {
oz4 : 6 ,
oz8 : 9 ,
oz12 : 13 ,
oz16 : 13 ,
oz32 : 20 ,
"3packs" : { bags : 18 , each : 18 } , //????
"kimchi" : { oz16 : 10 } ,
"krauts" : { oz16 : 10 } ,
"pickled eggs" : { oz16 : 13 } ,
"jalapeno candy" : { bags : 5 } , //? Price guess
"eggs" : { each : 7 }
} ;
itemAliases [ "3 packs" ] = "3packs" ;
itemAliases [ "3 pack" ] = "3packs" ;
itemAliases [ "3pack" ] = "3packs" ;
itemAliases [ "Salsa Hot" ] = "Salsa, Hot" ;
itemAliases [ "Sweet Spicy Dipping" ] = "Sweet Spicy Dipping Sauce" ;
itemAliases [ "Spiced Seckel Jam" ] = "Pear Jam, Seckel" ;
itemAliases [ "Spiced Seckle Pear Jam" ] = "Pear Jam, Seckel" ;
itemAliases [ "Spices, Smoked" ] = "Spices, Smoked Pepper" ;
itemAliases [ "Sweet Sour Cabbage" ] = "Sweet Sour Red Cabbage" ;
itemAliases [ "Pickled Onion, Pepper" ] = "Pickled Onions (sweet)" ;
itemAliases [ "Pickled Onion, Spicy" ] = "Pickled Onion Dill w/Espelette" ;
itemAliases [ "Pickled Onion, hot pep" ] = "Pickled Onion Dill w/Espelette" ;
itemAliases [ "Shrub Samplers" ] = "Shrubs" ;
itemAliases [ "Shrub, Anise Hyssop" ] = "Shrubs" ;
itemAliases [ "Shrub, Basil" ] = "Shrubs" ;
itemAliases [ "Shrub, Strawberry Bals" ] = "Shrubs" ;
itemAliases [ "Shrub, Tayberry" ] = "Shrubs" ;
itemAliases [ "Tomato Sauce" ] = "Tomato Sauce, Basil" ;
itemAliases [ "Pickled Onion Hot Pepper" ] = "Pickled Onion Dill w/Espelette" ;
itemAliases [ "Applesauce Honey" ] = "Applesauce, Honey" ;
itemAliases [ "Applesauce Cinnamon" ] = "Applesauce, Cinnamon" ;
itemAliases [ "Applesauce Unsweet" ] = "Applesauce, Unsweetened" ;
itemAliases [ "Applesauce, Unsweet" ] = "Applesauce, Unsweetened" ;
itemAliases [ "Babcock Ginger Jam" ] = "Peach Jam, Babcock w/ Ginger" ;
itemAliases [ "Babcock Lavendar Jam" ] = "Peach Jam, Babcock w/ Lavender" ;
itemAliases [ "Babcock Peach Jam" ] = "Peach Jam, Babcock" ;
itemAliases [ "Bartlett Pear Jam, Vanilla" ] = "Bartlett Vanilla Jam" ;
itemAliases [ "Bartlett Pear Vanilla Jam" ] = "Bartlett Vanilla Jam" ;
itemAliases [ "Blackberry Jam, Mint" ] = "Blackberry Mint Jam" ;
itemAliases [ "Bloody Mary" ] = "Bloody Mary Mix" ;
itemAliases [ "Bread Butter Pickles" ] = "Pickles, Bread Butter" ;
itemAliases [ "Chow Chow Hot" ] = "Chow Chow Spicy" ;
itemAliases [ "Chow Chow, Mild" ] = "Chow Chow Mild" ;
itemAliases [ "Chow Chow, Spicy" ] = "Chow Chow Spicy" ;
itemAliases [ "Chow chow Hot" ] = "Chow Chow Spicy" ;
itemAliases [ "Comice Sherry Jam" ] = "Comice Pear Jam w/ Sherry" ;
itemAliases [ "Dill Pickles" ] = "Pickles, Dill" ;
itemAliases [ "Dried Pear" ] = "Dried, Pear" ;
itemAliases [ "Dried Tomatillo" ] = "Dried, Tomatillo" ;
itemAliases [ "Dried, Tomato" ] = "Dried Tomato" ;
itemAliases [ "Eggplant Pesto" ] = "Pesto, Eggplant" ;
itemAliases [ "Fennel Pickles" ] = "Pickles, Fennel" ;
itemAliases [ "Fig Port Jam" ] = "Fig Jam, Port" ;
itemAliases [ "French Apple Jam" ] = "Apple Jam, French" ;
itemAliases [ "Garlic Scape Pesto" ] = "Pesto, Garlic Scape" ;
itemAliases [ "Ginger Garlic Pickles" ] = "Pickles, Ginger Garlic" ;
itemAliases [ "Green Gage Ginger Jam" ] = "Green Gage Jam w/ Ginger" ;
itemAliases [ "Jujube Ginger Butter" ] = "Jujube & Ginger Butter" ;
itemAliases [ "Leather" ] = "Leather, Unspecified" ;
itemAliases [ "Leek Potato Soup" ] = "Leek & Potato Soup" ;
itemAliases [ "Mint Pesto" ] = "Pesto, Mint" ;
itemAliases [ "Napa Kraut Onion" ] = "Napa Kraut, Onion" ;
itemAliases [ "Peach Jam, Babcock Ginger" ] = "Peach Jam, Babcock w/ Ginger" ;
itemAliases [ "Peach Jam, Babcock Lavender" ] = "Peach Jam, Babcock w/ Lavender" ;
itemAliases [ "Pear Dessert Sauce" ] = "Pear Dessert Topping" ;
itemAliases [ "Pear Ginger Preserve" ] = "Pear Ginger Preserves" ;
itemAliases [ "Pear Jam, Bosc" ] = "Bosc Pear Jam" ;
itemAliases [ "Pear Jam, Comice" ] = "Comice Pear Jam" ;
itemAliases [ "Pear Jam, Sherry" ] = "Comice Pear Jam w/ Sherry" ;
itemAliases [ "Pepper Relish, Spicy" ] = "Spicy Pepper Relish" ;
itemAliases [ "Pepper Relish, Sweet" ] = "Sweet Pepper Relish" ;
itemAliases [ "Pickled Onion Fennel" ] = "Pickled Onions Fennel" ;
itemAliases [ "Pickled Onion, Fennel" ] = "Pickled Onions Fennel" ;
itemAliases [ "Pickled Onion, Sweet" ] = "Pickled Onions (sweet)" ;
itemAliases [ "Pickled Onion, Sweet Pep" ] = "Pickled Onions (sweet)" ;
itemAliases [ "Pickled Onion, Sweet Pepper" ] = "Pickled Onions (sweet)" ;
itemAliases [ "Pickles w/ Fennel" ] = "Pickles, Fennel" ;
itemAliases [ "Plum Jam, Wild" ] = "Wild Plum Jam" ;
itemAliases [ "Plum Syrup, Wild" ] = "Wild Plum Syrup" ;
itemAliases [ "Pumpkin Rollup" ] = "Leather, Pumpkin" ;
itemAliases [ "Rubarb Jam" ] = "Rhubarb Jam" ;
itemAliases [ "Santa Rosa Plum Jam" ] = "Plum Jam, Santa Rosa" ;
itemAliases [ "Saturn Peach Jam" ] = "Peach Jam, Saturn" ;
itemAliases [ "Sauerkraut Red" ] = "Sauerkraut, Red" ;
itemAliases [ "Seckel Pear Jam" ] = "Pear Jam, Seckel" ;
itemAliases [ "Spiced Plum Jam" ] = "Plum Jam, Spiced" ;
itemAliases [ "Spices" ] = "Spices, Unspecified" ;
itemAliases [ "Spices, Basil/Coriander" ] = "Spices, Basil/Corriander" ;
itemAliases [ "Spices, Other" ] = "Spices, Unspecified" ;
itemAliases [ "Strawberry Lavendar Jam" ] = "Strawberry Lavender Jam" ;
itemAliases [ "Sz Broccoli" ] = "Szechuan Broccoli" ;
itemAliases [ "Tomato Sauce Basil" ] = "Tomato Sauce, Basil" ;
itemAliases [ "Tomato Sauce Fennel" ] = "Tomato Sauce, Fennel" ;
itemAliases [ "Tomato Sauce Oregano" ] = "Tomato Sauce, Oregano" ;
itemAliases [ "Tomato, Dried" ] = "Dried Tomato" ;
itemAliases [ "Tomato, dried" ] = "Dried Tomato" ;
itemAliases [ "White Grape Jam" ] = "Grape Jam, White" ;
itemAliases [ "Pepper Syrup" ] = "Spicy Pepper Syrup" ;
itemAliases [ "Apple Prickly Pear" ] = "Applesauce, Prickly Pear" ;
itemAliases [ "Babcock Peach Chutney" ] = "Peach Chutney, Babcock" ;
itemAliases [ "Blackberry Conserve" ] = "Blackberry Hazelnut Conserve" ;
itemAliases [ "Bread Butter Armenian" ] = "Pickles, Bread Butter Armenian" ;
itemAliases [ "Currant Jam" ] = "White Currant Jam" ;
{ //Load the object ids for the measures and venues we will encounter.
let result ;
2025-07-02 11:18:09 -07:00
result = await Measures . findOneAsync ( { name : 'Jar 4oz' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) measureIdMap [ '4oz' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Jar 4oz" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Measures . findOneAsync ( { name : 'Jar 8oz' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) measureIdMap [ '8oz' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Jar 8oz" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Measures . findOneAsync ( { name : 'Jar 12oz' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) measureIdMap [ '12oz' ] = result . _id
else { console . log ( "Error: Couldn't find the _id for Jar 12oz" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Measures . findOneAsync ( { name : 'Jar 16oz' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) measureIdMap [ '16oz' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Jar 16oz" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Measures . findOneAsync ( { name : 'Jar 32oz' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) measureIdMap [ '32oz' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Jar 32oz" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Measures . findOneAsync ( { name : 'Each' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) measureIdMap [ 'Each' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Each" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Measures . findOneAsync ( { name : 'Bags' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) measureIdMap [ 'Bags' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Bags" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Venues . findOneAsync ( { name : 'Boonville' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) venueIdMap [ 'bv' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Boonville" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Venues . findOneAsync ( { name : 'Clement St' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) venueIdMap [ 'sf' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Clement St" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Venues . findOneAsync ( { name : 'Ukiah' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) venueIdMap [ 'uk' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Ukiah" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Venues . findOneAsync ( { name : 'Mendocino' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) venueIdMap [ 'men' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Mendocino" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Venues . findOneAsync ( { name : 'Ft Bragg' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) venueIdMap [ 'fb' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Ft Bragg" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Venues . findOneAsync ( { name : 'On Farm' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) venueIdMap [ 'of' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for On Farm" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Venues . findOneAsync ( { name : 'Unknown Restaurant' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) { venueIdMap [ 'res' ] = result . _id ; venueIdMap [ 'w' ] = result . _id ; }
else { console . log ( "Error: Couldn't find the _id for Unknown Restaurant" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Venues . findOneAsync ( { name : 'Yorkville Market' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) venueIdMap [ 'ym' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Yorkville Market" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Venues . findOneAsync ( { name : 'Yorkville Cellars' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) venueIdMap [ 'yc' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Yorkville Cellars" ) ; hasError = true ; }
2025-07-02 11:18:09 -07:00
result = await Venues . findOneAsync ( { name : 'Mail Order' } , { fields : { _id : 1 } } ) ;
2017-01-15 11:33:37 -08:00
if ( result ) venueIdMap [ 'mo' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Mail Order" ) ; hasError = true ; }
// result = Items.find({}, {fields: {_id: 1, name: 1}, sort: {name: 1}}).fetch();
2025-07-02 11:18:09 -07:00
result = await Products . find ( { } , { fields : { _id : 1 , name : 1 } , sort : { name : 1 } } ) . fetchAsync ( ) ;
2017-01-15 11:33:37 -08:00
for ( let i = 0 ; i < result . length ; i ++ ) itemIdMap [ result [ i ] . name . toLowerCase ( ) ] = result [ i ] . _id ;
//console.log(JSON.stringify(itemIdMap));
}
2025-07-02 11:18:09 -07:00
readCSV ( fileName , Meteor . bindEnvironment ( async function ( error , data ) {
2017-01-15 11:33:37 -08:00
//csv.read(fileName, function(error, csvData) {
//Data is an array of arrays. data[0] = array of headers. data[1] = first row of data.
if ( error ) console . log ( "Unable to read the importSales.csv file:" + error ) ;
else {
//Collect the mapping data.
collectMetadata ( data [ 0 ] ) ;
//Remove everything first.
2025-07-02 11:18:09 -07:00
await Sales . removeAsync ( { "importTag" : "1" } ) ;
2017-01-15 11:33:37 -08:00
// console.log("CSV Column Mapping: " + JSON.stringify(map));
// readRow(data[1]);
let undefinedItems = { } ;
for ( let i = 1 ; i < data . length ; i ++ ) {
2025-07-02 11:18:09 -07:00
await readRow ( data [ i ] , undefinedItems ) ;
2017-01-15 11:33:37 -08:00
}
// let output = "";
// output += "----------------\n";
// output +="Undefined Items:\n";
// output +="Name;32 oz;16 oz;12 oz;8 oz;4 oz;bags;each\n"
//
// let items = [];
// for(let property in undefinedItems) {
// items.push(property);
// }
// items.sort();
// for(let i = 0; i < items.length; i++) {
// let next = items[i];
// let sizes = undefinedItems[next];
//
// // console.log(JSON.stringify(sizes));
// output += next+";"+sizes['32 oz']+";"+sizes['16 oz']+";"+sizes['12 oz']+";"+sizes['8 oz']+";"+sizes['4 oz']+";"+sizes['bags']+";"+sizes['each'] + "\n";
// }
// output += "----------------";
// console.log(output);`
}
} ) ) ;
//Collect the metadata from the first row of the CSV data - make a mapping.
function collectMetadata ( row ) {
let DATE = 'date' ;
let VENUE = 'vendor' ;
let ITEM = 'item' ;
let OZ32 = '32oz' ;
let OZ16 = '16oz' ;
let OZ12 = '12oz' ;
let OZ8 = '8oz' ;
let OZ4 = '4oz' ;
let BAGS = 'bags' ;
let EACH = 'each' ;
//Iterate over the columns to create a mapping.
for ( let i = 0 ; i < row . length ; i ++ ) {
let next = row [ i ] ;
if ( next && next != '' ) {
switch ( next . toLowerCase ( ) ) {
case DATE :
map . date = i ;
break ;
case VENUE :
map . venue = i ;
break ;
case ITEM :
map . item = i ;
break ;
case OZ32 :
map . oz32 = i ;
break ;
case OZ16 :
map . oz16 = i ;
break ;
case OZ12 :
map . oz12 = i ;
break ;
case OZ8 :
map . oz8 = i ;
break ;
case OZ4 :
map . oz4 = i ;
break ;
case BAGS :
map . bags = i ;
break ;
case EACH :
map . each = i ;
break ;
}
}
}
}
//Reads a single row of CSV data and adds it to the database.
2025-07-02 11:18:09 -07:00
async function readRow ( row , undefinedItems ) {
2017-01-15 11:33:37 -08:00
let date = moment ( row [ map . date ] , "M/D/YYYY" ) . toDate ( ) ;
let venue = row [ map . venue ] . toLowerCase ( ) ;
let item = row [ map . item ] . trim ( ) ;
item = itemAliases [ item ] ? itemAliases [ item ] : item ;
item = item . toLowerCase ( ) ;
let oz32 = row [ map . oz32 ] == undefined ? 0 : Number ( row [ map . oz32 ] ) ;
let oz16 = row [ map . oz16 ] == undefined ? 0 : Number ( row [ map . oz16 ] ) ;
let oz12 = row [ map . oz12 ] == undefined ? 0 : Number ( row [ map . oz12 ] ) ;
let oz8 = row [ map . oz8 ] == undefined ? 0 : Number ( row [ map . oz8 ] ) ;
let oz4 = row [ map . oz4 ] == undefined ? 0 : Number ( row [ map . oz4 ] ) ;
let bags = row [ map . bags ] == undefined ? 0 : Number ( row [ map . bags ] ) ;
let each = row [ map . each ] == undefined ? 0 : Number ( row [ map . each ] ) ;
let venueId = venueIdMap [ venue ] ;
let itemId = itemIdMap [ item ] ;
let year = date . getFullYear ( ) ;
if ( venueId == undefined ) {
console . log ( "Found an undefined venue: " + venue ) ;
}
else if ( itemId == undefined ) {
let sizes = undefinedItems [ row [ map . item ] ] || { '32 oz' : 0 , '16 oz' : 0 , '12 oz' : 0 , '8 oz' : 0 , '4 oz' : 0 , 'bags' : 0 , 'each' : 0 } ;
sizes [ '32 oz' ] += oz32 ;
sizes [ '16 oz' ] += oz16 ;
sizes [ '12 oz' ] += oz12 ;
sizes [ '8 oz' ] += oz8 ;
sizes [ '4 oz' ] += oz4 ;
sizes [ 'bags' ] += bags ;
sizes [ 'each' ] += each ;
undefinedItems [ row [ map . item ] ] = sizes ; //Use the capitalized name - will use the mapping back in the calling code to generate a sorted list for sharing with the admin.
}
else if ( priceMap [ year ] == undefined ) {
console . log ( "Unexpected year: " + year ) ;
}
else {
//Split it into multiple sales entries, one for each measure that has a positive value.
if ( oz32 > 0 ) {
let price = priceMap [ year ] [ item ] ;
if ( price != undefined ) price = price [ 'oz32' ] ;
if ( price == undefined ) price = priceMap [ year ] [ 'oz32' ] ;
2025-07-02 11:18:09 -07:00
if ( price ) await insertSale ( { date : date , amount : oz32 , price : price , venueId : venueId , productId : itemId , measureId : measureIdMap [ '32oz' ] } ) ;
2017-01-15 11:33:37 -08:00
else console . log ( "Could not find a price in the year " + year + " for " + item + " in the size oz32" ) ;
}
if ( oz16 > 0 ) {
let price = priceMap [ year ] [ item ] ;
if ( price != undefined ) price = price [ 'oz16' ] ;
if ( price == undefined ) price = priceMap [ year ] [ 'oz16' ] ;
2025-07-02 11:18:09 -07:00
if ( price ) await insertSale ( { date : date , amount : oz16 , price : price , venueId : venueId , productId : itemId , measureId : measureIdMap [ '16oz' ] } ) ;
2017-01-15 11:33:37 -08:00
else console . log ( "Could not find a price in the year " + year + " for " + item + " in the size oz16" ) ;
}
if ( oz12 > 0 ) {
let price = priceMap [ year ] [ item ] ;
if ( price != undefined ) price = price [ 'oz12' ] ;
if ( price == undefined ) price = priceMap [ year ] [ 'oz12' ] ;
2025-07-02 11:18:09 -07:00
if ( price ) await insertSale ( { date : date , amount : oz12 , price : price , venueId : venueId , productId : itemId , measureId : measureIdMap [ '12oz' ] } ) ;
2017-01-15 11:33:37 -08:00
else console . log ( "Could not find a price in the year " + year + " for " + item + " in the size oz12" ) ;
}
if ( oz8 > 0 ) {
let price = priceMap [ year ] [ item ] ;
if ( price != undefined ) price = price [ 'oz8' ] ;
if ( price == undefined ) price = priceMap [ year ] [ 'oz8' ] ;
2025-07-02 11:18:09 -07:00
if ( price ) await insertSale ( { date : date , amount : oz8 , price : price , venueId : venueId , productId : itemId , measureId : measureIdMap [ '8oz' ] } ) ;
2017-01-15 11:33:37 -08:00
else console . log ( "Could not find a price in the year " + year + " for " + item + " in the size oz8" ) ;
}
if ( oz4 > 0 ) {
let price = priceMap [ year ] [ item ] ;
if ( price != undefined ) price = price [ 'oz4' ] ;
if ( price == undefined ) price = priceMap [ year ] [ 'oz4' ] ;
2025-07-02 11:18:09 -07:00
if ( price ) await insertSale ( { date : date , amount : oz4 , price : price , venueId : venueId , productId : itemId , measureId : measureIdMap [ '4oz' ] } ) ;
2017-01-15 11:33:37 -08:00
else console . log ( "Could not find a price in the year " + year + " for " + item + " in the size oz4" ) ;
}
if ( bags > 0 ) {
let price = priceMap [ year ] [ item ] ;
if ( price != undefined ) price = price [ 'bags' ] ;
if ( price == undefined ) price = priceMap [ year ] [ 'bags' ] ;
2025-07-02 11:18:09 -07:00
if ( price ) await insertSale ( { date : date , amount : bags , price : price , venueId : venueId , productId : itemId , measureId : measureIdMap [ 'Bags' ] } ) ;
2017-01-15 11:33:37 -08:00
else {
console . log ( "Could not find a price in the year " + year + " for " + item + " in the size bags" ) ;
}
}
if ( each > 0 ) {
let price = priceMap [ year ] [ item ] ;
if ( price != undefined ) price = price [ 'each' ] ;
if ( price == undefined ) price = priceMap [ year ] [ 'each' ] ;
2025-07-02 11:18:09 -07:00
if ( price ) await insertSale ( { date : date , amount : each , price : price , venueId : venueId , productId : itemId , measureId : measureIdMap [ 'Each' ] } ) ;
2017-01-15 11:33:37 -08:00
else console . log ( "Could not find a price in the year " + year + " for " + item + " in the size each" ) ;
}
}
}
2025-07-02 11:18:09 -07:00
async function insertSale ( sale ) {
2017-01-15 11:33:37 -08:00
sale . createdAt = new Date ( ) ;
2017-02-03 09:20:29 -08:00
sale . importTag = "1" ;
2025-07-02 11:18:09 -07:00
await Sales . insertAsync ( sale , function ( error ) {
2017-01-15 11:33:37 -08:00
if ( error ) console . log ( "Failed to insert the sale: " + JSON . stringify ( sale ) + "\n ERROR: " + error ) ;
2017-02-03 09:20:29 -08:00
} , { bypassCollection2 : true } ) ;
}
} ,
"importSales2" : function ( ) {
let fileName = "importSales2.csv" ;
//The mapping of model attributes to CSV columns. The oz sizes are arrays of columns since there are multiple.
let map = { } ;
//The id's in the db for the letious jar sizes.
let measureIdMap = { } ;
let venueIdMap = { } ;
let itemIdMap = { } ;
let hasError = false ;
{ //Load the object ids for the measures and venues we will encounter.
let result ;
result = Measures . findOne ( { name : 'Pounds' } , { fields : { _id : 1 } } ) ;
if ( result ) measureIdMap [ 'lbs' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Lbs" ) ; hasError = true ; }
result = Measures . findOne ( { name : 'Each' } , { fields : { _id : 1 } } ) ;
if ( result ) measureIdMap [ 'each' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Each" ) ; hasError = true ; }
result = Measures . findOne ( { name : 'Dozen Large' } , { fields : { _id : 1 } } ) ;
if ( result ) measureIdMap [ 'dozen, large' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Dozen, Large" ) ; hasError = true ; }
result = Venues . findOne ( { name : 'Boonville' } , { fields : { _id : 1 } } ) ;
if ( result ) venueIdMap [ 'bv' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Boonville" ) ; hasError = true ; }
result = Venues . findOne ( { name : 'Clement St' } , { fields : { _id : 1 } } ) ;
if ( result ) venueIdMap [ 'sf' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Clement St" ) ; hasError = true ; }
result = Venues . findOne ( { name : 'Ukiah' } , { fields : { _id : 1 } } ) ;
if ( result ) venueIdMap [ 'uk' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Ukiah" ) ; hasError = true ; }
result = Venues . findOne ( { name : 'Mendocino' } , { fields : { _id : 1 } } ) ;
if ( result ) venueIdMap [ 'men' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Mendocino" ) ; hasError = true ; }
result = Venues . findOne ( { name : 'Ft Bragg' } , { fields : { _id : 1 } } ) ;
if ( result ) venueIdMap [ 'fb' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Ft Bragg" ) ; hasError = true ; }
result = Venues . findOne ( { name : 'On Farm' } , { fields : { _id : 1 } } ) ;
if ( result ) venueIdMap [ 'of' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for On Farm" ) ; hasError = true ; }
result = Venues . findOne ( { name : 'Unknown Restaurant' } , { fields : { _id : 1 } } ) ;
if ( result ) { venueIdMap [ 'res' ] = result . _id ; venueIdMap [ 'w' ] = result . _id ; }
else { console . log ( "Error: Couldn't find the _id for Unknown Restaurant" ) ; hasError = true ; }
result = Venues . findOne ( { name : 'Yorkville Market' } , { fields : { _id : 1 } } ) ;
if ( result ) venueIdMap [ 'ym' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Yorkville Market" ) ; hasError = true ; }
result = Venues . findOne ( { name : 'Yorkville Cellars' } , { fields : { _id : 1 } } ) ;
if ( result ) venueIdMap [ 'yc' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Yorkville Cellars" ) ; hasError = true ; }
result = Venues . findOne ( { name : 'Mail Order' } , { fields : { _id : 1 } } ) ;
if ( result ) venueIdMap [ 'mo' ] = result . _id ;
else { console . log ( "Error: Couldn't find the _id for Mail Order" ) ; hasError = true ; }
result = Products . find ( { } , { fields : { _id : 1 , name : 1 } , sort : { name : 1 } } ) . fetch ( ) ;
for ( let i = 0 ; i < result . length ; i ++ ) itemIdMap [ result [ i ] . name . toLowerCase ( ) ] = result [ i ] . _id ;
}
readCSV ( fileName , Meteor . bindEnvironment ( function ( error , data ) {
//Data is an array of arrays. data[0] = array of headers. data[1] = first row of data.
if ( error ) console . log ( "Unable to read the importSales.csv file:" + error ) ;
else {
//Collect the mapping data.
collectMetadata ( data [ 0 ] ) ;
//Remove everything first.
Sales . remove ( { "importTag" : "2" } ) ;
let undefinedItems = { } ;
for ( let i = 1 ; i < data . length ; i ++ ) {
readRow ( data [ i ] , undefinedItems ) ;
}
}
} ) ) ;
//Collect the metadata from the first row of the CSV data - make a mapping.
function collectMetadata ( row ) {
let DATE = 'date' ;
let VENUE = 'vendor' ;
let ITEM = 'item' ;
let LBS = 'lbs' ;
let EACH = 'each' ;
let DOZ = 'dozen, large' ;
let TOTAL = 'total' ;
//Iterate over the columns to create a mapping.
for ( let i = 0 ; i < row . length ; i ++ ) {
let next = row [ i ] ;
if ( next && next != '' ) {
switch ( next . toLowerCase ( ) ) {
case DATE :
map . date = i ;
break ;
case VENUE :
map . venue = i ;
break ;
case ITEM :
map . item = i ;
break ;
case LBS :
map . lbs = i ;
break ;
case EACH :
map . each = i ;
break ;
case DOZ :
map . doz = i ;
break ;
case TOTAL :
map . total = i ;
break ;
}
}
}
}
//Reads a single row of CSV data and adds it to the database.
function readRow ( row , undefinedItems ) {
let date = moment ( row [ map . date ] , "M/D/YYYY" ) . toDate ( ) ;
let venue = row [ map . venue ] ? row [ map . venue ] . toLowerCase ( ) : undefined ;
let item = row [ map . item ] ? row [ map . item ] . trim ( ) : undefined ;
item = item ? item . toLowerCase ( ) : undefined ;
let lbs = row [ map . lbs ] == undefined ? 0 : Number ( row [ map . lbs ] ) ;
let each = row [ map . each ] == undefined ? 0 : Number ( row [ map . each ] ) ;
let doz = row [ map . doz ] == undefined ? 0 : Number ( row [ map . doz ] ) ;
let total = row [ map . total ] == undefined ? 0 : Number ( row [ map . total ] ) ;
let venueId = venueIdMap [ venue ] ;
let itemId = itemIdMap [ item ] ;
let year = date . getFullYear ( ) ;
if ( venueId == undefined ) {
console . log ( "Found an undefined venue: " + venue ) ;
console . log ( row ) ;
}
else if ( itemId == undefined ) {
console . log ( "Error: Could not find the item: '" + item + "'" ) ;
}
else if ( total == undefined || total <= 0 ) {
console . log ( "Error: Invalid total '" + total + "' for the item: '" + item + "'" ) ;
}
else if ( ! ( lbs > 0 || each > 0 || doz > 0 ) ) {
console . log ( "Error: Invalid measures for the item: '" + item + "'" ) ;
}
else {
//Split it into multiple sales entries, one for each measure that has a positive value.
if ( lbs > 0 ) {
let price = total / lbs ;
insertSale ( { date : date , amount : lbs , price : price , venueId : venueId , productId : itemId , measureId : measureIdMap [ 'lbs' ] } ) ;
}
if ( each > 0 ) {
let price = total / each ;
insertSale ( { date : date , amount : each , price : price , venueId : venueId , productId : itemId , measureId : measureIdMap [ 'each' ] } ) ;
}
if ( doz > 0 ) {
let price = total / doz ;
insertSale ( { date : date , amount : doz , price : price , venueId : venueId , productId : itemId , measureId : measureIdMap [ 'dozen, large' ] } ) ;
}
}
}
function insertSale ( sale ) {
sale . createdAt = new Date ( ) ;
sale . importTag = "2" ;
Sales . insert ( sale , function ( error ) {
if ( error ) console . log ( "Failed to insert the sale: " + JSON . stringify ( sale ) + "\n ERROR: " + error ) ;
} , { bypassCollection2 : true } ) ;
2017-01-15 11:33:37 -08:00
}
}
} ) ;