diff --git a/package.json b/package.json index 49bb3e0f..02005906 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Dashboard", - "version": "1.1.141", + "version": "1.1.16", "description": "Ottemo Administration Tool", "main": "gulpfile.js", "repository": { @@ -21,10 +21,7 @@ "gulp-imagemin": "^2.0.0", "gulp-inline-css": "^3.0.1", "gulp-jshint": "^1.10.0", - "gulp-livereload": "^3.8.0", "gulp-load-plugins": "^1.2.0", - "gulp-minify-css": "^0.3.13", - "gulp-minify-html": "^0.1.8", "gulp-plumber": "^1.0.1", "gulp-rename": "^1.2.2", "gulp-replace-task": "^0.11.0", diff --git a/src/app/app.scss b/src/app/app.scss index 06961629..58e924f8 100644 --- a/src/app/app.scss +++ b/src/app/app.scss @@ -22,6 +22,7 @@ @import 'login/login'; @import 'order/order'; @import 'product/product'; +@import 'reports/reports'; @import 'seo/seo'; @import 'subscriptions/subscriptions'; @import 'visitor/visitor'; \ No newline at end of file diff --git a/src/app/category/api.service.js b/src/app/category/api.service.js index 934e6aac..2c8ba235 100644 --- a/src/app/category/api.service.js +++ b/src/app/category/api.service.js @@ -52,8 +52,11 @@ angular.module("categoryModule") "addProduct": { method: "POST", params: { - categoryID: "@categoryId", - productID: "@productId" + // this is a post method, but we don't really care about the data as much + // as the params, the `@` extracts the param values from the post data + // so that we don't have to write `addProduct({},params) + categoryID: "@categoryID", + productID: "@productID" }, url: REST_SERVER_URI + "/category/:categoryID/product/:productID" }, diff --git a/src/app/category/edit.controller.js b/src/app/category/edit.controller.js index 027aa3c6..9ee7887e 100644 --- a/src/app/category/edit.controller.js +++ b/src/app/category/edit.controller.js @@ -9,13 +9,15 @@ angular.module("categoryModule") "dashboardUtilsService", "_", function ($scope, $routeParams, $location, $q, categoryApiService, dashboardUtilsService, _) { - var categoryId, rememberProducts, oldProducts, getDefaultCategory; + + var savedProducts = [] + // Initialize SEO if (typeof $scope.initSeo === "function") { $scope.initSeo("category"); } - categoryId = $routeParams.id; + var categoryId = $routeParams.id; if (!categoryId && categoryId !== "new") { $location.path("/categories"); @@ -25,9 +27,7 @@ function ($scope, $routeParams, $location, $q, categoryApiService, dashboardUtil categoryId = null; } - oldProducts = []; - - getDefaultCategory = function () { + function getDefaultCategory() { return { name: "", "parent_id": "", @@ -35,11 +35,6 @@ function ($scope, $routeParams, $location, $q, categoryApiService, dashboardUtil }; }; - /** - * Current selected category - * - * @type {Object} - */ $scope.category = {}; /** @@ -55,7 +50,7 @@ function ($scope, $routeParams, $location, $q, categoryApiService, dashboardUtil var result = response.result || {}; $scope.category = result; $scope.category.parent = $scope.category['parent_id']; - $scope.category.products = $scope.category.product_ids; + savedProducts = $scope.category.product_ids; }); } @@ -64,34 +59,34 @@ function ($scope, $routeParams, $location, $q, categoryApiService, dashboardUtil }; $scope.saveProducts = function () { - var promises = []; - - var categoryId = $scope.category.id || $scope.category._id; - var _prev = $scope.category.product_ids; - var _new = $scope.category.products; - - var products_to_remove = _.difference(_prev,_new); - var products_to_add = _.difference(_new,_prev); - - if (products_to_remove.length){ - _.each(products_to_remove, function(productID){ - promises.push(categoryApiService.removeProduct({ - categoryID: categoryId, - productID: productID - })) - }) - } + var categoryID = $scope.category.id || $scope.category._id; + var newProductList = $scope.category.product_ids; - if (products_to_add.length){ - _.each(products_to_add, function(productID){ - promises.push(categoryApiService.addProduct({ - categoryId: categoryId, - productId: productID - })) - }) - } + var toRemove = _.difference(savedProducts, newProductList); + var toAdd = _.difference(newProductList, savedProducts); + + var promises = _.map(toRemove, removePid); + promises = promises.concat( _.map(toAdd, addPid) ); return $q.all(promises); + + ///////////////// + + function removePid(productID){ + var params = { + categoryID: categoryID, + productID: productID, + }; + return categoryApiService.removeProduct(params).$promise; + } + + function addPid(productID){ + var params = { + categoryID: categoryID, + productID: productID, + }; + return categoryApiService.addProduct(params).$promise; + } }; /** @@ -101,75 +96,81 @@ function ($scope, $routeParams, $location, $q, categoryApiService, dashboardUtil $scope.save = function () { $('[ng-click="save()"]').addClass('disabled').append('').siblings('.btn').addClass('disabled'); - var id, defer, saveSuccess, saveError, updateSuccess, updateError; - defer = $q.defer(); + var defer = $q.defer(); + var id = $scope.category.id || $scope.category._id; + + // Props that aren't recognized by the server + delete $scope.category.parent; + delete $scope.category.path; + delete $scope.category.products; + + if (!id) { + if ($scope.category.name !== '') { + + // Props that aren't recognized by the server + delete $scope.category.product_ids; + + categoryApiService.save($scope.category).$promise + .then(saveSuccess, saveError) + .then(function(){ + savedProducts = $scope.category.product_ids; + }); + } + } else { + $scope.category.id = id; + $scope.saveProducts().then(function () { + + // Props that aren't recognized by the server + delete $scope.category.product_ids; - if (typeof $scope.category !== "undefined") { - id = $scope.category.id || $scope.category._id; + categoryApiService.update($scope.category).$promise + .then(updateSuccess, updateError) + .then(function(){ + savedProducts = $scope.category.product_ids; + }); + }); } - saveSuccess = function (response) { + return defer.promise; + + //////////////// + + function saveSuccess(response) { if (response.error === null) { $scope.category = response.result || getDefaultCategory(); $scope.message = dashboardUtilsService.getMessage(null, 'success', 'Category was created successfully'); defer.resolve(true); } - $('[ng-click="save()"]').removeClass('disabled').children('i').remove(); - $('[ng-click="save()"]').siblings('.btn').removeClass('disabled'); + + allowSaving(); }; - saveError = function () { + function saveError() { defer.resolve(false); - $('[ng-click="save()"]').removeClass('disabled').children('i').remove(); - $('[ng-click="save()"]').siblings('.btn').removeClass('disabled'); + allowSaving(); }; - updateSuccess = function (response) { + function updateSuccess(response) { if (response.error === null) { $scope.category = response.result || getDefaultCategory(); $scope.message = dashboardUtilsService.getMessage(null, 'success', 'Product was updated successfully'); defer.resolve(true); - $('[ng-click="save()"]').removeClass('disabled').children('i').remove(); - $('[ng-click="save()"]').siblings('.btn').removeClass('disabled'); + + allowSaving(); } }; - updateError = function () { + function updateError() { defer.resolve(false); - $('[ng-click="save()"]').removeClass('disabled').children('i').remove(); - $('[ng-click="save()"]').siblings('.btn').removeClass('disabled'); + allowSaving(); }; - delete $scope.category.parent; - delete $scope.category.path; - - - if (!id) { - if ($scope.category.name !== '') { - - delete $scope.category.products; - categoryApiService.save($scope.category).$promise - .then(saveSuccess, saveError) - .then(function(){ - $scope.category.products = $scope.category.product_ids; - }); - } - } else { - $scope.category.id = id; - $scope.saveProducts().then(function () { - - // Clean the associated product list off, before posting up - delete $scope.category.products; - categoryApiService.update($scope.category).$promise - .then(updateSuccess, updateError) - .then(function(){ - $scope.category.products = $scope.category.product_ids; - }); - }); - + // Refactor + function allowSaving() { + $('[ng-click="save()"]').removeClass('disabled').children('i').remove(); + $('[ng-click="save()"]').siblings('.btn').removeClass('disabled'); } - return defer.promise; }; }]); \ No newline at end of file diff --git a/src/app/config/directives/ot-store-date.directive.js b/src/app/config/directives/ot-store-date.directive.js new file mode 100644 index 00000000..4df8773a --- /dev/null +++ b/src/app/config/directives/ot-store-date.directive.js @@ -0,0 +1,40 @@ +angular.module("configModule") + +.directive('otStoreDate', + ['timezoneService', '$filter', + function(timezoneService, $filter) { + return { + restrict: 'EA', + template: '{{localDate}}', + scope: { + 'date' : '=', + }, + link: function(scope, element, attrs) { + + scope.localDate = ''; + + activate(); + + //////////////// + + function activate() { + update(); + scope.$watch('date', update); + } + + function update() { + scope.localDate = scope.date ? 'Loading...' : '-'; + + if (!scope.date) { + return; + } + + timezoneService.get().then(function(tz){ + scope.localDate = $filter('date')(scope.date, 'MM/dd/yyyy hh:mma', tz); + }); + } + } + }; + } +]); + diff --git a/src/app/config/filters/ot-storedate.js b/src/app/config/filters/ot-storedate.js deleted file mode 100644 index 3845bfab..00000000 --- a/src/app/config/filters/ot-storedate.js +++ /dev/null @@ -1,12 +0,0 @@ -angular.module("configModule") - -.filter('otStoreDate', ['timezoneService', '$filter', - function(timezoneService, $filter) { - return function(input) { - if (!input) return ""; - - return $filter('date')(input, 'MM/dd/yyyy hh:mma', timezoneService.storeTz); - } - } -]); - diff --git a/src/app/config/init.js b/src/app/config/init.js index 03a49c1e..9b1d21b1 100644 --- a/src/app/config/init.js +++ b/src/app/config/init.js @@ -1,16 +1,14 @@ -/** - * Config Module - */ -angular.module("configModule", ["ngRoute", "ngResource", "coreModule"]) +angular.module('configModule', [ + 'ngRoute', + 'ngResource', + 'coreModule' +]) -.config(["$routeProvider", function ($routeProvider) { +.config(['$routeProvider', function($routeProvider) { $routeProvider - .when("/settings/:group", { - templateUrl: "/views/config/edit.html", - controller: "configEditController" + .when('/settings/:group', { + templateUrl: '/views/config/edit.html', + controller: 'configEditController', }); -}]) +}]); -.run(['timezoneService', function (timezoneService) { - timezoneService.init(); -}]); \ No newline at end of file diff --git a/src/app/config/service/timezone.js b/src/app/config/service/timezone.js index bca68fc0..c403e566 100644 --- a/src/app/config/service/timezone.js +++ b/src/app/config/service/timezone.js @@ -1,48 +1,30 @@ -//TODO: Consider moving to coreModule angular.module('configModule') -.factory('timezoneService', ['configApiService', '$q', - function(configApiService, $q) { - var storeTz = null; +.factory('timezoneService', ['configApiService', '$q', 'moment', + function(configApiService, $q, moment) { + var tzPromise = false; var service = { get: getTz, makeDateRange: makeDateRange, - init: init, // @deprecated - storeTz: 0, // @deprecated }; return service; //////////////////////// - function init() { - - // Cache the store tz - configApiService.getPath({ - path: 'general.store.timezone' - }).$promise - .then(function(response) { - service.storeTz = response.result.substr(3); - }); - } - function getTz() { - // We have the tz return a promise wrapped value - if (null !== storeTz) { - return $q.resolve(storeTz) - } - var config = { - path: 'general.store.timezone' - }; + if (!tzPromise){ + var config = { path: 'general.store.timezone' }; - return configApiService.getPath(config).$promise - .then(function(response) { - storeTz = response.result.substr(3); - return storeTz - }) + tzPromise = configApiService.getPath(config).$promise + .then(function(response) { + return response.result.substr(3); + }); + } + return tzPromise; } /** @@ -51,7 +33,7 @@ angular.module('configModule') */ function makeDateRange(rangeString) { return getTz().then(function(tz) { - return _make(tz, rangeString) + return _make(tz, rangeString); }); //////////////////////// @@ -62,6 +44,8 @@ angular.module('configModule') var endDate = moment().utcOffset(tz).endOf('day'); switch (rangeString.toLowerCase()) { + case 'all time': + return {}; case 'today': startDate = startDate.startOf('day'); break; @@ -75,11 +59,17 @@ angular.module('configModule') case 'last 30 days': startDate = startDate.subtract(30, 'days').startOf('day'); break; + case 'month to date': + startDate = startDate.startOf('month'); + break; + case 'year to date': + startDate = startDate.startOf('year'); + break; } return { - startDate: startDate, - endDate: endDate + start_date: startDate.toISOString(), + end_date: endDate.toISOString(), }; } } diff --git a/src/app/core/directives/editor/ot-not-editable.html b/src/app/core/directives/editor/ot-not-editable.html index 5b2fe9c8..d449055b 100644 --- a/src/app/core/directives/editor/ot-not-editable.html +++ b/src/app/core/directives/editor/ot-not-editable.html @@ -1,6 +1,7 @@

