Skip to content

Instantly share code, notes, and snippets.

@kolyaflash
Last active August 29, 2015 13:59
Show Gist options
  • Save kolyaflash/10917801 to your computer and use it in GitHub Desktop.
Save kolyaflash/10917801 to your computer and use it in GitHub Desktop.
//--- app.js
function uuid() {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (d + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c=='x' ? r : (r&0x7|0x8)).toString(16);
});
return uuid;
};
var salesApp = angular.module('salesApp', [
'ngRoute',
'salesControllers',
'salesServices',
'salesOrder',
'salesSale',
'salesDataStorage',
]);
var salesControllers = angular.module('salesControllers', []);
var salesServices = angular.module('salesServices', ['ngResource', 'ableData']);
salesApp.config(['$interpolateProvider', function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
}]);
salesApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/sale', {
templateUrl: 'partials/sale.html',
controller: 'SaleCtrl'
}).
when('/sales/process', {
templateUrl: 'partials/process.html',
controller: 'ProcessCtrl'
}).
when('/returns', {
templateUrl: 'partials/returns.html',
controller: 'ReturnsCtrl'
}).
otherwise({
redirectTo: '/sale'
});
}]);
//--- controllers.js
salesControllers.controller('SaleCtrl', ['$scope', '$rootScope', '$filter', '$location',
'availableProductsService',
'availableCustomersService',
'getCurrentOrder',
function($scope, $rootScope, $filter, $location, availableProductsService,
availableCustomersService, getCurrentOrder) {
$scope.foundProducts = [];
$scope.order = getCurrentOrder();
$scope.$watch("order.needLSSyns", function (newValue, oldValue) {
if ($scope.order.needLSSyns) {
$scope.order.syncLS();
}
});
$scope.customers = availableCustomersService.getObjects();
$scope.$on(availableCustomersService.cacheUpdatedEvent, function (e) {
$scope.$apply(function(){
$scope.customers = availableCustomersService.getObjects();
});
});
$scope.searchProduct = function (searchValue) {
$scope.foundProducts = [];
if (! searchValue) {
return;
}
angular.forEach(availableProductsService.getObjects(), function (product, key) {
if (product.name.toLowerCase().indexOf(searchValue.toLowerCase()) > -1) {
$scope.foundProducts.push(product);
}
});
};
$scope.discardOrder = function () {
$scope.order.discard();
};
$scope.processOrder = function () {
if ($scope.order.getPositions().length < 1) {
alert("Нужно больше позиций.");
return;
}
$location.path('/sales/process');
};
}]);
salesControllers.controller('ReturnsCtrl', ['$scope', 'salesList', function($scope, salesList){
$scope.sales = salesList.getObjects();
$scope.$on(salesList.cacheUpdatedEvent, function(e) {
$scope.$apply(function(){
$scope.sales = salesList.getObjects();
console.log("Scope sales list updated on cacheUpdatedEvent!");
});
});
}]);
salesControllers.controller('ProcessCtrl', ['$scope', 'getCurrentOrder', 'createSale',
function ($scope, getCurrentOrder, createSale) {
$scope.order = getCurrentOrder();
$scope.goBack = function () {
window.history.back();
};
$scope.confirmSale = function () {
createSale.create($scope.order);
$scope.order.discard();
};
}]);
//--- modules.js
angular.module('salesDataStorage', []).factory('datastorage', [function () {
var db = false;
if ( ! db) {
var openRequest = indexedDB.open("sales", 10);
openRequest.onupgradeneeded = function(e) {
console.log("Upgrading...");
var thisDB = e.target.result;
if(!thisDB.objectStoreNames.contains("Product")) {
var Product = thisDB.createObjectStore("Product", { keyPath: "id" });
Product.createIndex("id","id", {unique:true});
}
if(!thisDB.objectStoreNames.contains("Customer")) {
var Customer = thisDB.createObjectStore("Customer", { keyPath: "id" });
Customer.createIndex("id","id", {unique:true});
}
if(!thisDB.objectStoreNames.contains("Sale")) {
var Sale = thisDB.createObjectStore("Sale", { autoIncrement: true });
}
}
openRequest.onsuccess = function(e) {
console.log("Success!");
db = e.target.result;
subject.successEvent(db);
}
openRequest.onerror = function(e) {
console.log("Error");
console.dir(e);
}
}
var subject = new function () {
this.waiters = [];
this.execute = function (observerFunc) {
if (db) {
observerFunc(db);
} else {
this.waiters.push(observerFunc);
}
},
this.successEvent = function (db) {
angular.forEach(this.waiters, function (observer) {
observer(db);
});
this.waiters = [];
}
};
return subject;
}]);
var ableData = angular.module('ableData', []);
ableData.factory('DataCache', ['$cacheFactory', function ($cacheFactory) {
return $cacheFactory('dataCache', {});
}]);
ableData.service('dataSource', ['$resource', '$rootScope', 'DataCache', 'datastorage',
function ($resource, $rootScope, DataCache, datastorage) {
/*
Store data in dataCache
*/
var dataSource = function (dbName, dataIdentifier, resourceUrl) {
this.cacheUpdatedEvent = dataIdentifier + '.cacheUpdated',
this.idbUpdatedEvent = dataIdentifier + '.idbUpdated',
this.updateCacheEvent = dataIdentifier + '.updateCache',
this.loadFromServer = function () {
var idbUpdatedEvent = this.idbUpdatedEvent;
if (resourceUrl) {
console.log("Loading from server starts ", dataIdentifier);
var resource = $resource(resourceUrl, {}, {
query: {
method: 'GET', params: {},
},
});
var response = resource.query(function() {
console.log("Load from server complete ", dataIdentifier);
var items_objects = response.objects;
datastorage.execute(function (db) {
var transaction = db.transaction([dbName], "readwrite");
var store = transaction.objectStore(dbName);
var clearRequest = store.clear();
clearRequest.onsuccess = function (e) {
angular.forEach(items_objects, function (item) {
var request = store.add(item);
});
console.log("IDB updated from server", dataIdentifier);
$rootScope.$broadcast(idbUpdatedEvent);
}
});
});
}
},
this.updateCache = function () {
/*
Loads data to DataCache
*/
var cacheUpdatedEvent = this.cacheUpdatedEvent;
datastorage.execute(function (db) {
console.log("Begin update cache from idb", dataIdentifier);
var transaction = db.transaction([dbName], IDBTransaction.READ_ONLY);
var store = transaction.objectStore(dbName);
var cursorRequest = store.openCursor();
DataCache.remove(dataIdentifier);
var _objects = [];
cursorRequest.onsuccess = function(e) {
var cursor = e.target.result;
if (cursor) {
_objects.push(cursor.value);
cursor.continue();
} else {
DataCache.put(dataIdentifier, _objects);
console.log(dataIdentifier + " is now with " + _objects.length +
" objects. broadcast "+cacheUpdatedEvent+"...");
$rootScope.$broadcast(cacheUpdatedEvent);
return;
}
};
});
},
this.getObjects = function () {
var objects = DataCache.get(dataIdentifier);
var length = 0;
if (objects) {
var length = objects.length;
}
console.log("getObjects from cache", dataIdentifier, length);
return objects;
},
this.get = function (id) {
var result = undefined;
angular.forEach(this.getObjects(), function (obj) {
if ( ! result) {
if (obj.id == id) {
result = obj;
}
}
});
return result;
}
}
return {
getInstance: function (dbName, dataIdentifier, resourceUrl) {
console.log("Create instance " + dataIdentifier);
var obj = new dataSource(dbName, dataIdentifier, resourceUrl);
obj.loadFromServer();
obj.updateCache();
$rootScope.$on(obj.updateCacheEvent, function (e) {
console.log("Update cache...", obj.updateCacheEvent);
obj.updateCache();
});
return {
getObjects: obj.getObjects,
get: obj.get,
resource: obj.resource,
cacheUpdatedEvent: obj.cacheUpdatedEvent,
updateCacheEvent: obj.updateCacheEvent,
}
}
};
}]);
//--- order.js
var salesOrder = angular.module('salesOrder', ['LocalStorageModule']);
salesOrder.factory('getCurrentOrder', ['localStorageService', function (localStorageService) {
var positionsLSkey = "currentOrder_positions";
var positionsJson = localStorageService.get(positionsLSkey);
if ( ! positionsJson ) {
var positions = [];
} else {
var positions = angular.fromJson(positionsJson);
}
var currentOrder = {
positions: positions,
discount: 0,
selectedCustomer: false,
needLSSyns: false,
orderForSale: function () {
return {
positions: this.positions,
discount: this.discount,
}
},
getTotal: function () {
var total = 0;
angular.forEach(this.positions, function (position, key) {
total += parseFloat(position.price * position.count);
});
return total - ((total * this.discount) / 100);
},
getPositions: function () {
return this.positions;
},
deletePosition: function (delPosition) {
var positions = this.positions;
angular.forEach(positions, function (position, key) {
if (position.uuid == delPosition.uuid) {
positions.splice(key, 1);
};
return;
});
this.needLSSyns = true;
},
discard: function () {
this.positions = [];
this.needLSSyns = true;
},
add: function (product) {
var isNew = true;
var positions = this.positions;
angular.forEach(positions, function (position, i) {
if (product.id && product.id == position.product.id) {
positions[i].count += 1;
isNew = false;
return;
}
});
if (isNew) {
positions.push({
uuid: uuid(),
product: product,
count: 1,
price: product.purchase_price,
});
}
this.needLSSyns = true;
},
syncLS: function () {
localStorageService.add(positionsLSkey, localStorageService.stringifyJson(this.positions));
this.needLSSyns = false;
},
};
return function () {
return currentOrder;
};
}]);
//-- sale.js
var salesSale = angular.module('salesSale', ['salesDataStorage', 'ableData']);
salesSale.service('createSale', ['datastorage', '$rootScope', 'salesList', function (datastorage, $rootScope, salesList) {
this.db = undefined,
this.create = function (order) {
var transaction = this.db.transaction(["Sale"], "readwrite");
var store = transaction.objectStore("Sale");
//this.db.transaction(["Sale"], "readwrite").objectStore("Sale").get(X).onsuccess = function(e) {}
var sale = {
date: new Date(),
customer: order.customer,
order: order.orderForSale(),
};
var request = store.add(sale);
transaction.oncomplete = function(event) {
console.log("Saled! Try broadcast.");
$rootScope.$broadcast(salesList.updateCacheEvent);
};
},
this.setDb = function (db) {
this.db = db;
},
this.init = function () {
console.log("init createSale");
var parentThis = this;
datastorage.execute(function (_db) {
parentThis.setDb(_db);
});
},
this.init();
}]);
salesSale.factory('salesList', ['dataSource', '$rootScope', function (dataSource, $rootScope) {
var ds = dataSource.getInstance('Sale', 'salesObjects');
return ds;
}]);
// --- services.js
salesServices.factory('availableCustomersService', ['dataSource', function (dataSource) {
var ds = dataSource.getInstance('Customer', 'customersObjects', '/api/v1/contractors\\/');
return ds;
}]);
salesServices.factory('availableProductsService', ['dataSource', function (dataSource) {
var ds = dataSource.getInstance('Product', 'productsObjects', '/api/v1/products\\/');
return ds;
}]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment