Added Reports (forgot to commit); Added label prototype.

This commit is contained in:
Wynne Crisman
2019-07-28 13:47:54 -07:00
parent c1183a1470
commit 8211da6b39
13 changed files with 314 additions and 39 deletions

View File

@@ -3,7 +3,7 @@ import { Mongo } from 'meteor/mongo';
import { check } from 'meteor/check';
import {SimpleSchema} from 'meteor/aldeed:simple-schema';
Measures = new Mongo.Collection('Measures');
let Measures = new Mongo.Collection('Measures');
Measures.attachSchema(new SimpleSchema({
name: {
type: String,

View File

@@ -2,17 +2,18 @@ import { Meteor } from 'meteor/meteor';
if(Meteor.isServer) {
WebApp.connectHandlers.use("/reports/AnnualTotals", (req, res, next) => {
const separator = ";";
try {
let result = Meteor.collections.Sales.aggregate([{$group: {_id: {$substr: ['$date', 0, 4]}, total: {$sum: {$multiply: ["$price", "$amount"]}}}}]);
result.toArray().then(function(result) {
res.writeHead(200, {'Content-Type': 'text/csv'});
res.write("Year,Sales Total\n");
res.write("Year" + separator + "Sales Total ($)\n");
for(let i = 0; i < result.length; i++) {
res.write(result[i]._id);
res.write(",");
res.write(separator);
res.write("" + result[i].total);
res.write("\n");
}
@@ -25,13 +26,14 @@ if(Meteor.isServer) {
}
});
WebApp.connectHandlers.use("/reports/MonthlyTotals", (req, res, next) => {
const separator = ";";
try {
let result = Meteor.collections.Sales.aggregate([{$group: {_id: {$substr: ['$date', 0, 6]}, total: {$sum: {$multiply: ["$price", "$amount"]}}}}]);
result.toArray().then(function(result) {
res.writeHead(200, {'Content-Type': 'text/csv'});
res.write("Date,Sales Total\n");
res.write("Date" + separator + "Sales Total ($)\n");
result.sort(function(a, b) {
return parseInt(a._id) - parseInt(b._id);
@@ -39,7 +41,7 @@ if(Meteor.isServer) {
for(let i = 0; i < result.length; i++) {
res.write(result[i]._id.substr(4, 2) + "/" + result[i]._id.substr(0, 4));
res.write(",");
res.write(separator);
res.write("" + result[i].total);
res.write("\n");
}
@@ -51,7 +53,72 @@ if(Meteor.isServer) {
res.end();
}
});
WebApp.connectHandlers.use("/reports/AnnualSaleCountsByMeasure", (req, res, next) => {
const separator = ";";
try {
let result = Meteor.collections.Sales.aggregate([{
$group: {
_id: {$concat: [{$substr: ['$date', 0, 4]}, "-", "$measureId"]},
measureId: {$first: "$measureId"},
year: {$first: {$substr: ['$date', 0, 4]}},
count: {$sum: "$amount"},
total: {$sum: {$multiply: ["$price", "$amount"]}}
}
}]);
result.toArray().then(function(result) {
let totalByYear = {};
//Create a map of maps: year -> measure id -> sales count.
for(let next of result) {
//Get the map of totals by product for the year.
let totalByMeasure = totalByYear[next.year];
//Create the map if necessary.
if(totalByMeasure === undefined) totalByMeasure = totalByYear[next.year] = {};
totalByMeasure[next.measureId] = {count: next.count, total: next.total};
}
//Create a list of ordered measures. We could use a map, but then getting the ordering correct would be difficult.
let measures = Meteor.collections.Measures.find({}, {fields: {_id: 1, name: 1}, sort: {order: 1}}).fetch();
//Collect the years in ascending oder.
let years = Object.keys(totalByYear).sort(function(a, b) {return parseInt(a) - parseInt(b);});
res.writeHead(200, {'Content-Type': 'text/csv'});
res.write("Year" + separator + "Measure" + separator + "Sales Count" + separator + "Sales Total ($)\n");
result.sort(function(a, b) {
return parseInt(a._id) - parseInt(b._id);
});
for(let year of years) {
for(let measure of measures) {
let totals = totalByYear[year][measure._id];
if(totals) {
res.write(year);
res.write(separator);
res.write(measure.name);
res.write(separator);
res.write("" + totals.count);
res.write(separator);
res.write("" + totals.total);
res.write("\n");
}
}
}
res.end();
});
} catch(err) {
console.log(err);
res.end();
}
});
WebApp.connectHandlers.use("/reports/TagTotals", (req, res, next) => {
const separator = ";";
try {
//Aggregate all the sales by product id & year, then later create a map between products and tags to create tag totals.
let result = Meteor.collections.Sales.aggregate([{
@@ -111,7 +178,7 @@ if(Meteor.isServer) {
//Iterate over the years and add them to the headers.
for(let year of years) {
res.write("," + year);
res.write(separator + year);
}
res.write('\n');
@@ -135,7 +202,7 @@ if(Meteor.isServer) {
if(productAnnualTotal) annualTotal += productAnnualTotal;
}
res.write("," + annualTotal);
res.write(separator + annualTotal);
}
res.write('\n');
@@ -201,7 +268,7 @@ if(Meteor.isServer) {
//Iterate over the years and add them to the headers.
for(let year of years) {
res.write(separator + year + " Count" + separator + year + " Total");
res.write(separator + year + " Count" + separator + year + " Total ($)");
}
res.write('\n');

View File

@@ -116,6 +116,13 @@ pri.route('/graphTest', {
BlazeLayout.render('Body', {content: 'GraphTest'});
}
});
pri.route('/labels', {
name: 'Labels',
action: function(params, queryParams) {
require("/imports/ui/Label.js");
BlazeLayout.render('Body', {content: 'LabelMaker'});
}
});
pri.route('/testList', {
name: 'TestList',
action: function(params, queryParams) {

31
imports/ui/Label.html Normal file
View File

@@ -0,0 +1,31 @@
<template name="LabelMaker">
<div id="labelMaker">
<div class="labelOptions"></div>
<div class="labelContents">
<div><label for="title1">Title:</label> <input type="text" name="title1" class="title1 input" value="{{title1}}"/></div>
<div><label for="title2">Title:</label> <input type="text" name="title2" class="title2 input" value="{{title2}}"/></div>
<div><label for="ingredients" style="vertical-align: top">Ingredients:</label> <textarea name="ingredients" class="ingredients">{{ingredients}}</textarea></div>
<div><label for="date">Date:</label> <input type="number" name="date" class="date input" value="{{date}}"/></div>
<div><label for="date">Starting Number:</label> <input type="number" name="startNumber" class="startNumber input" value="{{startNumber}}"/></div>
<div><label for="date">Count:</label> <input type="number" name="count" class="count input" value="{{count}}"/></div>
<div><button name="generate" class="generate">Generate</button></div>
</div>
<div class="labelContainer">
<div class="labelSample label">
<img class="labelLogo" alt="logo" src="/images/PetitTetonLabelLogo_2in Width_v1.png"/>
<div class="labelTagline">We grow it. We can it.</div>
{{{labelText}}}
</div>
</div>
</div>
</template>
<template name="Labels">
{{each label}}
<div class="label">
<img class="labelLogo" alt="logo" src="/images/PetitTetonLabelLogo_2in Width_v1.png"/>
<div class="labelTagline">We grow it. We can it.</div>
{{{labelText}}}
</div>
{{/each}}
</template>

93
imports/ui/Label.import.styl vendored Normal file
View File

@@ -0,0 +1,93 @@
#labelMaker
margin: 10px 20px
height: 100%
width: 100%
.labelContents
label
font-family: TimesNewRoman, Times New Roman, Times
font-weight: 200
font-size: 14px
.title1
width: 500px
font-family: TimesNewRoman, Times New Roman, Times
font-size: .142in
font-weight: 800
line-height: .142in
.title2
width: 500px
font-family: TimesNewRoman, Times New Roman, Times
font-size: 14px
font-weight: 800
line-height: 16px
.ingredients
width: 500px
height: 100px
font-family: TimesNewRoman, Times New Roman, Times
font-size: 12px
font-weight: 100
line-height: 14px
.date
width: 500px
font-family: TimesNewRoman, Times New Roman, Times
font-size: 12px
font-weight: 100
line-height: 14px
.labelContainer
text-align: center
width: 100%
width-min: 3in
height-min: 2in
background-color: grey
padding: 20px
.labelSample
display: inline-block
width: 3in
height: 2in
background-color: white
color: black
text-align: center
.labelLogo
width: .8in
.labelTagline
font-family: TimesNewRoman, Times New Roman, Times
font-size: .1in
font-weight: 100
line-height: .2in
.title1
width: 100%
font-family: TimesNewRoman, Times New Roman, Times
font-size: .2in
font-weight: 800
text-transform: uppercase
.title2
width: 100%
font-family: TimesNewRoman, Times New Roman, Times
font-size: .15in
font-weight: 800
.ingredients
width: 100%
font-family: TimesNewRoman, Times New Roman, Times
font-size: .1in
font-weight: 100
.ingredientsEnding
width: 100%
font-family: TimesNewRoman, Times New Roman, Times
font-size: .1in
font-weight: 100
.instructions
width: 100%
font-family: TimesNewRoman, Times New Roman, Times
font-size: .1in
font-weight: 800
.address
width: 100%
font-family: TimesNewRoman, Times New Roman, Times
font-size: .1in
font-weight: 100
.website
width: 100%
font-family: TimesNewRoman, Times New Roman, Times
font-size: .1in
font-weight: 100

75
imports/ui/Label.js Normal file
View File

@@ -0,0 +1,75 @@
import './Label.html';
import swal from 'sweetalert2';
import dragula from 'dragula';
//******************************************************************
//** Creates printable labels for a roll style printer.
//******************************************************************
let PREFIX = "LabelMaker_";
Template.LabelMaker.onCreated(function() {
});
Template.LabelMaker.onRendered(function() {
let template = this;
});
Template.LabelMaker.onDestroyed(function() {
});
Template.LabelMaker.events({
'change .title1': function(event, template) {
Session.set(PREFIX + "title1", $(event.target).val());
},
'change .title2': function(event, template) {
Session.set(PREFIX + "title2", $(event.target).val());
},
'change .ingredients': function(event, template) {
Session.set(PREFIX + "ingredients", $(event.target).val());
},
'change .date': function(event, template) {
Session.set(PREFIX + "date", parseInt($(event.target).val()));
},
'click .generate': function(event, template) {
}
});
Template.LabelMaker.helpers({
title1: function() {return Session.get(PREFIX + "title1")},
title2: function() {return Session.get(PREFIX + "title2")},
ingredients: function() {return Session.get(PREFIX + "ingredients")},
date: function() {return Session.get(PREFIX + "date")},
labelText: function() {
return "<div class='title1'>" + Session.get(PREFIX + "title1") + "</div>" +
"<div class='title2'>" + Session.get(PREFIX + "title2") + "</div>" +
"<div class='ingredients'><span class='ingredientsPrefix'>Ingredients</span>:" + Session.get(PREFIX + "ingredients") + "</div>" +
"<div class='ingredientsEnding'>*<span style='font-style: oblique'>grown by us</span> <span class='size'>8oz</span> FD1951 (" + Session.get(PREFIX + "date") + ")</div>" +
"<div class='instructions'>Refrigerate after opening; return jar when done</div>" +
"<div class='address'>18601 Hwy 128, Yorkville, CA 95494</div>" +
"<div class='website'>www.PetitTeton.com</div>";
}
});
Template.Labels.onCreated(function() {
});
Template.Labels.onRendered(function() {
let template = this;
});
Template.Labels.onDestroyed(function() {
});
Template.Labels.events({
});
Template.Labels.helpers({
labels: function() {return Session.get(PREFIX + "labels")},
title2: function() {return Session.get(PREFIX + "title2")},
ingredients: function() {return Session.get(PREFIX + "ingredients")},
date: function() {return Session.get(PREFIX + "date")},
labelText: function() {
return "<div class='title1'>" + Session.get(PREFIX + "title1") + "</div>" +
"<div class='title2'>" + Session.get(PREFIX + "title2") + "</div>" +
"<div class='ingredients'><span class='ingredientsPrefix'>Ingredients</span>:" + Session.get(PREFIX + "ingredients") + "</div>" +
"<div class='ingredientsEnding'>*<span style='font-style: oblique'>grown by us</span> <span class='size'>8oz</span> FD1951 (" + Session.get(PREFIX + "date") + ")</div>" +
"<div class='instructions'>Refrigerate after opening; return jar when done</div>" +
"<div class='address'>18601 Hwy 128, Yorkville, CA 95494</div>" +
"<div class='website'>www.PetitTeton.com</div>";
}
});

View File

@@ -5,5 +5,6 @@
<a download="TagTotals.csv" href="/reports/TagTotals">Tag Totals (csv)</a> The total sales ($) are shown by year for each tag. Since multiple tags can be associated with multiple products (N to N relationship), there will likely be overlap in the numbers.<br/>
<a download="TagSalesByMeasure.csv" href="/reports/TagSalesByMeasure">Tag Sales By Measure (csv)</a> This is a table of tags & measures by year. The tags and the measures associated with them are along the vertical column, and the years are horizontal. Both item counts and sales totals ($) are shown for each year.<br/>
<a download="ProductSalesByMeasure.csv" href="/reports/ProductSalesByMeasure">Product Sales By Measure (csv)</a> This is a table of products & product measures by year, showing the sales in terms of unit counts and dollar values for each year, each product, and each product's measure.<br/>
<a download="AnnualSaleCountsByMeasure.csv" href="/reports/AnnualSaleCountsByMeasure">Annual Sale Counts By Measure (csv)</a><br/>
</div>
</template>

View File

@@ -144,7 +144,7 @@ Template.UserEditor.events({
let roles = [];
user.username = template.$('input[name="username"]').val();
user.email = template.$('input[name="email"]').val();
user.emails = [{address: template.$('input[name="email"]').val(), verified: true}]; //Assume it is verified since an administrator is adding it.
let roleSpans = template.$('.role.selected');
for(let i = 0; i < roleSpans.length; i++) {