- - {{ item[attribute.Attribute] | otStoreDate }} + {{ item[attribute.Attribute] }} diff --git a/src/app/core/directives/ot-paginator.directive.js b/src/app/core/directives/ot-paginator.directive.js deleted file mode 100644 index 44671f0b..00000000 --- a/src/app/core/directives/ot-paginator.directive.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * getClass(page) - * setPage(page) - * getPages() - */ -angular.module('coreModule') - -.directive('otPaginator', ['$location', function($location) { - return { - restrict: 'E', - scope: { - 'parent': '=object' - }, - templateUrl: '/views/core/directives/ot-paginator.html', - controller: ['$scope', function($scope) { - - var countNeighbors = 4; - $scope.leftBreak = false; - $scope.rightBreak = false; - - $scope.isNeighbors = function(page) { - return Math.abs($scope.parent.paginator.page - page) <= countNeighbors; - }; - - $scope.$watch('parent.paginator.page', function() { - if (typeof $scope.parent.paginator === 'undefined') { - return true; - } - - var leftBorder = $scope.parent.paginator.page - countNeighbors; - var rightBorder = $scope.parent.paginator.page + countNeighbors; - - if (leftBorder > 2) { - $scope.leftBreak = true; - } - - if (rightBorder < $scope.parent.paginator.countPages - 1) { - $scope.rightBreak = true; - } - - }, true); - }] - }; -}]); - diff --git a/src/app/core/directives/ot-paginator.html b/src/app/core/directives/ot-paginator.html deleted file mode 100644 index f0bea3ec..00000000 --- a/src/app/core/directives/ot-paginator.html +++ /dev/null @@ -1,25 +0,0 @@ - -

- -
diff --git a/src/app/core/directives/ot-table-manager-popup.directive.js b/src/app/core/directives/ot-table-manager-popup.directive.js index b5b50da6..cdd3bd7b 100644 --- a/src/app/core/directives/ot-table-manager-popup.directive.js +++ b/src/app/core/directives/ot-table-manager-popup.directive.js @@ -259,78 +259,10 @@ angular.module("coreModule") return true; }; - /** PAGINATOR */ - - $scope.getPages = function () { - if (typeof $scope.paginator === "undefined") { - return false; - } - var p, result; - result = []; - - for (p = 1; p <= $scope.paginator.countPages; p += 1) { - result.push(p); - } - return result; - }; - - $scope.setPage = function (page) { - if (typeof $scope.paginator === "undefined" || page === $scope.paginator.page) { - return false; - } - - var _setPage = function (page) { - if ("prev" === page && $scope.paginator.page !== 1) { - $scope.paginator.page = $scope.paginator.page - 1; - } else if ("next" === page && $scope.paginator.page !== $scope.paginator.countPages) { - $scope.paginator.page = $scope.paginator.page + 1; - } else if (-1 === ["prev", "next"].indexOf(page)) { - $scope.paginator.page = page; - } else { - return false; - } - - return true; - }; - - if (!_setPage(page)) { - return false; - } - - $("#selectAll").removeAttr("checked"); - isSelectedAll = false; - + $scope.updateSearch = function () { $scope.parent.search = getSearchObj(); }; - /** - * Gets class for item of paginator - * - * @param {string} page - * @returns {string} - */ - $scope.getClass = function (page) { - if (typeof $scope.paginator === "undefined") { - return ''; - } - - var _class; - _class = ''; - - if (page === parseInt($scope.paginator.page, 10)) { - _class = 'active'; - } - - if (("prev" === page && $scope.paginator.page === 1) || - ("next" === page && $scope.paginator.page >= $scope.paginator.countPages)) { - _class = 'disabled'; - } - - return _class; - }; - - /** PAGINATOR END*/ - /** Sorting */ $scope.getSortClass = function (attr) { diff --git a/src/app/core/directives/ot-table-manager-popup.html b/src/app/core/directives/ot-table-manager-popup.html index 28b23055..5333d465 100644 --- a/src/app/core/directives/ot-table-manager-popup.html +++ b/src/app/core/directives/ot-table-manager-popup.html @@ -2,7 +2,17 @@
- +
+
+
+
@@ -64,7 +74,10 @@ {{_item[field.attribute] | currency}} - {{_item[field.attribute] | otStoreDate}} + + @@ -81,7 +94,17 @@ - +
+
+
+
diff --git a/src/app/core/directives/ot-table-manager.directive.js b/src/app/core/directives/ot-table-manager.directive.js index 2e989d76..72b044b2 100644 --- a/src/app/core/directives/ot-table-manager.directive.js +++ b/src/app/core/directives/ot-table-manager.directive.js @@ -224,66 +224,11 @@ angular.module("coreModule") return true; }; - /** PAGINATOR */ - $scope.getPages = function () { - if (typeof $scope.paginator === "undefined") { - return false; - } - var p, result; - result = []; - - for (p = 1; p <= $scope.paginator.countPages; p += 1) { - result.push(p); - } - return result; - }; - - $scope.setPage = function (page) { - if (typeof $scope.paginator === "undefined") { - return false; - } - - if ("prev" === page && $scope.paginator.page !== 1) { - $scope.paginator.page = $scope.paginator.page - 1; - } else if ("next" === page && $scope.paginator.page !== $scope.paginator.countPages) { - $scope.paginator.page = $scope.paginator.page + 1; - } else if (-1 === ["prev", "next"].indexOf(page)) { - $scope.paginator.page = page; - } - + $scope.updateSearch = function () { $location.search(getQueryStr()); }; - /** - * Gets class for item of paginator - * - * @param {string} page - * @returns {string} - */ - $scope.getClass = function (page) { - if (typeof $scope.paginator === "undefined") { - return ''; - } - - var _class; - _class = ''; - - if (page === parseInt($scope.paginator.page, 10)) { - _class = 'active'; - } - - if (("prev" === page && $scope.paginator.page === 1) || - ("next" === page && $scope.paginator.page >= $scope.paginator.countPages)) { - _class = 'disabled'; - } - - return _class; - }; - - /** PAGINATOR END*/ - /** Sorting */ - $scope.getSortClass = function (attr) { var _class = ""; if (attr === $scope.sort.currentValue) { @@ -308,7 +253,6 @@ angular.module("coreModule") $scope.parent.idsSelectedRows[$scope.items[i][$scope.map.id]] = isSelectedAll; } }; - /** Sorting end*/ getQueryStr = function (reset) { diff --git a/src/app/core/directives/ot-table-manager.html b/src/app/core/directives/ot-table-manager.html index e55e4201..42753037 100644 --- a/src/app/core/directives/ot-table-manager.html +++ b/src/app/core/directives/ot-table-manager.html @@ -28,7 +28,17 @@ - +
+
+
+
@@ -95,7 +105,10 @@ {{_item[field.attribute] | currency}} - {{_item[field.attribute] | otStoreDate}} + + @@ -113,7 +126,17 @@ - +
+
+
+
diff --git a/src/app/core/directives/validator/password.js b/src/app/core/directives/validator/password.js deleted file mode 100644 index 8a2b9a19..00000000 --- a/src/app/core/directives/validator/password.js +++ /dev/null @@ -1,50 +0,0 @@ -angular.module("coreModule") - -.directive("otPassword", function() { - return { - restrict: 'EA', - require: '?ngModel', - link: function(scope, elem, attrs, ngModel) { - - var minLength = 6; - var commonPasswords = ['123456', 'password', '12345678', 'thunder', 'dragon', '696969', 'mustang', - 'letmein', 'baseball', 'master', 'michael', 'football', 'shadow', 'monkey', 'abc123', 'fuckme', - 'jordan', 'harley', 'ranger', 'iwantu', 'jennifer', 'hunter', 'batman', 'trustno1', 'thomas', - 'tigger', 'robert', 'access', 'buster', '1234567', 'soccer', 'hockey', 'killer', 'george', - 'andrew', 'charlie', 'superman', 'asshole', 'fuckyou', 'dallas', 'jessica', 'panties', 'pepper', - 'austin', 'william', 'cowboy', 'silver', 'richard', 'fucker', 'orange', 'merlin', 'michelle', - 'corvette', 'bigdog', 'cheese', 'matthew', '121212', 'patrick', 'martin', 'freedom', 'ginger', - 'blowjob', 'nicole', 'sparky', 'yellow', 'camaro', 'secret', 'falcon', 'taylor', '111111', - '131313', '123123' - ]; - - var messages = { - minLength: 'The password should have ' + minLength + ' characters or more.', - common: 'You entered one of the fifty most common passwords, please try something stronger.' - }; - - var validate = function(value) { - - if (!value) return value; - - var valid = true; - if (value.length < minLength) { - valid = false; - ngModel.message = messages.minLength; - } - if (commonPasswords.indexOf(value) >= 0) { - valid = false; - ngModel.message = messages.common; - } - ngModel.$setValidity('ot-password', valid); - return value; - }; - - //For DOM -> model validation - ngModel.$parsers.unshift(validate); - //For model -> DOM validation - ngModel.$formatters.unshift(validate); - } - }; -}); - diff --git a/src/app/core/directives/validator/price.js b/src/app/core/directives/validator/price.js deleted file mode 100644 index 9c45e09b..00000000 --- a/src/app/core/directives/validator/price.js +++ /dev/null @@ -1,27 +0,0 @@ -angular.module("coreModule") - .directive("otPrice", function () { - return { - restrict: 'A', - require: '?ngModel', - link: function (scope, elem, attrs, ngModel) { - - var re = new RegExp("^\\d*\\.*\\d{0,2}$", ""); - var priceNotValid = "not valid price"; - - var validate = function (value) { - var valid = re.test(value); - ngModel.$setValidity('ot-price', valid); - if (!valid) { - ngModel.message = priceNotValid; - } - - return value; - }; - - //For DOM -> model validation - ngModel.$parsers.unshift(validate); - //For model -> DOM validation - ngModel.$formatters.unshift(validate); - } - }; - }); diff --git a/src/app/dashboard/controller.js b/src/app/dashboard/controller.js index 2a9afa7a..2fbbe450 100644 --- a/src/app/dashboard/controller.js +++ b/src/app/dashboard/controller.js @@ -1,13 +1,13 @@ -angular.module("dashboardModule") - -.controller("dashboardController", [ - "$scope", - "$location", - "dashboardStatisticService", - "coreImageService", - "dashboardUtilsService", - "$timeout", - "moment", +angular.module('dashboardModule') + +.controller('dashboardController', [ + '$scope', + '$location', + 'dashboardStatisticService', + 'coreImageService', + 'dashboardUtilsService', + '$timeout', + 'moment', function( $scope, $location, @@ -35,7 +35,7 @@ angular.module("dashboardModule") // Other Widgets $scope.referrers = []; $scope.conversions = {}; - $scope.topSellers = {} + $scope.topSellers = {}; // REFACTOR OUT $scope.getProductImage = getProductImage; @@ -110,7 +110,7 @@ angular.module("dashboardModule") tickAmount: 24, labels: { formatter: function() { - return moment.utc(this.value).format('ha') + return moment.utc(this.value).format('ha'); } } }, diff --git a/src/app/dashboard/menu/service.js b/src/app/dashboard/menu/service.js index 0ae5f5c9..7241afa2 100644 --- a/src/app/dashboard/menu/service.js +++ b/src/app/dashboard/menu/service.js @@ -72,7 +72,7 @@ angular.module('dashboardModule') icon: 'fa-random' }, { title: 'Reports', - link: '/reports/product', + link: '/reports', icon: 'fa-area-chart' }, { title: 'Settings', diff --git a/src/app/dashboard/service/statistic.js b/src/app/dashboard/service/statistic.js index aae8527f..0bef8f6d 100644 --- a/src/app/dashboard/service/statistic.js +++ b/src/app/dashboard/service/statistic.js @@ -1,171 +1,203 @@ -angular.module("dashboardModule") -/** -* dashboardStatisticService implementation -*/ -.service("dashboardStatisticService", [ -"dashboardApiService", -"$q", -"moment", -function ($api, $q, moment) { - - - var getReferrers = function () { - return $api.getReferrers().$promise.then(function (response) { - return response.result; - }); - }; - - var getVisits = function () { - - return $api.getVisits().$promise.then(function (response) { - - var defaults = { - // total: {today: 0, yesterday: 0, week: 0}, - total: {today: moment().milliseconds(), yesterday: 0, week: 0}, - unique: {today: 0, yesterday: 0, week: 0} +angular.module('dashboardModule') + +.service('dashboardStatisticService', [ + 'dashboardApiService', + '$q', + 'moment', + '_', + function( + $api, + $q, + moment, + _ + ) { + + var service = { + getReferrers: getReferrers, + getVisits: getVisits, + getVisitsDetail: getVisitsDetail, + getConversions: getConversions, + getSales: getSales, + getSalesDetail: getSalesDetail, + getTopSellers: getTopSellers, + getVisitorsOnline: getVisitorsOnline, + }; + + return service; + + ////////////////////////////// + + function getReferrers() { + return $api.getReferrers().$promise.then(function(response) { + return response.result; + }); + } + + function getVisits() { + + return $api.getVisits().$promise.then(function(response) { + + var defaults = { + total: { today: 0, yesterday: 0, week: 0 }, + unique: { today: 0, yesterday: 0, week: 0 }, + }; + + return response.result || defaults; + }); + } + + function getSales() { + + return $api.getSales().$promise + .then(function(response) { + var defaults = { + sales: { today: 0, yesterday: 0, week: 0, monthToDate: 0}, + orders: { today: 0, yesterday: 0, week: 0, monthToDate: 0}, + }; + + return response.result || defaults; + }) + .then(function(result){ + // Add in average cart size + result.salesAvg = { + today: getAverageOrderSize('today'), + yesterday: getAverageOrderSize('yesterday'), + week: getAverageOrderSize('week'), + monthToDate: getAverageOrderSize('monthToDate'), + }; + + return result; + + ////// + + function getAverageOrderSize(param) { + if (!result.orders[param]) { + return 0; + } + return (result.sales[param] / result.orders[param]).toFixed(2); + } + }); + } + + function _processDetailResponse(points) { + + // Split into two sets + var set1 = points.splice(0, 24).map(function(point) { + var pointTime = point[0]; + pointTime = moment.unix(pointTime).add(1, 'day').valueOf(); + + return [pointTime, point[1]]; + }); + + var set2 = points.map(function(point) { + var pointTime = point[0]; + pointTime = moment.unix(pointTime).valueOf(); + + return [pointTime, point[1]]; + }); + + // z-index insures that today is on top + var dataSets = [{ + name: 'Today', + data: set2, + zIndex: 2 + }, { + name: 'Yesterday', + data: set1, + zIndex: 1 + }, ]; + + return dataSets; + } + + function getVisitsDetail() { + + var options = { + 'from': moment().subtract(1, 'day').format('YYYY-MM-DD'), + 'to': moment().add(1, 'day').format('YYYY-MM-DD') }; - // return defaults - return response.result || defaults; - }); - }; - - var getSales = function () { - - return $api.getSales().$promise.then(function (response) { - var defaults = { - // sales: {today: 0, yesterday: 0, week: 0}, - sales: {today: moment().milliseconds() * 102, yesterday: 0, week: 0}, - orders: {today: 0, yesterday: 0, week: 0} + + return $api.getVisitsDetails(options).$promise.then(function(response) { + return _processDetailResponse(response.result); + }); + } + + function getSalesDetail() { + var options = { + 'from': moment().subtract(1, 'day').format('YYYY-MM-DD'), + 'to': moment().add(1, 'day').format('YYYY-MM-DD') }; - // return defaults - return response.result || defaults; - }); - }; - var _processDetailResponse = function(points) { + return $api.getSalesDetails(options).$promise.then(function(response) { + return _processDetailResponse(response.result); + }); + } - // Split into two sets - var set1 = points.splice(0,24).map(function(point){ - var pointTime = point[0]; - pointTime = moment.unix(pointTime).add(1,'day').valueOf(); + function getConversions() { - return [pointTime, point[1]]; - }); + var getPercents = function(val, total) { + return Math.round((Math.abs(val / total) * 100) * 100) / 100 || 0; + }; - var set2 = points.map(function(point){ - var pointTime = point[0]; - pointTime = moment.unix(pointTime).valueOf(); + return $api.getConversions().$promise.then(function(response) { + var result = response.result || []; + var conversion = {}; - return [pointTime, point[1]]; - }); + if (null === response.error) { + conversion.addedToCart = result.addedToCart; + conversion.addedToCartPercent = getPercents(result.addedToCart, result.totalVisitors); - // z-index insures that today is on top - var dataSets = [ - {name: 'Today', data: set2, zIndex: 2}, - {name: 'Yesterday', data: set1, zIndex: 1}, - ]; + conversion.purchased = result.purchased; + conversion.purchasedPercent = getPercents(result.purchased, result.totalVisitors); - return dataSets; - } + conversion.reachedCheckout = result.visitCheckout; + conversion.reachedCheckoutPercent = getPercents(result.visitCheckout, result.totalVisitors); - var getVisitsDetail = function () { + conversion.setPayment = result.setPayment; + conversion.setPaymentPercent = getPercents(result.setPayment, result.totalVisitors); - var options = { - "from": moment().subtract(1,'day').format('YYYY-MM-DD'), - "to": moment().add(1,'day').format('YYYY-MM-DD') - }; + conversion.totalVisitors = result.totalVisitors; + } - return $api.getVisitsDetails(options).$promise.then(function (response) { - return _processDetailResponse(response.result); - }); - }; + return conversion; + }); + } - var getSalesDetail = function () { - var options = { - "from": moment().subtract(1,'day').format('YYYY-MM-DD'), - "to": moment().add(1,'day').format('YYYY-MM-DD') - }; + function getTopSellers() { + return $api.getTopSellers().$promise.then(function(response) { + return response.result; + }); + } - return $api.getSalesDetails(options).$promise.then(function (response) { - return _processDetailResponse(response.result); - }); - }; + function getVisitorsOnline() { + var defer; + defer = $q.defer(); + $api.getVisitorsOnline().$promise.then(function(response) { + var result, visitorsDetail; - var getConversions = function () { + result = response.result || []; + visitorsDetail = {}; - var getPercents = function (val, total) { - return Math.round((Math.abs(val/total) * 100) * 100) / 100 || 0; - }; + if (null === response.error) { + + visitorsDetail.direct = result.Direct; + visitorsDetail.directRatio = (Math.abs(result.DirectRatio) * 100).toFixed(2); + visitorsDetail.online = result.Online; + visitorsDetail.onlineRatio = (Math.abs(result.OnlineRatio) * 100).toFixed(2); + visitorsDetail.search = result.Search; + visitorsDetail.searchRatio = (Math.abs(result.SearchRatio) * 100).toFixed(2); + visitorsDetail.site = result.Site; + visitorsDetail.siteRatio = (Math.abs(result.SiteRatio) * 100).toFixed(2); + + defer.resolve(visitorsDetail); + } else { + defer.resolve(visitorsDetail); + } + }); + + return defer.promise; + } + } +]); - return $api.getConversions().$promise.then(function (response) { - var result = response.result || []; - var conversion = {}; - - if (null === response.error) { - conversion.addedToCart = result["addedToCart"]; - conversion.addedToCartPercent = getPercents(result["addedToCart"], result["totalVisitors"]); - - conversion.purchased = result["purchased"]; - conversion.purchasedPercent = getPercents(result["purchased"], result["totalVisitors"]); - - conversion.reachedCheckout = result["visitCheckout"]; - conversion.reachedCheckoutPercent = getPercents(result["visitCheckout"], result["totalVisitors"]); - - conversion.setPayment = result["setPayment"]; - conversion.setPaymentPercent = getPercents(result["setPayment"], result["totalVisitors"]); - - conversion.totalVisitors = result["totalVisitors"]; - } - - return conversion; - }); - }; - - var getTopSellers = function () { - return $api.getTopSellers().$promise.then(function (response) { - return response.result; - }); - }; - - var getVisitorsOnline = function () { - var defer; - defer = $q.defer(); - - $api.getVisitorsOnline().$promise.then(function (response) { - var result, visitorsDetail; - - result = response.result || []; - visitorsDetail = {}; - - if (null === response.error) { - - visitorsDetail["direct"] = result.Direct; - visitorsDetail["directRatio"] = (Math.abs(result.DirectRatio) * 100).toFixed(2); - visitorsDetail["online"] = result.Online; - visitorsDetail["onlineRatio"] = (Math.abs(result.OnlineRatio) * 100).toFixed(2); - visitorsDetail["search"] = result.Search; - visitorsDetail["searchRatio"] = (Math.abs(result.SearchRatio) * 100).toFixed(2); - visitorsDetail["site"] = result.Site; - visitorsDetail["siteRatio"] = (Math.abs(result.SiteRatio) * 100).toFixed(2); - - defer.resolve(visitorsDetail); - } else { - defer.resolve(visitorsDetail); - } - }); - - return defer.promise; - }; - - return { - getReferrers: getReferrers, - getVisits: getVisits, - getVisitsDetail: getVisitsDetail, - getConversions: getConversions, - getSales: getSales, - getSalesDetail: getSalesDetail, - getTopSellers: getTopSellers, - getVisitorsOnline: getVisitorsOnline - }; -}]); diff --git a/src/app/dashboard/welcome.html b/src/app/dashboard/welcome.html index cd320b8f..1915df41 100644 --- a/src/app/dashboard/welcome.html +++ b/src/app/dashboard/welcome.html @@ -19,6 +19,7 @@

Sales

+ @@ -26,21 +27,25 @@

Sales

+ + + +
Total Sales Order CountSales Avg.
Today $ $
Yesterday {{salesStats.sales.yesterday | currency}} {{salesStats.orders.yesterday}}{{salesStats.salesAvg.yesterday | currency}}
Last 7 days {{salesStats.sales.week | currency}} {{salesStats.orders.week}}{{salesStats.salesAvg.week | currency}}
Month to date {{salesStats.sales.monthToDate | currency}} {{salesStats.orders.monthToDate}}{{salesStats.salesAvg.monthToDate | currency}}
diff --git a/src/app/discounts/api.service.js b/src/app/discounts/api.service.js index 4ca19c24..f19b4fb2 100644 --- a/src/app/discounts/api.service.js +++ b/src/app/discounts/api.service.js @@ -1,4 +1,4 @@ -angular.module("discountsModule") +angular.module('discountsModule') /** * code @@ -9,12 +9,19 @@ angular.module("discountsModule") * percent * times */ -.service("discountsService", [ - "$http", - "REST_SERVER_URI", - "moment", - "timezoneService", - function($http, REST_SERVER_URI, moment, timezoneService) { +.service('discountsService', [ + '$http', + '$q', + 'REST_SERVER_URI', + 'moment', + 'timezoneService', + function( + $http, + $q, + REST_SERVER_URI, + moment, + timezoneService + ) { var _url = REST_SERVER_URI + '/coupons'; var service = { @@ -31,61 +38,66 @@ angular.module("discountsModule") //////////////////////////// function _transformResponse(discountSource) { - var _storeTz = timezoneService.storeTz; - var discount = {}; + return timezoneService.get().then(adjustDiscount); - angular.merge(discount, defaults(), discountSource); + function adjustDiscount(tz) { + var discount = {}; - // We aren't currently recognizing this - delete discount.name; + angular.merge(discount, defaults(), discountSource); - // Process the datetime into the storefront tz - discount.sinceLocal = moment(discount.since).utcOffset(_storeTz).format('YYYY-MM-DD HH:mm'); - discount.untilLocal = moment(discount.until).utcOffset(_storeTz).format('YYYY-MM-DD HH:mm'); + // We aren't currently recognizing this property + delete discount.name; - // hack for handling target - if ( ['order','cart'].indexOf(discount.target) === -1 ) { - // extra hack because the list comes back as a string of json `"[123,234]"` - discount.target_line_items = angular.fromJson(discount.target); - discount.target = 'product'; - } else { - discount.target = 'order'; - } + // Process the datetime into the storefront tz + discount.sinceLocal = moment(discount.since).utcOffset(tz).format('YYYY-MM-DD HH:mm'); + discount.untilLocal = moment(discount.until).utcOffset(tz).format('YYYY-MM-DD HH:mm'); + + // hack for handling target + if ( ['order','cart'].indexOf(discount.target) === -1 ) { + // extra hack because the list comes back as a string of json `"[123,234]"` + discount.target_line_items = angular.fromJson(discount.target); + discount.target = 'product'; + } else { + discount.target = 'order'; + } - // hack for handling type - discount.type = discount.amount ? 'amount' : 'percent'; + // hack for handling type + discount.type = discount.amount ? 'amount' : 'percent'; - return discount; + return discount; + } } function _transformRequest(discountSource) { - var _storeTz = ' ' + timezoneService.storeTz; - - // processing the params can effect the source data, so we need to copy it out - var discount = {}; - angular.merge(discount, discountSource); - - // We aren't currently recognizing this - discount.name = discount.code; - - // Process the datetime back - discount.since = moment(discount.sinceLocal + _storeTz, 'YYYY-MM-DD HH:mm Z').toISOString(); - discount.until = moment(discount.untilLocal + _storeTz, 'YYYY-MM-DD HH:mm Z').toISOString(); - delete discount.sinceLocal; - delete discount.untilLocal; - - // hack for formatting target - if (discount.target === 'order') { - discount.target = 'cart'; - } else { - discount.target = discount.target_line_items; + return timezoneService.get().then(adjustDiscount); + + function adjustDiscount(tz) { + // processing the params can effect the source data, so we need to copy it out + var discount = {}; + angular.merge(discount, discountSource); + + // We aren't currently recognizing this + discount.name = discount.code; + + // Process the datetime back + discount.since = moment(discount.sinceLocal + tz, 'YYYY-MM-DD HH:mm Z').toISOString(); + discount.until = moment(discount.untilLocal + tz, 'YYYY-MM-DD HH:mm Z').toISOString(); + delete discount.sinceLocal; + delete discount.untilLocal; + + // hack for formatting target + if (discount.target === 'order') { + discount.target = 'cart'; + } else { + discount.target = discount.target_line_items; + } + + // Clean up empty variable + delete discount.target_line_items; + delete discount.type; + + return discount; } - - // Clean up empty variable - delete discount.target_line_items; - delete discount.type - - return discount; } function one(id) { @@ -95,19 +107,21 @@ angular.module("discountsModule") } function post(data) { - var params = _transformRequest(data); - - return $http.post(_url, params).then(function(response) { + return _transformRequest(data).then(function(params){ + return $http.post(_url, params); + }).then(function(response){ return response.data.result; }); } function put(data) { - var params = _transformRequest(data); - - return $http.put(_url + '/' + params._id, params).then(function(response) { + return _transformRequest(data).then(function(params){ + return $http.put(_url + '/' + params._id, params); + }) + .then(function(response) { return response.data.result; }); + } function remove(id) { @@ -119,9 +133,9 @@ angular.module("discountsModule") function getList() { return $http.get(_url).then(function(response) { var results = response.data.result || []; - results = results.map(_transformResponse); + var promiseResults = results.map(_transformResponse); - return results; + return $q.all(promiseResults); }); } diff --git a/src/app/discounts/list.html b/src/app/discounts/list.html index e2878a6a..aaa19935 100644 --- a/src/app/discounts/list.html +++ b/src/app/discounts/list.html @@ -30,8 +30,8 @@

{{ discount.code {{ discount.times === -1 ? 'No limit' : discount.times }} - Begins: {{ discount.since | otStoreDate }}
- Ends: {{ discount.until | otStoreDate }} + Begins:
+ Ends: diff --git a/src/app/order/edit.html b/src/app/order/edit.html index 8afbed4b..dd14fb9c 100644 --- a/src/app/order/edit.html +++ b/src/app/order/edit.html @@ -130,7 +130,7 @@

Billing Address

Order Details

ID: {{order._id}}
-
Order Date: {{order.created_at | otStoreDate}}
+
Order Date:
Shipping Info: diff --git a/src/app/order/print.html b/src/app/order/print.html index d7003f46..fb3aec26 100644 --- a/src/app/order/print.html +++ b/src/app/order/print.html @@ -55,7 +55,7 @@

Shipping Address

Order Details

Order ID: {{order._id}}
-
Date: {{order.created_at | otStoreDate}}
+
Date:
Payment Method: {{order.payment_info.payment_method_name}}
diff --git a/src/app/reports/customer-activity.controller.js b/src/app/reports/customer-activity.controller.js new file mode 100644 index 00000000..25378e74 --- /dev/null +++ b/src/app/reports/customer-activity.controller.js @@ -0,0 +1,45 @@ +angular.module('reportsModule') + +.controller('reportsCustomerActivityController', [ + '$scope', 'timezoneService', 'reportsService', '$location', + function($scope, timezoneService, reportsService, $location) { + $scope.report = {}; + $scope.timeframe = { + frame: 'last 7 days', + options: [ + 'today', + 'last 7 days', + 'month to date', + 'year to date', + 'all time', + ], + set: setTimeframe, + }; + $scope.sort = $location.search().sort || ''; + + activate(); + + //////////////////// + + function activate(){ + fetchReport($scope.timeframe.frame); + } + + function setTimeframe(frame) { + $scope.timeframe.frame = frame; + fetchReport(frame); + } + + function fetchReport(frame) { + timezoneService.makeDateRange(frame) + .then(function(options) { + options.sort = $scope.sort; + return reportsService.customerActivity(options); + }) + .then(function(report){ + $scope.report = report; + }); + } + } +]); + diff --git a/src/app/reports/customer-activity.html b/src/app/reports/customer-activity.html new file mode 100644 index 00000000..50e28bfd --- /dev/null +++ b/src/app/reports/customer-activity.html @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EmailNameTotal SalesTotal OrdersAvg Order AmountFirst Purchase DateMost Recent Purchase
{{c.email}}{{c.name}}{{c.total_sales | currency}}{{c.total_orders}}{{c.avg_sales | currency}}
+ No results found for this timeframe. +
+ + count: {{ report.meta.count }}, + limit: {{report.meta.limit}}, + perf: {{report.perf_ms.toFixed(2)}} ms, + frame: {{timeframe.frame}} + +
+ diff --git a/src/app/reports/init.js b/src/app/reports/init.js index 93e57b80..bef99774 100644 --- a/src/app/reports/init.js +++ b/src/app/reports/init.js @@ -7,9 +7,32 @@ angular.module('reportsModule', [ .config(['$routeProvider', function($routeProvider) { $routeProvider + .when('/reports', { + templateUrl: '/views/reports/view.html', + }) .when('/reports/product', { templateUrl: '/views/reports/product.html', - controller: 'reportsProductController' + controller: 'reportsProductController', + }) + .when('/reports/customer-activity', { + templateUrl: '/views/reports/customer-activity.html', + controller: 'reportsCustomerActivityController', + }) + .when('/reports/payment-method', { + templateUrl: '/views/reports/payment-method.html', + controller: 'reportsPaymentMethodController', + }) + .when('/reports/shipping-method', { + templateUrl: '/views/reports/shipping-method.html', + controller: 'reportsShippingMethodController', + }) + .when('/reports/location-country', { + templateUrl: '/views/reports/location-country.html', + controller: 'reportsLocationCountryController', + }) + .when('/reports/location-us', { + templateUrl: '/views/reports/location-us.html', + controller: 'reportsLocationUSController', }); }]); diff --git a/src/app/reports/location-country.controller.js b/src/app/reports/location-country.controller.js new file mode 100644 index 00000000..bbbb070f --- /dev/null +++ b/src/app/reports/location-country.controller.js @@ -0,0 +1,43 @@ +angular.module('reportsModule') + +.controller('reportsLocationCountryController', [ + '$scope', 'timezoneService', 'reportsService', '$location', + function($scope, timezoneService, reportsService, $location) { + $scope.report = {}; + $scope.timeframe = { + frame: 'last 7 days', + options: [ + 'today', + 'last 7 days', + 'month to date', + 'year to date', + 'all time', + ], + set: setTimeframe, + }; + + activate(); + + //////////////////// + + function activate(){ + fetchReport($scope.timeframe.frame); + } + + function setTimeframe(frame) { + $scope.timeframe.frame = frame; + fetchReport(frame); + } + + function fetchReport(frame) { + timezoneService.makeDateRange(frame) + .then(function(options) { + return reportsService.locationCountry(options); + }) + .then(function(report){ + $scope.report = report; + }); + } + } +]); + diff --git a/src/app/reports/location-country.html b/src/app/reports/location-country.html new file mode 100644 index 00000000..ae1b0a85 --- /dev/null +++ b/src/app/reports/location-country.html @@ -0,0 +1,26 @@ + + + \ No newline at end of file diff --git a/src/app/reports/location-us.controller.js b/src/app/reports/location-us.controller.js new file mode 100644 index 00000000..85c946ea --- /dev/null +++ b/src/app/reports/location-us.controller.js @@ -0,0 +1,43 @@ +angular.module('reportsModule') + +.controller('reportsLocationUSController', [ + '$scope', 'timezoneService', 'reportsService', '$location', + function($scope, timezoneService, reportsService, $location) { + $scope.report = {}; + $scope.timeframe = { + frame: 'last 7 days', + options: [ + 'today', + 'last 7 days', + 'month to date', + 'year to date', + 'all time', + ], + set: setTimeframe, + }; + + activate(); + + //////////////////// + + function activate(){ + fetchReport($scope.timeframe.frame); + } + + function setTimeframe(frame) { + $scope.timeframe.frame = frame; + fetchReport(frame); + } + + function fetchReport(frame) { + timezoneService.makeDateRange(frame) + .then(function(options) { + return reportsService.locationUS(options); + }) + .then(function(report){ + $scope.report = report; + }); + } + } +]); + diff --git a/src/app/reports/location-us.html b/src/app/reports/location-us.html new file mode 100644 index 00000000..4f150fce --- /dev/null +++ b/src/app/reports/location-us.html @@ -0,0 +1,26 @@ + + + \ No newline at end of file diff --git a/src/app/reports/ot-simple-report.directive.js b/src/app/reports/ot-simple-report.directive.js new file mode 100644 index 00000000..650a3781 --- /dev/null +++ b/src/app/reports/ot-simple-report.directive.js @@ -0,0 +1,22 @@ +angular.module('reportsModule') + +.directive('otSimpleReport', [function() { + return { + restrict: 'E', + scope: { + 'report': '=', + 'frame': '=', + }, + templateUrl: '/views/reports/ot-simple-report.html', + controller: function($scope) { + $scope.percentWidth = percentWidth; + + /////////////////// + + function percentWidth(item) { + return 100 * (item.total_sales / $scope.report.total_sales) + '%'; + } + } + }; +}]); + diff --git a/src/app/reports/ot-simple-report.html b/src/app/reports/ot-simple-report.html new file mode 100644 index 00000000..66e03af5 --- /dev/null +++ b/src/app/reports/ot-simple-report.html @@ -0,0 +1,47 @@ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTotal SalesTotal OrdersAverage Order Size
+ {{m.name}} +
+
+
{{m.total_sales | currency}}{{m.total_orders}}{{m.avg_sales | currency}}
+ No results found for this timeframe. +
+ + perf: {{report.perf_ms.toFixed(2)}} ms, + frame: {{frame}} + +
+
+ diff --git a/src/app/reports/payment-method.controller.js b/src/app/reports/payment-method.controller.js new file mode 100644 index 00000000..8e048dac --- /dev/null +++ b/src/app/reports/payment-method.controller.js @@ -0,0 +1,43 @@ +angular.module('reportsModule') + +.controller('reportsPaymentMethodController', [ + '$scope', 'timezoneService', 'reportsService', '$location', + function($scope, timezoneService, reportsService, $location) { + $scope.report = {}; + $scope.timeframe = { + frame: 'last 7 days', + options: [ + 'today', + 'last 7 days', + 'month to date', + 'year to date', + 'all time', + ], + set: setTimeframe, + }; + + activate(); + + //////////////////// + + function activate(){ + fetchReport($scope.timeframe.frame); + } + + function setTimeframe(frame) { + $scope.timeframe.frame = frame; + fetchReport(frame); + } + + function fetchReport(frame) { + timezoneService.makeDateRange(frame) + .then(function(options) { + return reportsService.paymentMethod(options); + }) + .then(function(report){ + $scope.report = report; + }); + } + } +]); + diff --git a/src/app/reports/payment-method.html b/src/app/reports/payment-method.html new file mode 100644 index 00000000..e3e44696 --- /dev/null +++ b/src/app/reports/payment-method.html @@ -0,0 +1,26 @@ + + + diff --git a/src/app/reports/product.controller.js b/src/app/reports/product.controller.js index 9ff872ae..a1427585 100644 --- a/src/app/reports/product.controller.js +++ b/src/app/reports/product.controller.js @@ -16,9 +16,7 @@ angular.module('reportsModule') 'last 7 days', 'last 30 days', ], - isOpen: false, set: setTimeframe, - toggle: toggle, }; $scope.chartConfig = getChartConfig(); @@ -41,16 +39,9 @@ angular.module('reportsModule') */ function setTimeframe(frame) { $scope.timeframe.frame = frame; - $scope.timeframe.isOpen = false; - fetchReport(frame); } - // Open/Close the timeframe dropdown - function toggle() { - $scope.timeframe.isOpen = !$scope.timeframe.isOpen; - } - // Fetch a report for a timeframe string, and make sure // to modify the dates for the store tz function fetchReport(frame) { diff --git a/src/app/reports/product.html b/src/app/reports/product.html index 61e53996..347d87f1 100644 --- a/src/app/reports/product.html +++ b/src/app/reports/product.html @@ -1,17 +1,17 @@ diff --git a/src/app/visitor/edit.html b/src/app/visitor/edit.html index a45d30c7..b9d82b67 100644 --- a/src/app/visitor/edit.html +++ b/src/app/visitor/edit.html @@ -43,7 +43,7 @@

- {{ order.Extra.created_at | otStoreDate }} + {{ order.Extra._id }}
@@ -75,7 +75,7 @@

- {{ subscription.Extra.created_at | otStoreDate }} + {{ subscription.Extra._id }} {{ subscription.Extra.status }}