Last active
August 29, 2015 13:59
-
-
Save kolyaflash/10917801 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//--- 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