diff --git a/pkg/package.json b/pkg/package.json index 363219a3..b4cfc054 100644 --- a/pkg/package.json +++ b/pkg/package.json @@ -10,14 +10,34 @@ "dist:win32-ia32": "./node_modules/.bin/build --platform win32 --arch ia32", "dist:win32-x64": "./node_modules/.bin/build --platform win32 --arch x64", "dist:win32": "./node_modules/.bin/build --platform win32 --arch all", - "release": "gulp && npm run dist:win32-ia32" + "dist:osx": "./node_modules/.bin/build --platform darwin", + "release": "gulp && npm run dist:win32-ia32", + "releaseosx": "gulp && npm run dist:osx" }, "build": { + "appId": "in.automint.mac", + "catagory": "public.app-category.productivity", "iconUrl": "http://cruzer.io/automint.ico", "win": { "authors": "Automint Pvt. Ltd.", "loadingGif": "build/installer.gif", "remoteReleases": "http://updates.automint.in/releases/win32/ia32/" + }, + "dmg": { + "icon": "build/icon.icns", + "contents": [ + { + "x": 410, + "y": 150, + "type": "link", + "path": "/Applications" + }, + { + "x": 130, + "y": 150, + "type": "file" + } + ] } }, "devDependencies": { diff --git a/src/app/app.controller.js b/src/app/app.controller.js index 7a1eef11..2d11c1d8 100644 --- a/src/app/app.controller.js +++ b/src/app/app.controller.js @@ -2,161 +2,100 @@ * Closure for root level controllers * @author ndkcha * @since 0.4.1 - * @version 0.6.4 + * @version 0.7.0 */ /// (function() { - const ammHelp = require('./automint_modules/am-help.js'); - - angular.module('automintApp') - .controller('lockScreenCtrl', LockScreenController) - .controller('appBarHeaderCtrl', HeaderbarController) - .controller('appSideBarCtrl', SidebarController); - - HeaderbarController.$inject = ['$rootScope', '$scope', '$state', '$timeout', '$mdSidenav', 'amRootFactory']; - SidebarController.$inject = ['$state', '$mdSidenav']; - LockScreenController.$inject = ['$rootScope', '$state', '$window', 'amRootFactory', 'utils']; - - function LockScreenController($rootScope, $state, $window, amRootFactory, utils) { - var vm = this, passcode, skip = true; - - $rootScope.cRootLock = 'active'; - - vm.unlock = unlock; - vm.isMessage = false; - vm.addService = addService; - - var source = localStorage.getItem('cover-pic'); - $('#am-lockscreen-img').attr('src', (source) ? source : 'assets/img/logo-250x125px.png').width(250).height(125); - amRootFactory.getPasscode().then(gps).catch(unlock); - - function addService() { - $rootScope.cRootLock = ''; - $state.go('restricted.services.add', { - fromState: 'locked' - }); - } - function gps(res) { - if (!res || res.enabled == false) { - unlock(); - skip = true; - return; - } - skip = false; - passcode = res.code; - } + angular.module('automintApp').controller('amCtrl', HomeController).controller('amUpdatePwdCtrl', UpdatePasswordController); - function unlock() { - var transitState = 'restricted.dashboard'; - if (skip == false) { - if (vm.passcode != passcode) { - vm.message = "Wrong Passcode!!!"; - vm.isMessage = true; - return; - } - } - $rootScope.isAutomintLocked = false; - $rootScope.cRootLock = ''; - if ($state.params.fromState != undefined) - transitState = $state.params.fromState; - $state.go(transitState); - } - } + HomeController.$inject = ['$rootScope', '$state', '$amRoot', '$amLicense', 'utils']; + UpdatePasswordController.$inject = ['$mdDialog', '$rootScope', '$amLicense', '$amRoot']; - function HeaderbarController($rootScope, $scope, $state, $timeout, $mdSidenav, amRootFactory) { + function HomeController($rootScope, $state, $amRoot, $amLicense, utils) { + // initialize view model var vm = this; - // map functions to view model - vm.toggleSideNavbar = buildDelayedToggler('main-nav-left'); - vm.openLockScreen = openLockScreen; - vm.openHelpWindow = openHelpWindow; - vm.addService = addService; - $rootScope.setCoverPic(); + // default execution steps + $rootScope.isFirstLoad = true; + $amLicense.checkLogin(true).then(success).catch(failure); - amRootFactory.getPasscode().then(gps).catch(failure); + // function definitions - function addService() { - $state.go('restricted.services.add'); + function success(res) { + if (res.isLoggedIn) { + if (res.isCloudEnabled) { + if (res.isCloudForceEnabled != false) + $amRoot.syncDb(); + } + $amRoot.dbAfterLogin(false); + } else + failure(); } - function openHelpWindow() { - ammHelp.openHelpWindow(); + function failure(err) { + if (err != undefined) + utils.showSimpleToast(err); + $rootScope.hidePreloader = true; + $state.go('login'); } + } - function gps(res) { - if (res == undefined) - return; - $rootScope.isPasscodeEnabled = res.enabled; - } + function UpdatePasswordController($mdDialog, $rootScope, $amLicense, $amRoot) { + // initialize view model + var vm = this; - function failure(err) { - $rootScope.isPasscodeEnabled = false; - } + // temporary assignments for the instance + // no such assignments for now - function openLockScreen() { - $rootScope.isAutomintLocked = true; - $state.go('locked', { - fromState: $state.current.name - }); - } + // named assignments to view model + vm.password = ''; + + // function mappings to view model + vm.OnKeyDown = OnKeyDown; + vm.submit = submit; + + // default execution steps + setTimeout(focusPassword, 300); + + // function definitions - // Supplies a function that will continue to operate until the time is up. - function debounce(func, wait, context) { - var timer; - return function debounced() { - var context = $scope, - args = Array.prototype.slice.call(arguments); - $timeout.cancel(timer); - timer = $timeout(function() { - timer = undefined; - func.apply(context, args); - }, wait || 10); - }; + function focusPassword() { + $('#ami-password').focus(); } - // Build handler to open/close a SideNav; when animation finishes report completion in console - function buildDelayedToggler(navID) { - return debounce(function() { - $mdSidenav(navID).toggle(); - }, 200); + function OnKeyDown(event) { + if (event.keyCode == 13) + submit(); } - } - function SidebarController($state, $mdSidenav) { - var vm = this; + function submit() { + $rootScope.busyApp.show = true; + $rootScope.busyApp.message = 'Loging In. Please Wait..'; + $amLicense.loadCredentials($rootScope.amGlobals.credentials.username, vm.password); + $amLicense.login(false).then(success).catch(failure); + + function success(res) { + $rootScope.busyApp.show = false; + if (res.isLoggedIn) { + if (res.isSyncableDb) { + if ($rootScope.amDbSync) + $rootScope.amDbSync.cancel(); + $amRoot.syncDb(); + } + $mdDialog.hide(); + } else { + utils.showSimpleToast('Your license has expired!'); + $state.go('login'); + } + } - // map functions to view model - vm.openState = openState; - - // objects passed to view model - vm.items = [{ - name: 'Dashboard', - icon: 'dashboard', - state: 'restricted.dashboard' - }, { - name: 'Customers', - icon: 'group', - state: 'restricted.customers.all' - }, { - name: 'Treatments', - icon: 'local_car_wash', - state: 'restricted.treatments.master' - }, { - name: 'Inventory', - icon: 'build', - state: 'restricted.inventory.all' - }, { - name: 'Settings', - icon: 'settings', - state: 'restricted.settings' - }]; - - function openState(state) { - $mdSidenav('main-nav-left').close() - $state.go(state); + function failure(err) { + $rootScope.busyApp.show = false; + vm.message = err.message; + } } } })(); \ No newline at end of file diff --git a/src/app/app.db.js b/src/app/app.db.js index 8bd03e50..191fb98b 100644 --- a/src/app/app.db.js +++ b/src/app/app.db.js @@ -1,112 +1,25 @@ -/* +/** * Closure to create factories for handling databases * @author ndkcha * @since 0.4.1 - * @version 0.6.0 + * @version 0.7.0 */ /// (function() { - angular.module('automintApp') - .factory('pdbCustomers', PouchDbCustomers) - .factory('pdbConfig', PouchDbConfig) - .factory('pdbCommon', PouchDbCommon) - .factory('pdbCache', PouchDbCache); - - PouchDbCustomers.$inject = ['$q']; - PouchDbConfig.$inject = ['$q']; - PouchDbCommon.$inject = ['$q']; - PouchDbCache.$inject = ['$q']; - - function PouchDbCache($q) { - // named assignments - var database; - - // initialized factory and function mappings - var factory = { - setDatabase: setDatabase, - save: save, - get: get, - query: query, - getAll: getAll, - saveAll: saveAll - }; - - return factory; - - // function definitions - - // setup database - function setDatabase(name) { - database = new PouchDB(name, { - auto_compaction: true - }); - } - - // save a document in pouchDb database - function save(document) { - var tracker = $q.defer(); - if (document._id) - database.put(document).then(saveSuccessfull).catch(saveFailed); - else { - noIdError = { - ok: false, - message: 'No id provided' - }; - tracker.reject(noIdError); - } - - return tracker.promise; - - // respond to success response on saving database - function saveSuccessfull(response) { - tracker.resolve(response); - } - - // respond to failure response on saving database - function saveFailed(error) { - tracker.reject(error); - } - } - - // get a document from pouchdb database - function get(documentId, options) { - if (options) - return database.get(documentId, options); - else - return database.get(documentId); - } - - // query a document - // refs { mrf: map reduce function } - function query(mrf, options) { - if (options) - return database.query(mrf, options); - else - return database.query(mrf); - } + angular.module('automintApp').factory('pdbMain', PouchDBMain).factory('pdbCache', PouchDbCache).factory('pdbLocal', PouchDbLocal); - // fetch bulk documents from database - function getAll(options) { - if (options) - return database.allDocs(options); - else { - dgaOptions = { - include_docs: true - }; - return database.allDocs(dgaOptions); - } - } + /* + === NOTE === + Use PouchDB() as constructor of PouchDb databases as mentioned in pouchdb api + */ - // put bulk documents into database - function saveAll(documents) { - return database.bulkDocs(documents); - } - } + PouchDbLocal.$inject = ['$q']; + PouchDBMain.$inject = ['$q']; + PouchDbCache.$inject = ['$q']; - // factory function for customers' database - function PouchDbCustomers($q) { + function PouchDbLocal($q) { // named assignments // refs { dga: defaultGetAll } var database, syncOptions, noIdError, dgaOptions; @@ -129,7 +42,9 @@ // setup database function setDatabase(name) { - database = new PouchDB(name); + database = new PouchDB(name, { + auto_compaction: true + }); } // return change listeners of database @@ -215,8 +130,7 @@ } } - // factory function for workshop's config database - function PouchDbConfig($q) { + function PouchDBMain($q) { // named assignments // refs { dga: defaultGetAll } var database, syncOptions, noIdError, dgaOptions; @@ -229,7 +143,8 @@ save: save, get: get, query: query, - getAll: getAll + getAll: getAll, + saveAll: saveAll }; return factory; @@ -238,7 +153,9 @@ // setup database function setDatabase(name) { - database = new PouchDB(name); + database = new PouchDB(name, { + revs_limit: 10 + }); } // return change listeners of database @@ -257,7 +174,7 @@ if (!syncOptions) { syncOptions = { live: true, - retry: true + retry: false }; } return database.sync(remoteDb, syncOptions); @@ -317,23 +234,25 @@ return database.allDocs(dgaOptions); } } - } - // factory function for common dataset - function PouchDbCommon($q) { + // put bulk documents into database + function saveAll(documents) { + return database.bulkDocs(documents); + } + } + + function PouchDbCache($q) { // named assignments - // refs { dga: defaultGetAll } - var database, replicaOptions, noIdError, dgaOptions; - + var database; + // initialized factory and function mappings var factory = { setDatabase: setDatabase, - OnDbChanged: OnDbChanged, - replicate : replicate, save: save, get: get, query: query, - getAll: getAll + getAll: getAll, + saveAll: saveAll }; return factory; @@ -342,29 +261,9 @@ // setup database function setDatabase(name) { - database = new PouchDB(name); - } - - // return change listeners of database - function OnDbChanged(options) { - if (!options) { - options = { - since: 'now', - live: true, - } - } - return database.changes(options); - } - - // setup replication from server - function replicate(remoteDb) { - if (!replicaOptions) { - replicaOptions = { - live: true, - retry: true - }; - } - return database.replicate.from(remoteDb, replicaOptions); + database = new PouchDB(name, { + auto_compaction: true + }); } // save a document in pouchDb database @@ -421,5 +320,10 @@ return database.allDocs(dgaOptions); } } + + // put bulk documents into database + function saveAll(documents) { + return database.bulkDocs(documents); + } } })(); \ No newline at end of file diff --git a/src/app/app.directive.js b/src/app/app.directive.js index 2992f95e..0a2d88af 100644 --- a/src/app/app.directive.js +++ b/src/app/app.directive.js @@ -2,7 +2,7 @@ * Closure for root level directives * @author ndkcha * @since 0.4.1 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -53,8 +53,9 @@ function callback() { var checkTitle = (toState.data && toState.data.pageTitle); + $rootScope.sidebarItemIndex = (toState.data && (toState.data.sidebarItemIndex != undefined)) ? toState.data.sidebarItemIndex : -1; $rootScope.module_title = checkTitle ? toState.data.pageTitle : ''; - $rootScope.page_title = checkTitle ? toState.data.pageTitle + ' - ' + default_title : default_title; + $rootScope.page_title = checkTitle ? (default_title + ' | ' + toState.data.pageTitle) : default_title; } } } diff --git a/src/app/app.factory.js b/src/app/app.factory.js index 6760344d..a6f80948 100644 --- a/src/app/app.factory.js +++ b/src/app/app.factory.js @@ -2,47 +2,15 @@ * Closure for root level factories * @author ndkcha * @since 0.4.1 - * @version 0.6.1 + * @version 0.7.0 */ /// (function() { - angular.module('automintApp') - .factory('amRootFactory', RootFactory) - .factory('utils', UtilsFactory); + angular.module('automintApp').factory('utils', UtilsFactory); - RootFactory.$inject = ['$q', '$amRoot', 'pdbConfig']; UtilsFactory.$inject = ['$mdToast']; - - function RootFactory($q, $amRoot, pdbConfig) { - // initialize factory object and map functions - var factory = { - getPasscode: getPasscode - } - - return factory; - - // function definitions - - function getPasscode() { - var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); - return tracker.promise; - - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObj).catch(failure); - } - - function getSettingsObj(res) { - tracker.resolve(res.passcode); - } - - function failure(err) { - tracker.reject(err); - } - } - } function UtilsFactory($mdToast) { // temporary named assignments diff --git a/src/app/app.js b/src/app/app.js index 4c539348..743868ed 100644 --- a/src/app/app.js +++ b/src/app/app.js @@ -2,7 +2,7 @@ * Automint Application * @author ndkcha * @since 0.4.1 - * @version 0.6.1 + * @version 0.7.0 */ /// @@ -50,16 +50,8 @@ $rootScope.$state = $state; $rootScope.$stateParams = $stateParams; - $rootScope.setCoverPic = setCoverPic; - // initialize database and default syncing mechanism with automint server $amRoot.initDb(); - - // set cover photo - function setCoverPic() { - var source = localStorage.getItem('cover-pic'); - $('#am-cover-pic').attr('src', (source) ? source : 'assets/img/logo-250x125px.png').width(250).height(125); - } } // configure debug mode diff --git a/src/app/app.service.js b/src/app/app.service.js index cbe67736..2297f7f1 100644 --- a/src/app/app.service.js +++ b/src/app/app.service.js @@ -1,168 +1,426 @@ -/* - * Closure for root level service +/** + * Root level service * @author ndkcha * @since 0.4.1 - * @version 0.6.4 + * @version 0.7.0 */ /// (function() { - angular.module('automintApp') - .service('$amRoot', AutomintService); + const ipcRenderer = require('electron').ipcRenderer; - AutomintService.$inject = ['$rootScope', '$state', '$q', '$log', 'utils', 'constants', 'pdbCustomers', 'pdbConfig', 'pdbCommon', 'amFactory', 'pdbCache']; + angular.module('automintApp').service('$amRoot', AutomintService); - function AutomintService($rootScope, $state, $q, $log, utils, constants, pdbCustomers, pdbConfig, pdbCommon, amFactory, pdbCache) { - // set up service object - var sVm = this; - var blockViews = true; + AutomintService.$inject = ['$rootScope', '$state', '$q', '$mdDialog', 'constants', 'pdbMain', 'pdbCache', 'pdbLocal', 'amFactory']; - // keep track of current configuration of application - sVm.docIds = {}; - sVm.username = ''; + function AutomintService($rootScope, $state, $q, $mdDialog, constants, pdbMain, pdbCache, pdbLocal, amFactory) { + // set up service view model + var vm = this; - // map functions - sVm.initDb = initDb; - sVm.syncDb = syncDb; - sVm.ccViews = ccViews; - sVm.isWorkshopId = isWorkshopId; - sVm.isTreatmentId = isTreatmentId; - sVm.isSettingsId = isSettingsId; - sVm.isInventoryId = isInventoryId; - sVm.updateConfigReferences = updateConfigReferences; - - // named assignments - var successResponse = { - success: true + // named assignments to rootScope + if (!$rootScope.amGlobals) + $rootScope.amGlobals = {}; + if ($rootScope.amGlobals.configDocIds == undefined) { + $rootScope.amGlobals.configDocIds = { + settings: 'settings', + treatment: 'treatments', + inventory: 'inventory', + workshop: 'workshop' + } } - var failureResponse = { - success: false + if ($rootScope.amGlobals.creator == undefined) + $rootScope.amGlobals.creator = ''; + if ($rootScope.amGlobals.channel == undefined) + $rootScope.amGlobals.channel = ''; + if ($rootScope.busyApp == undefined) { + $rootScope.busyApp = { + show: false, + message: '' + } + } + + // named assignments to keep track of current configuration of application service + + // map functions + $rootScope.amGlobals.IsConfigDoc = IsConfigDoc; + vm.initDb = initDb; + vm.syncDb = syncDb; + vm.dbAfterLogin = dbAfterLogin; + vm.generateCacheDocs = generateCacheDocs; + + // function definitions + + function IsConfigDoc(id) { + if (id.match(/\bsettings/i)) + return true; + if (id.match(/\btreatments/i)) + return true; + if (id.match(/\binventory/i)) + return true; + if (id.match(/\bworkshop/i)) + return true; + return false; } // initialize databases function initDb() { // setup local databases - pdbConfig.setDatabase(constants.pdb_w_config); - pdbCustomers.setDatabase(constants.pdb_w_customers); - pdbCommon.setDatabase(constants.pdb_common); + pdbMain.setDatabase(constants.pdb_main); pdbCache.setDatabase(constants.pdb_cache); + pdbLocal.setDatabase(constants.pdb_local); + } - // check and create views - manageDbVersions().then(ccViews).catch(ccViews); + function syncDb() { + var username = $rootScope.amGlobals.credentials.username, password = $rootScope.amGlobals.credentials.password; + if ((username == '') || (username == undefined) || (password == '') || (password == undefined)) { + console.error('No Username or Password provided for database sync'); + return; + } + var url = amFactory.generateDbUrl(username, password, constants.sgw_w_main); + if ((url == undefined) || (url == '')) { + console.error('Username/Password/Database name missing from url'); + return; + } + + $rootScope.amDbSync = pdbMain.sync(url); + $rootScope.amDbSync.on('complete', onCompleteDb); + $rootScope.amDbSync.on('paused', onPausedDb); + $rootScope.amDbSync.on('error', onErrorDb); + $rootScope.amDbSync.on('denied', onDeniedDb); + $rootScope.amDbSync.on('change', onChangedDb); + $rootScope.amDbSync.on('active', onActiveDb); + + function onChangedDb(info) { + // listen to on change event + console.info('pdbSync change', info); + } - // listen to changes in local db - OnCustomerDbChanged(); - OnConfigDbChanged(); + function onPausedDb(err) { + // listen to on pause event\ + console.warn('pdbSync pause', err); - // setup server iteraction - // oneWayReplication(); - // syncDb(); - } + if ($rootScope.isSyncCalledFromSettings == true) { + setTimeout(loadSb, 1000); + $rootScope.isSyncCalledFromSettings = false; - function manageDbVersions() { - var tracker = $q.defer(); - isSettingsId().then(getSettingsDoc).catch(failure); - return tracker.promise; + function loadSb() { + generateCacheDocs(true).then(tr).catch(tr); - function getSettingsDoc(res) { - pdbConfig.get(sVm.docIds.settings).then(getSettingsObject).catch(writeSettingsObject); + function tr() { + $rootScope.loadSettingsBlock(); + $rootScope.busyApp.show = false; + } + } + } + + if ($rootScope.isSyncCalledManually == true) { + setTimeout(prepraeTransit, 1000); + $rootScope.isSyncCalledManually = false; + + function prepraeTransit() { + $rootScope.isOnChangeMainDbBlocked = false; + // handle database migration if any and generate cache docs after the process + // no such migrations right now + generateCacheDocs(true).then(transitToDashboard).catch(transitToDashboard); + } + } } - function getSettingsObject(res) { - if (!res.dbversion) - res.dbversion = 0; - switch (res.dbversion) { - case 0: - applyPatch1().then(proceed).catch(proceed); - break; - } + function onActiveDb() { + // listen to on active event + } - function proceed(res) { - res.dbversion = constants.db_version; - pdbConfig.save(res).then(success).catch(failure); + function onDeniedDb(err) { + // listen to on denied event + if (err.status && (err.status == 401)) { + $mdDialog.show({ + controller: 'amUpdatePwdCtrl', + controllerAs: 'vm', + templateUrl: 'app/views/updatepassword.tmpl.html', + parent: angular.element(document.body), + targetEvent: event, + clickOutsideToClose: true + }).then(success).catch(success); + + function success(res) { + // do nothing + } } + console.error('pdbSync deny', err); } - function writeSettingsObject(err) { - var doc = { - _id: utils.generateUUID('sttngs'), - creator: sVm.username, - dbversion: constants.db_version - } - applyPatch1().then(proceed).catch(proceed); + function onCompleteDb(info) { + // listen to on complete event + console.info('pdbSync complete', info); + } - function proceed(res) { - pdbConfig.save(doc).then(success).catch(failure); + function onErrorDb(err) { + // listen to on error event + if (err.status && (err.status == 401)) { + $mdDialog.show({ + controller: 'amUpdatePwdCtrl', + controllerAs: 'vm', + templateUrl: 'app/views/updatepassword.tmpl.html', + parent: angular.element(document.body), + targetEvent: event, + clickOutsideToClose: true + }).then(success).catch(success); + + function success(res) { + // do nothing + } } + console.error('pdbSync error', err); } + } - function success(res) { - tracker.resolve(res); + function transitToDashboard() { + $state.go('restricted.dashboard'); + } + + function dbAfterLogin(wait) { + + // setup database change listeners + pdbMain.OnDbChanged({ + since: 'now', + live: true + }).on('change', OnChangeMainDb); + + if ($rootScope.checkAutomintValidity == undefined) + $rootScope.checkAutomintValidity = setInterval(checkAutomintValidity, 1000*60*60*24); + + if (wait) + $rootScope.isSyncCalledManually = true; + else { + // handle database migration if any and generate cache docs after the process + // no such migrations right now + generateCacheDocs().then(transitToDashboard).catch(transitToDashboard); } - function failure(err) { - tracker.reject(err); + function checkAutomintValidity() { + $amLicense.checkLogin(true).then(success).catch(failure); + + function success(res) { + if (res.isLoggedIn) { + if ((!res.isCloudEnabled) || (res.isCloudEnabled && (res.isCloudForceEnabled == false))) { + if ($rootScope.amDbSync) + $rootScope.amDbSync.cancel(); + } + } else + failure("Something went wrong. Login Again"); + } + + function failure(err) { + $rootScope.busyApp.show = true; + $rootScope.busyApp.message = err; + $rootScope.busyApp.isRaEnabled = true; + setTimeout(restartApp, 1000); + } + + function restartApp(err) { + ipcRenderer.send('am-do-restart', true); + } } } - function applyPatch1() { - var tracker = $q.defer(); - pdbCustomers.getAll().then(success).catch(failure); - return tracker.promise; + function OnChangeMainDb(change) { + if ($rootScope.isOnChangeMainDbBlocked == true) + return; + if (IsConfigDoc(change.id)) + return; + if (change.deleted == true) { + generateCacheDocs(true); + return; + } + var curdoc; + + pdbMain.get(change.id, { + revs_info: true + }).then(getCurrentVersion); + + function getCurrentVersion(cdoc) { + curdoc = cdoc; + if (cdoc._revs_info.length > 1) { + pdbMain.get(change.id, { + rev: cdoc._revs_info[1].rev + }).then(getLastVersion); + } else + getLastVersion(); + } - function success(res) { - var customers = []; - res.rows.forEach(iterateRows); - pdbCustomers.saveAll(customers).then(saveSuccess).catch(failure); - - function iterateRows(row) { - if (row.doc && row.doc.user && row.doc.user.vehicles) { - Object.keys(row.doc.user.vehicles).forEach(iterateVehicles); - customers.push(row.doc); + function getLastVersion(ldoc) { + pdbCache.get(constants.pdb_cache_views.view_services).then(vsuv).catch(vsuv); + pdbCache.get(constants.pdb_cache_views.view_next_due_vehicles).then(vndvs).catch(vndvs); + + function vndvs(cachedoc) { + if (cachedoc.error == true) { + cachedoc = { + _id: constants.pdb_cache_views.view_services + } + } + if (curdoc.user == undefined) + return; + if (curdoc.user.vehicles) + Object.keys(curdoc.user.vehicles).forEach(iterateVehicles); + pdbCache.save(cachedoc); + + function iterateVehicles(vId) { + var vehicle = curdoc.user.vehicles[vId]; + var lastVehicle = undefined, lvcd = undefined; + if (ldoc && ldoc.user && ldoc.user.vehicles && ldoc.user.vehicles[vId]) + lastVehicle = ldoc.user.vehicles[vId]; + if (lastVehicle && lastVehicle.nextdue) + lvcd = moment(lastVehicle.nextdue).format('MMM YYYY'); + if (!vehicle.nextdue) { + if (lastVehicle) { + if (lastVehicle.nextdue) { + if (lvcd && cachedoc[lvcd] && cachedoc[lvcd][vId]) + delete cachedoc[lvcd][vId]; + } + } + return; + } + var cd = moment(vehicle.nextdue).format('MMM YYYY'); + if (lastVehicle && lvcd) { + if ((cachedoc[lvcd] != undefined) && (cachedoc[lvcd][vId] != undefined)) + delete cachedoc[lvcd][vId]; + } + if (cachedoc[cd] == undefined) + cachedoc[cd] = {}; + cachedoc[cd][vId] = { + cstmr_id: change.id, + cstmr_name: curdoc.user.name, + cstmr_mobile: curdoc.user.mobile, + vhcl_reg: vehicle.reg, + vhcl_manuf: vehicle.manuf, + vhcl_model: vehicle.model, + vhcl_nextdue: vehicle.nextdue, + } + } + } + + function vsuv(cachedoc) { + if (cachedoc.error == true) { + cachedoc = { + _id: constants.pdb_cache_views.view_services + } } + if (curdoc.user == undefined) + return; + if (curdoc.user.vehicles) + Object.keys(curdoc.user.vehicles).forEach(iterateVehicles); + pdbCache.save(cachedoc); + function iterateVehicles(vId) { - if (row.doc.user.vehicles[vId].services) - Object.keys(row.doc.user.vehicles[vId].services).forEach(iterateServices); + var vehicle = curdoc.user.vehicles[vId]; + if (vehicle.services) + Object.keys(vehicle.services).forEach(iterateServices); function iterateServices(sId) { - if (row.doc.user.vehicles[vId].services[sId].status == 'billed') - row.doc.user.vehicles[vId].services[sId].status = 'due'; - if (row.doc.user.vehicles[vId].services[sId].state == undefined || row.doc.user.vehicles[vId].services[sId].state == '') - row.doc.user.vehicles[vId].services[sId].state = 'Bill'; + var service = vehicle.services[sId]; + var payreceived = (service.partialpayment) ? service.partialpayment.total : ((service.status == "paid") ? service.cost : 0); + var cd = moment(service.date).format('MMM YYYY'); + cd = angular.lowercase(cd).replace(' ', '-'); + if (service._deleted == true) { + if (cachedoc[cd] && cachedoc[cd][sId]) + delete cachedoc[cd][sId]; + return; + } + if (ldoc && ldoc.user && ldoc.user.vehicles && ldoc.user.vehicles[vId] && ldoc.user.vehicles[vId].services && ldoc.user.vehicles[vId].services[sId]) { + var lvd = moment(ldoc.user.vehicles[vId].services[sId].date).format('MMM YYYY'); + lvd = angular.lowercase(lvd).replace(' ', '-'); + if (cachedoc[lvd][sId] != undefined) + delete cachedoc[lvd][sId]; + } + if (cachedoc[cd] == undefined) + cachedoc[cd] = {}; + cachedoc[cd][sId] = { + cstmr_id: change.id, + cstmr_name: curdoc.user.name, + cstmr_mobile: curdoc.user.mobile, + vhcl_id: vId, + vhcl_reg: vehicle.reg, + vhcl_manuf: vehicle.manuf, + vhcl_model: vehicle.model, + vhcl_nextdue: vehicle.nextdue, + srvc_date: service.date, + srvc_cost: service.cost, + srvc_status: service.status, + srvc_state: service.state, + srvc_payreceived: payreceived + }; } } } } + } - function saveSuccess(res) { - tracker.resolve(res); - } + function generateCacheDocs(force) { + var tracker = $q.defer(); + pdbMain.getAll().then(success).catch(failure); + return tracker.promise; - function failure(err) { - tracker.reject(err); - } - } + function success(res) { + var serviceCacheCallback = (force == true) ? generateServicesCache : quitRoutine; + var nextDueCacheCallback = (force == true) ? generateNextDueCache : quitRoutine; + pdbCache.get(constants.pdb_cache_views.view_services).then(serviceCacheCallback).catch(generateServicesCache); + pdbCache.get(constants.pdb_cache_views.view_next_due_vehicles).then(nextDueCacheCallback).catch(generateNextDueCache); - function ccViews(force) { - // service module + function quitRoutine() { + tracker.resolve(true); + } - pdbCache.get(constants.pdb_cache_views.view_services).then(vsuv).catch(vsuv); + function generateNextDueCache(vvcdoc) { + var vdocToSave = {}; + res.rows.forEach(iterateRows); + vdocToSave._id = constants.pdb_cache_views.view_next_due_vehicles; + if (vvcdoc._rev != undefined) + vdocToSave._rev = vvcdoc._rev; + pdbCache.save(vdocToSave).then(quitRoutine).catch(quitRoutine); - // view service - function vsuv(cachedoc) { - pdbCustomers.getAll().then(success).catch(failure); + function iterateRows(row) { + if (IsConfigDoc(row.id)) + return; + if (row.doc.user == undefined) + return; + if (row.doc.user.vehicles) + Object.keys(row.doc.user.vehicles).forEach(iterateVehicles); + + function iterateVehicles(vId) { + var vehicle = row.doc.user.vehicles[vId]; + if (!vehicle.nextdue) + return; + var cd = moment(vehicle.nextdue).format('MMM YYYY'); + if (vdocToSave[cd] == undefined) + vdocToSave[cd] = {}; + vdocToSave[cd][vId] = { + cstmr_id: row.id, + cstmr_name: row.doc.user.name, + cstmr_mobile: row.doc.user.mobile, + vhcl_reg: vehicle.reg, + vhcl_manuf: vehicle.manuf, + vhcl_model: vehicle.model, + vhcl_nextdue: vehicle.nextdue + } + } + } + } - function success(res) { + function generateServicesCache(cachedoc) { var docsToSave = {}, isChanged = false; res.rows.forEach(iterateRows); docsToSave._id = constants.pdb_cache_views.view_services; - if (cachedoc._rev) + if (cachedoc._rev != undefined) docsToSave._rev = cachedoc._rev; - pdbCache.save(docsToSave); + pdbCache.save(docsToSave).then(quitRoutine).catch(quitRoutine); function iterateRows(row) { + if (IsConfigDoc(row.id)) + return; + if (row.doc.user == undefined) + return; if (row.doc.user.vehicles) Object.keys(row.doc.user.vehicles).forEach(iterateVehicles); @@ -174,6 +432,7 @@ function iterateServices(sId) { var service = vehicle.services[sId]; var cd = moment(service.date).format('MMM YYYY'); + var payreceived = (service.partialpayment) ? service.partialpayment.total : ((service.status == "paid") ? service.cost : 0); cd = angular.lowercase(cd).replace(' ', '-'); if (service._deleted == true) { if (cachedoc[cd][sId] != undefined) @@ -194,7 +453,8 @@ srvc_date: service.date, srvc_cost: service.cost, srvc_status: service.status, - srvc_state: service.state + srvc_state: service.state, + srvc_payreceived: payreceived }; } } @@ -206,288 +466,5 @@ console.warn(err); } } - - function OnCustomerDbChanged() { - pdbCustomers.OnDbChanged({ - since: 'now', - live: true - }).on('change', onChange).on('complete', onComplete).on('error', onError); - - function onChange(change) { - if (change.deleted == true) { - ccViews(); - return; - } - var curdoc; - pdbCache.get(constants.pdb_cache_views.view_services).then(vsuv).catch(vsuv); - - function vsuv(cachedoc) { - if (cachedoc.error == true) { - cachedoc = { - _id: constants.pdb_cache_views.view_services - } - } - - pdbCustomers.get(change.id, { - revs_info: true - }).then(getCurrentVersion); - - function getCurrentVersion(cdoc) { - curdoc = cdoc; - if (cdoc._revs_info.length > 1) { - pdbCustomers.get(change.id, { - rev: cdoc._revs_info[1].rev - }).then(getLastVersion); - } else - getLastVersion(); - } - - function getLastVersion(ldoc) { - if (curdoc.user.vehicles) - Object.keys(curdoc.user.vehicles).forEach(iterateVehicles); - pdbCache.save(cachedoc); - - function iterateVehicles(vId) { - var vehicle = curdoc.user.vehicles[vId]; - if (vehicle.services) - Object.keys(vehicle.services).forEach(iterateServices); - - function iterateServices(sId) { - var service = vehicle.services[sId]; - var cd = moment(service.date).format('MMM YYYY'); - cd = angular.lowercase(cd).replace(' ', '-'); - if (service._deleted == true) { - if (cachedoc[cd] && cachedoc[cd][sId]) - delete cachedoc[cd][sId]; - return; - } - if (ldoc && ldoc.user && ldoc.user.vehicles && ldoc.user.vehicles[vId] && ldoc.user.vehicles[vId].services && ldoc.user.vehicles[vId].services[sId]) { - var lvd = moment(ldoc.user.vehicles[vId].services[sId].date).format('MMM YYYY'); - lvd = angular.lowercase(lvd).replace(' ', '-'); - if (cachedoc[lvd][sId] != undefined) - delete cachedoc[lvd][sId]; - } - if (cachedoc[cd] == undefined) - cachedoc[cd] = {}; - cachedoc[cd][sId] = { - cstmr_id: change.id, - cstmr_name: curdoc.user.name, - cstmr_mobile: curdoc.user.mobile, - vhcl_id: vId, - vhcl_reg: vehicle.reg, - vhcl_manuf: vehicle.manuf, - vhcl_model: vehicle.model, - vhcl_nextdue: vehicle.nextdue, - srvc_date: service.date, - srvc_cost: service.cost, - srvc_status: service.status, - srvc_state: service.state - }; - } - } - } - } - } - - function onComplete(info) { - // console.log(info); - } - - function onError(error) { - // console.log(error); - } - } - - function OnConfigDbChanged() { - pdbConfig.OnDbChanged({ - since: 'now', - live: true, - include_docs: true - }).on('change', onChange).on('complete', onComplete).on('error', onError); - - function onChange(change) { - // console.log(change); - } - - function onComplete(info) { - // console.log(info); - } - - function onError(error) { - // console.log(error); - } - } - - function updateConfigReferences() { - var tracker = $q.defer(); - pdbConfig.getAll().then(successQuery).catch(failedQuery); - return tracker.promise; - - // if promise returns with all documents, update configurations - function successQuery(res) { - res.rows.forEach(iterateDocuments); - tracker.resolve(successResponse); - - // iterate through documents to match id(s) of documents - function iterateDocuments(element) { - if (element.id.match(/\btrtmnt-/i)) - sVm.docIds.treatment = element.id; - if (element.id.match(/\bwrkshp-/i)) - sVm.docIds.workshop = element.id; - if (element.id.match(/\bsttngs-/i)) - sVm.docIds.settings = element.id; - if (element.id.match(/\binvntry-/i)) - sVm.docIds.inventory = element.id; - } - } - - // if promise returns with error - function failedQuery(err) { - tracker.reject(failureResponse); - } - } - - // check if database is syncable to remote - function isSyncable() { - var tracker = $q.defer(); - var workshopUser = $.extend({}, successResponse); - - isWorkshopId().then(setCredentials).catch(noWorkshopUser); - return tracker.promise; - - // if workshop document is tracker, look for username and password inside document - function setCredentials(res) { - pdbConfig.get(sVm.docIds.workshop).then(setWorkshopUser).catch(noWorkshopUser); - - // if workshop users existing, return with username and password - function setWorkshopUser(res) { - if (res.user) { - workshopUser.username = res.user.username; - workshopUser.password = res.user.password; - tracker.resolve(workshopUser); - } else - noWorkshopUser(); - } - } - - // if no workshop, return with failed response bool - function noWorkshopUser(error) { - tracker.reject(failureResponse); - } - } - - // setup sync (bidirectional replication) - function syncDb() { - isSyncable().then().catch(); - - // if sync details found - function runSync(res) { - if (res.success) { - sVm.username = res.username; - // construct database url for workshop configuration and customers' db - dbConfigUrl = amFactory.generateDbUrl(res.username, res.password, constants.sgw_w_config); - dbCustomersUrl = amFactory.generateDbUrl(res.username, res.password, constants.sgw_w_customers); - - // sync database - pdbConfig.sync(dbConfigUrl) - .on('change', onChangedDb) - .on('paused', onPausedDb) - .on('active', onActiveDb) - .on('denied', onDeniedDb) - .on('complete', onCompleteDb) - .on('error', onErrorDb); - - pdbCustomers.sync(dbCustomersUrl) - .on('change', onChangedDb) - .on('paused', onPausedDb) - .on('active', onActiveDb) - .on('denied', onDeniedDb) - .on('complete', onCompleteDb) - .on('error', onErrorDb); - } - } - - // no sync details found - function noSync(error) { - $log.debug('cannot sync at moment! no sync details found'); - } - } - - // setup one-way replication - function oneWayReplication() { - // setup common database replication - pdbCommon.replicate(constants.db_url + constants.sgw_common) - .on('change', onChangedDb) - .on('paused', onPausedDb) - .on('active', onActiveDb) - .on('denied', onDeniedDb) - .on('complete', onCompleteDb) - .on('error', onErrorDb); - } - - // check if treatment's document id is loaded to current docId object - function isTreatmentId() { - return isDocId('trtmnt'); - } - - // check if workshop's document id is loaded to current docId object - function isWorkshopId() { - return isDocId('wrkshp'); - } - - // check if settings' document id is loaded to current docId object - function isSettingsId() { - return isDocId('sttngs'); - } - - // check if inventory's document id is loaded to current docId object - function isInventoryId() { - return isDocId('invntry'); - } - - // the check function - function isDocId(query) { - var tracker = $q.defer(); - if (sVm.docIds[query] == '' || sVm.docIds[query] == undefined) - sVm.updateConfigReferences().then(configUpdated).catch(updateFailed); - else - updateFailed(); - return tracker.promise; - - function configUpdated(res) { - tracker.resolve(successResponse); - } - - function updateFailed(err) { - tracker.resolve(failureResponse); - } - } - - // database listeners - - function onChangedDb(info) { - // listen to on change event - } - - function onPausedDb(err) { - // listen to on pause event\ - } - - function onActiveDb() { - // listen to on active event - } - - function onDeniedDb(err) { - // listen to on denied event - } - - function onCompleteDb(info) { - // listen to on complete event - updateConfigReferences(); - } - - function onErrorDb(err) { - // listen to on error event - } } })(); \ No newline at end of file diff --git a/src/app/app.states.js b/src/app/app.states.js index 564b1074..530b99ac 100644 --- a/src/app/app.states.js +++ b/src/app/app.states.js @@ -2,7 +2,7 @@ * Closure for state definitions and mappings to template files * @author ndkcha * @since 0.4.1 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -14,39 +14,49 @@ StateConfigs.$inject = ['$stateProvider', '$urlRouterProvider']; function StateConfigs($stateProvider, $urlRouterProvider) { - $urlRouterProvider.when('/', '/locked').otherwise('/locked'); + $urlRouterProvider.when('/', '/home').otherwise('/'); $stateProvider - .state('locked', { - url: '/locked', - views: { - 'lockscreen': { - templateUrl: 'app/views/lockscreen.html', - controller: 'lockScreenCtrl', - controllerAs: 'vm' - } - }, - params: { - fromState: undefined + .state('home', { + url: '/home', + templateUrl: 'app/views/initializing.html', + controller: 'amCtrl', + controllerAs: 'vm' + }) + .state('login', { + url: '/login', + templateUrl: 'app/login/login.html', + controller: 'amLoginCtrl', + controllerAs: 'vm', + resolve: { + deps: ['$ocLazyLoad', loadLoginDeps] } }) .state('restricted', { abstract: true, url: '', views: { + 'lockscreen': { + templateUrl: 'app/lock/lockscreen.html', + controller: 'amCtrlLock', + controllerAs: 'lockVm' + }, 'header_bar': { - templateUrl: 'app/appbar/headerView.html', - controller: 'appBarHeaderCtrl', + templateUrl: 'app/appbar/headerbar.html', + controller: 'amCtrlHeaderbar', controllerAs: 'headerVm' }, 'side_bar': { - templateUrl: 'app/appbar/sidebarView.html', - controller: 'appSideBarCtrl', + templateUrl: 'app/appbar/sidebar.html', + controller: 'amCtrlSidebar', controllerAs: 'sidebarVm' }, '': { templateUrl: 'app/views/restricted.html' } + }, + resolve: { + deps: ['$ocLazyLoad', loadAppbarDeps] } }) // dashboard @@ -62,7 +72,8 @@ deps: ['$ocLazyLoad', loadDashboardDeps] }, data: { - pageTitle: 'Dashboard' + pageTitle: 'Dashboard', + sidebarItemIndex: 0 } }) // customers @@ -83,7 +94,8 @@ deps: ['$ocLazyLoad', loadCuRADeps] }, data: { - pageTitle: 'All Customers' + pageTitle: 'All Customers', + sidebarItemIndex: 1 } }) .state('restricted.customers.add', { @@ -95,24 +107,25 @@ deps: ['$ocLazyLoad', loadCuCIDeps] }, data: { - pageTitle: 'Add a Customer' + pageTitle: 'Add a Customer', + sidebarItemIndex: 1 } }) .state('restricted.customers.edit', { url: '/edit', - templateUrl:'app/components/customers/customers_add.html', + templateUrl:'app/components/customers/customers_edit.html', controller: 'amCtrlCuUI', controllerAs: 'vm', params: { id: undefined, - openTab: undefined, fromState: undefined }, resolve: { deps: ['$ocLazyLoad', loadCuUIDeps] }, data: { - pageTitle: 'Edit Customer' + pageTitle: 'Edit Customer', + sidebarItemIndex: 1 } }) // treatments @@ -136,7 +149,8 @@ deps: ['$ocLazyLoad', loadTrMasterDeps] }, data: { - pageTitle: 'All Treatments' + pageTitle: 'All Treatments', + sidebarItemIndex: 2 } }) .state('restricted.treatments.add', { @@ -148,7 +162,8 @@ deps: ['$ocLazyLoad', loadTrCIDeps] }, data: { - pageTitle: 'Add a Treatment' + pageTitle: 'Add a Treatment', + sidebarItemIndex: 2 } }) .state('restricted.treatments.edit', { @@ -163,7 +178,8 @@ deps: ['$ocLazyLoad', loadTrUIDeps] }, data: { - pageTitle: 'Edit Treatment' + pageTitle: 'Edit Treatment', + sidebarItemIndex: 2 } }) // services @@ -184,7 +200,8 @@ deps: ['$ocLazyLoad', loadSeRADeps] }, data: { - pageTitle: 'All Services' + pageTitle: 'All Services', + sidebarItemIndex: -1 } }) .state('restricted.services.add', { @@ -199,7 +216,8 @@ deps: ['$ocLazyLoad', loadSeCIDeps] }, data: { - pageTitle: 'Add a Service' + pageTitle: 'Add a Service', + sidebarItemIndex: -1 } }) .state('restricted.services.edit', { @@ -217,7 +235,8 @@ deps: ['$ocLazyLoad', loadSeUIDeps] }, data: { - pageTitle: 'Edit Service' + pageTitle: 'Edit Service', + sidebarItemIndex: -1 } }) // settings @@ -233,7 +252,8 @@ deps: ['$ocLazyLoad', loadSettingsDeps] }, data: { - pageTitle: 'Settings' + pageTitle: 'Settings', + sidebarItemIndex: 4 } }) // invoices @@ -260,7 +280,8 @@ deps: ['$ocLazyLoad', loadIvRIDeps] }, data: { - pageTitle: 'View Invoice' + pageTitle: 'View Invoice', + sidebarItemIndex: -1 } }) // packages @@ -281,7 +302,8 @@ deps: ['$ocLazyLoad', loadPkCIDeps] }, data: { - pageTitle: 'Add Package' + pageTitle: 'Add Package', + sidebarItemIndex: 2 } }) .state('restricted.packages.edit', { @@ -296,7 +318,8 @@ deps: ['$ocLazyLoad', loadPkUIDeps] }, data: { - pageTitle: 'Edit Package' + pageTitle: 'Edit Package', + sidebarItemIndex: 2 } }) .state('restricted.memberships', { @@ -316,7 +339,8 @@ deps: ['$ocLazyLoad', loadMsCIDeps] }, data: { - pageTitle: 'Add Membership' + pageTitle: 'Add Membership', + sidebarItemIndex: 2 } }) .state('restricted.memberships.edit', { @@ -331,7 +355,8 @@ deps: ['$ocLazyLoad', loadMsUIDeps] }, data: { - pageTitle: 'Edit Membership' + pageTitle: 'Edit Membership', + sidebarItemIndex: 2 } }) .state('restricted.inventory', { @@ -351,7 +376,8 @@ deps: ['$ocLazyLoad', loadInRADeps] }, data: { - pageTitle: 'All Inventories' + pageTitle: 'All Inventories', + sidebarItemIndex: 3 } }) .state('restricted.inventory.add', { @@ -363,7 +389,8 @@ deps: ['$ocLazyLoad', loadInCIDeps] }, data: { - pageTitle: 'Add Inventory' + pageTitle: 'Add Inventory', + sidebarItemIndex: 3 } }) .state('restricted.inventory.edit', { @@ -378,17 +405,26 @@ deps: ['$ocLazyLoad', loadInUIDeps] }, data: { - pageTitle: 'Edit Inventory' + pageTitle: 'Edit Inventory', + sidebarItemIndex: 3 } }); - function loadAddServiceDeps($ocLazyLoad) { + function loadAppbarDeps($ocLazyLoad) { return $ocLazyLoad.load([ - 'material-datatable', - 'app/components/services/services.factory.js', - 'app/components/services/services-add.controller.js' + 'app/appbar/headerbar.controller.js', + 'app/appbar/sidebar.controller.js', + 'app/appbar/appbar.factory.js', + 'app/lock/lockscreen.controller.js' ]) } + + function loadLoginDeps($ocLazyLoad) { + return $ocLazyLoad.load([ + 'app/login/login.controller.js' + ]) + } + function loadInUIDeps($ocLazyLoad) { return $ocLazyLoad.load([ 'app/components/inventory/inventory-edit.controller.js' @@ -414,6 +450,7 @@ return $ocLazyLoad.load([ 'material-datatable', 'google-chart', + 'app/components/dashboard/tmpl/dialog-setcurrency.controller.js', 'app/components/dashboard/dashboard.controller-deps.js', 'app/components/dashboard/dashboard.controller.js', 'app/components/dashboard/dashboard.factory.js' @@ -433,13 +470,17 @@ function loadCuCIDeps($ocLazyLoad) { return $ocLazyLoad.load([ 'material-datatable', - 'app/components/customers/customers-add.controller.js' + 'assets/js/angular-elastic-input.min.js', + 'app/components/customers/customers-add.controller.js', + 'app/components/customers/tmpl/vehicle-crud.controller.js' ]) } function loadCuUIDeps($ocLazyLoad) { return $ocLazyLoad.load([ 'material-datatable', - 'app/components/customers/customers-edit.controller.js' + 'assets/js/angular-elastic-input.min.js', + 'app/components/customers/customers-edit.controller.js', + 'app/components/customers/tmpl/vehicle-crud.controller.js' ]) } function loadTreatmentDeps($ocLazyLoad) { @@ -476,6 +517,11 @@ function loadSeCIDeps($ocLazyLoad) { return $ocLazyLoad.load([ 'material-datatable', + 'app/components/services/tmpl/dialog_membership.edit.controller.js', + 'app/components/services/tmpl/dialog_discount.controller.js', + 'app/components/services/tmpl/dialog_partialpayment.controller.js', + 'app/components/services/tmpl2/dialog-td.controller.js', + 'app/components/services/tmpl2/dialog-id.controller.js', 'app/components/services/services-add.controller.js' ]) } @@ -489,18 +535,25 @@ function loadSeUIDeps($ocLazyLoad) { return $ocLazyLoad.load([ 'material-datatable', + 'app/components/services/tmpl/dialog_membership.edit.controller.js', + 'app/components/services/tmpl/dialog_discount.controller.js', + 'app/components/services/tmpl/dialog_partialpayment.controller.js', + 'app/components/services/tmpl2/dialog-td.controller.js', + 'app/components/services/tmpl2/dialog-id.controller.js', 'app/components/services/services-edit.controller.js' ]) } function loadSettingsDeps($ocLazyLoad) { return $ocLazyLoad.load([ + 'app/components/settings/tmpl/changepassword.controller.js', 'app/components/settings/settings.controller.js', 'app/components/settings/settings-backup.factory.js', 'app/components/settings/settings-login.factory.js', 'app/components/settings/settings-importdata.service.js', 'app/components/settings/settings-invoices.factory.js', - 'app/components/settings/settings-servicetax.factory.js', + 'app/components/settings/settings-tax.factory.js', 'app/components/settings/settings.factory.js', + 'assets/js/angular-elastic-input.min.js', 'assets/js/jquery.csv.min.js' ]) } diff --git a/src/app/app.theme.js b/src/app/app.theme.js index 38cf6cce..2428ef88 100644 --- a/src/app/app.theme.js +++ b/src/app/app.theme.js @@ -24,7 +24,8 @@ 'hue-1': '50' }) .accentPalette('light-blue', { - 'default': '700' + 'default': '700', + 'hue-1': '500' }) .warnPalette('green', { 'default': '600' diff --git a/src/app/appbar/appbar.factory.js b/src/app/appbar/appbar.factory.js new file mode 100644 index 00000000..6a055ecb --- /dev/null +++ b/src/app/appbar/appbar.factory.js @@ -0,0 +1,39 @@ +/** + * Factory for Appbar Components + * @author ndkcha + * @since 0.7.0 + * @version 0.7.0 + */ + +/// + +(function() { + angular.module('automintApp').factory('amAppbar', AppbarFactory); + + AppbarFactory.$inject = ['$q', '$rootScope', 'pdbMain']; + + function AppbarFactory($q, $rootScope, pdbMain) { + // initialize factory object and function maps + var factory = { + getPasscode: getPasscode + } + + return factory; + + // function definitions + + function getPasscode() { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObj).catch(failure); + return tracker.promise; + + function getSettingsObj(res) { + tracker.resolve(res.passcode); + } + + function failure(err) { + tracker.reject(err); + } + } + } +})(); \ No newline at end of file diff --git a/src/app/appbar/headerbar.controller.js b/src/app/appbar/headerbar.controller.js new file mode 100644 index 00000000..c3d90ba5 --- /dev/null +++ b/src/app/appbar/headerbar.controller.js @@ -0,0 +1,82 @@ +/** + * Controller for Header Bar + * @author ndkcha + * @since 0.7.0 + * @version 0.7.0 + */ + +/// + +(function() { + const ammHelp = require('./automint_modules/am-help.js'); + const ipcRenderer = require('electron').ipcRenderer; + + angular.module('automintApp').controller('amCtrlHeaderbar', HeaderBarController); + + HeaderBarController.$inject = ['$rootScope', '$scope', '$state', '$timeout', '$mdSidenav', '$amRoot', 'amAppbar']; + + function HeaderBarController($rootScope, $scope, $state, $timeout, $mdSidenav, $amRoot, amAppbar) { + var vm = this; + + // map functions to view model + vm.toggleSideNavbar = buildDelayedToggler('main-nav-left'); + vm.openLockScreen = openLockScreen; + vm.openHelpWindow = openHelpWindow; + vm.addService = addService; + vm.relaunch = relaunch; + + // default execution steps + $rootScope.hidePreloader = true; + amAppbar.getPasscode().then(gps).catch(failure); + + // function definitions + + function relaunch() { + ipcRenderer.send('am-do-restart', true); + } + + function addService() { + $state.go('restricted.services.add'); + } + + function openHelpWindow() { + ammHelp.openHelpWindow(); + } + + function gps(res) { + if (res == undefined) + return; + $rootScope.isPasscodeEnabled = res.enabled; + $rootScope.isAutomintLocked = res.enabled; + } + + function failure(err) { + $rootScope.isPasscodeEnabled = false; + } + + function openLockScreen() { + $rootScope.isAutomintLocked = true; + } + + // Supplies a function that will continue to operate until the time is up. + function debounce(func, wait, context) { + var timer; + return function debounced() { + var context = $scope, + args = Array.prototype.slice.call(arguments); + $timeout.cancel(timer); + timer = $timeout(function() { + timer = undefined; + func.apply(context, args); + }, wait || 10); + }; + } + + // Build handler to open/close a SideNav; when animation finishes report completion in console + function buildDelayedToggler(navID) { + return debounce(function() { + $mdSidenav(navID).toggle(); + }, 200); + } + } +})(); \ No newline at end of file diff --git a/src/app/appbar/headerView.html b/src/app/appbar/headerbar.html similarity index 84% rename from src/app/appbar/headerView.html rename to src/app/appbar/headerbar.html index 2955c7a3..51ea7d2a 100644 --- a/src/app/appbar/headerView.html +++ b/src/app/appbar/headerbar.html @@ -7,6 +7,10 @@
{{ module_title }}
+ + refresh + Relaunch Automint + add Add Service diff --git a/src/app/appbar/sidebar.controller.js b/src/app/appbar/sidebar.controller.js new file mode 100644 index 00000000..c6432285 --- /dev/null +++ b/src/app/appbar/sidebar.controller.js @@ -0,0 +1,91 @@ +/** + * Controller for Sidebar + * @author ndkcha + * @since 0.7.0 + * @version 0.7.0 + */ + +/// + +(function() { + const electron = require('electron').remote; + const ipcRenderer = require("electron").ipcRenderer; + const amApp = electron.app; + + angular.module('automintApp').controller('amCtrlSidebar', SidebarController); + + SidebarController.$inject = ['$rootScope', '$scope', '$state', '$http', '$mdSidenav']; + + function SidebarController($rootScope, $scope, $state, $http, $mdSidenav) { + var vm = this; + + // objects passed to view model + vm.items = [{ + name: 'Dashboard', + icon: 'dashboard', + state: 'restricted.dashboard' + }, { + name: 'Customers', + icon: 'group', + state: 'restricted.customers.all' + }, { + name: 'Treatments', + icon: 'local_car_wash', + state: 'restricted.treatments.master' + }, { + name: 'Inventory', + icon: 'build', + state: 'restricted.inventory.all' + }, { + name: 'Settings', + icon: 'settings', + state: 'restricted.settings' + }]; + vm.isAutomintUpdateAvailable = undefined; + + // map functions to view model + vm.openState = openState; + vm.doUpdate = doUpdate; + vm.isSelected = isSelected; + vm.goToDashboard = goToDashboard; + + // default execution steps + ipcRenderer.on('automint-updated', listenToAutomintUpdates); + getPackageFile(); + setCoverPic(); + + // function definitions + + function setCoverPic() { + var source = localStorage.getItem('cover-pic'); + $('#am-cover-pic').attr('src', (source) ? source : 'assets/img/logo-250x125px.png').width(250).height(125); + } + + function goToDashboard() { + $mdSidenav('main-nav-left').close() + $state.go(vm.items[0].state); + } + + function isSelected(index) { + return ($rootScope.sidebarItemIndex == index); + } + + function listenToAutomintUpdates(event, arg) { + vm.isAutomintUpdateAvailable = arg; + $scope.$apply(); + } + + function doUpdate() { + ipcRenderer.send('am-quit-update', true); + } + + function getPackageFile() { + vm.automintVersion = amApp.getVersion(); + } + + function openState(state) { + $mdSidenav('main-nav-left').close() + $state.go(state); + } + } +})(); \ No newline at end of file diff --git a/src/app/appbar/sidebar.html b/src/app/appbar/sidebar.html new file mode 100644 index 00000000..962c355b --- /dev/null +++ b/src/app/appbar/sidebar.html @@ -0,0 +1,37 @@ + + + + + + +
+   +
{{ item.icon }}
+
{{ item.name }}
+
+
+
+
+
+ + {{sidebarVm.automintVersion}} + + + Update Now + +
\ No newline at end of file diff --git a/src/app/appbar/sidebarView.html b/src/app/appbar/sidebarView.html deleted file mode 100644 index b3704930..00000000 --- a/src/app/appbar/sidebarView.html +++ /dev/null @@ -1,15 +0,0 @@ -
- - - - - -
-
-
{{ item.icon }}
-
{{ item.name }}
-
-
-
-
-
\ No newline at end of file diff --git a/src/app/components/customers/customers-add.controller.js b/src/app/components/customers/customers-add.controller.js index d471c36d..8819c5bd 100644 --- a/src/app/components/customers/customers-add.controller.js +++ b/src/app/components/customers/customers-add.controller.js @@ -2,7 +2,7 @@ * Controller for Add Customer component * @author ndkcha * @since 0.4.1 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -12,21 +12,18 @@ .controller('amCtrlCuCI', CustomerAddController) .controller('amCtrlMeD', MembershipEditDialogController); - CustomerAddController.$inject = ['$state', '$filter', '$q', '$log', '$mdDialog', 'utils', 'amCustomers']; + CustomerAddController.$inject = ['$rootScope', '$state', '$filter', '$q', '$log', '$mdDialog', 'utils', 'amCustomers']; MembershipEditDialogController.$inject = ['$mdDialog', '$filter', 'membership', 'treatments']; - function CustomerAddController($state, $filter, $q, $log, $mdDialog, utils, amCustomers) { + function CustomerAddController($rootScope, $state, $filter, $q, $log, $mdDialog, utils, amCustomers) { // initialize view model var vm = this; + // temporary named assignments + var nextDueDate = new Date(); + var vehicles; + // vm assignments to keep track of UI related elements - vm.label_userName = 'Enter Full Name:'; - vm.label_userMobile = 'Enter Mobile Number:'; - vm.label_userEmail = 'Enter Email:'; - vm.label_userAddress = 'Enter Address:'; - vm.label_vehicleReg = 'Enter Vehicle Registration Number:'; - vm.label_vehicleManuf = 'Manufacturer:'; - vm.label_vehicleModel = 'Model:'; vm.user = { mobile: '', name: '', @@ -44,44 +41,154 @@ vm.membershipChips = []; vm.vehicleTypeList = []; vm.loadingBasedOnMobile = false; - vm.isNextDueService = false; - vm.nextDueDate = new Date(); - vm.nextDueDate.setMonth(vm.nextDueDate.getMonth() + 3); + vm.customerTypeList = ['Lead', 'Customer', 'Agency']; + vm.possibleVehicleList = []; + vm.vNextDue = {}; // function maps vm.convertNameToTitleCase = convertNameToTitleCase; - vm.convertRegToCaps = convertRegToCaps; - vm.searchVehicleChange = searchVehicleChange; - vm.manufacturersQuerySearch = manufacturersQuerySearch; - vm.modelQuerySearch = modelQuerySearch; - vm.changeUserNameLabel = changeUserNameLabel; - vm.changeUserMobileLabel = changeUserMobileLabel; - vm.changeUserEmailLabel = changeUserEmailLabel; - vm.changeUserAddressLabel = changeUserAddressLabel; - vm.changeVehicleRegLabel = changeVehicleRegLabel; - vm.changeVehicleTab = changeVehicleTab; - vm.changeUserTab = changeUserTab; - vm.isAddOperation = isAddOperation; vm.save = save; vm.queryMembershipChip = queryMembershipChip; vm.OnClickMembershipChip = OnClickMembershipChip; vm.OnAddMembershipChip = OnAddMembershipChip; - vm.changeMembershipTab = changeMembershipTab; vm.goBack = goBack; vm.autoCapitalizeCustomerAddress = autoCapitalizeCustomerAddress; - vm.autoCapitalizeVehicleModel = autoCapitalizeVehicleModel; vm.checkExistingCustomerMobile = checkExistingCustomerMobile; vm.unsubscribeMembership = unsubscribeMembership; vm.getDate = getDate; + vm.editVehicle = editVehicle; + vm.blurAddVehicle = blurAddVehicle; + vm.IsVehicleSelected = IsVehicleSelected; + vm.changeVehicle = changeVehicle; // default execution steps setTimeout(focusCustomerName, 300); getMemberships(); getRegularTreatments(); getVehicleTypes(); - + // function definitions + function IsVehicleSelected(id) { + return (vm.currentVehicleId == id); + } + + function blurAddVehicle(event) { + if (event.keyCode == 9) + setTimeout(focusToSave, 100); + } + + function focusToSave() { + $('#amb-save').focus(); + } + + function changeVehicle(id) { + if (!id) { + setDefaultVehicle(); + return; + } + var found = $filter('filter')(vm.possibleVehicleList, { + id: id + }, true); + if (found.length > 0) { + vm.currentVehicleId = found[0].id; + vm.vehicle.id = found[0].id; + vm.vehicle.reg = found[0].reg; + vm.vehicle.manuf = found[0].manuf; + vm.vehicle.model = found[0].model; + autofillVehicle = true; + } else + setDefaultVehicle(); + } + + function setDefaultVehicle() { + vm.currentVehicleId = undefined; + vm.vehicle.id = undefined; + vm.vehicle.reg = ''; + vm.vehicle.manuf = ''; + vm.vehicle.model = ''; + autofillVehicle = false; + } + + function editVehicle(id) { + changeVehicle(id); + $mdDialog.show({ + controller: 'amCtrlCuVeCRUD', + controllerAs: 'vm', + templateUrl: 'app/components/customers/tmpl/vehicle-crud.tmpl.html', + parent: angular.element(document.body), + targetEvent: event, + locals: { + vehicle: vm.vehicle + }, + clickOutsideToClose: true + }).then(closeVehicleDialog).catch(closeVehicleDialog); + + function closeVehicleDialog(res) { + if (!res) + return; + var vId = res.id; + if (res.id == undefined) + res.id = ''; + if (!vehicles) + vehicles = {}; + + var prefixVehicle = 'vhcl'; + + if (vId == undefined) + vId = utils.generateUUID(prefixVehicle); + + if (vehicles[vId]) { + var tv = vehicles[vId]; + if ((tv.manuf != res.manuf) || (tv.model != res.model)) { + vId = utils.generateUUID(prefixVehicle); + vehicles[vId] = tv; + vm.vNextDue[vId] = vm.vNextDue[res.id]; + delete vehicles[res.id]; + delete vm.vNextDue[res.id]; + } + } else + vehicles[vId] = {}; + var intermvehicle = vehicles[vId]; + intermvehicle.reg = res.reg; + intermvehicle.manuf = res.manuf; + intermvehicle.model = res.model; + + var longname = (intermvehicle.manuf ? intermvehicle.manuf + ' ' : '') + (intermvehicle.model ? intermvehicle.model + ' ' : '') + (intermvehicle.reg ? ((intermvehicle.manuf || intermvehicle.model) ? ' - ' : '') + intermvehicle.reg : ''); + var shortname = (longname.length <= 45) ? longname : longname.substr(0, 45) + '...'; + var isLongName = (longname.length > 45); + + var vfound = $filter('filter')(vm.possibleVehicleList, { + id: res.id + }, true); + + if (vfound.length == 1) { + vfound[0].id = vId + vfound[0].reg = res.reg; + vfound[0].manuf = res.manuf; + vfound[0].model = res.model; + vfound[0].name = longname; + vfound[0].shortname = shortname; + vfound[0].isLongName = isLongName; + } else { + vm.possibleVehicleList.push({ + id: vId, + reg: res.reg, + manuf: res.manuf, + model: res.model, + name: longname, + shortname: shortname, + isLongName: isLongName + }); + vm.vNextDue[vId] = { + isNextDue: false, + nextdue: nextDueDate + } + } + changeVehicle(vId); + } + } + function getDate(date) { return moment(date).format('DD MMM YYYY'); } @@ -97,7 +204,7 @@ $mdDialog.show(confirm).then(performDelete, ignoreDelete); function performDelete() { - console.info('deleted'); + // do nothing } function ignoreDelete() { @@ -110,6 +217,8 @@ } function checkExistingCustomerMobile(ev) { + if (vm.user.mobile == '') + return; vm.loadingBasedOnMobile = true; amCustomers.getCustomerByMobile(vm.user.mobile).then(success).catch(failure); @@ -138,18 +247,9 @@ function failure(err) { vm.loadingBasedOnMobile = false; - console.info('New Customer'); } } - function autoCapitalizeVehicleModel() { - vm.vehicle.model = utils.autoCapitalizeWord(vm.vehicle.model); - } - - function autoCapitalizeVehicleManuf() { - vm.vehicle.manuf = utils.autoCapitalizeWord(vm.vehicle.manuf); - } - function autoCapitalizeCustomerAddress() { vm.user.address = utils.autoCapitalizeWord(vm.user.address); } @@ -158,10 +258,6 @@ $state.go('restricted.customers.all'); } - function changeMembershipTab(bool) { - vm.membershipTab = bool; - } - function OnClickMembershipChip(event) { var chipIndex = angular.element(event.currentTarget).controller('mdChips').selectedChip; if (chipIndex < 0) @@ -309,146 +405,30 @@ function convertNameToTitleCase() { vm.user.name = utils.convertToTitleCase(vm.user.name); } - - function convertRegToCaps() { - vm.vehicle.reg = vm.vehicle.reg.toUpperCase(); - } - - // query search for manufacturers [autocomplete] - function manufacturersQuerySearch() { - var tracker = $q.defer(); - var results = (vm.vehicle.manuf ? vm.manufacturers.filter(createFilterForManufacturers(vm.vehicle.manuf)) : vm.manufacturers); - - if (results.length > 0) { - return results; - } - - amCustomers.getManufacturers().then(allotManufacturers).catch(noManufacturers); - return tracker.promise; - - function allotManufacturers(res) { - vm.manufacturers = res; - results = (vm.vehicle.manuf ? vm.manufacturers.filter(createFilterForManufacturers(vm.vehicle.manuf)) : vm.manufacturers); - tracker.resolve(results); - } - - function noManufacturers(error) { - results = []; - tracker.resolve(results); - } - } - - // create filter for manufacturers' query list - function createFilterForManufacturers(query) { - var lcQuery = angular.lowercase(query); - return function filterFn(item) { - item = angular.lowercase(item); - return (item.indexOf(lcQuery) === 0); - } - } - - // query search for model [autocomplete] - function modelQuerySearch() { - var tracker = $q.defer(); - var results = (vm.vehicle.model ? vm.models.filter(createFilterForModel(vm.vehicle.model)) : vm.models); - - if (results.length > 0) - return results; - - amCustomers.getModels(vm.vehicle.manuf).then(allotModels).catch(noModels); - return tracker.promise; - - function allotModels(res) { - vm.models = res; - results = (vm.vehicle.model ? vm.models.filter(createFilterForModel(vm.vehicle.model)) : vm.models); - tracker.resolve(results); - } - - function noModels(err) { - results = []; - tracker.resolve(results); - } - } - - // create filter for models' query list - function createFilterForModel(query) { - var lcQuery = angular.lowercase(query); - return function filterFn(item) { - item = angular.lowercase(item); - return (item.indexOf(lcQuery) === 0); - } - } - - function searchVehicleChange() { - autoCapitalizeVehicleManuf(); - vm.models = []; - vm.vehicle.model = ''; - } - - // return boolean response to different configurations [BEGIN] - function isAddOperation() { - return true; - } - // return boolean response to different configurations [END] - - // change user tab selector variable - function changeUserTab(bool) { - vm.userTab = bool; - } - - // change vehicle tab selector variable - function changeVehicleTab(bool) { - vm.vehicleTab = bool; - } - - // listen to changes in input fields [BEGIN] - function changeUserNameLabel(force) { - vm.isUserName = (force != undefined || vm.user.name != ''); - vm.label_userName = vm.isUserName ? 'Name:' : 'Enter Full Name:'; - } - function changeUserMobileLabel(force) { - vm.isUserMobile = (force != undefined || vm.user.mobile != ''); - vm.label_userMobile = vm.isUserMobile ? 'Mobile:' : 'Enter Mobile Number:'; - } - function changeUserEmailLabel(force) { - vm.isUserEmail = (force != undefined || vm.user.email != ''); - vm.label_userEmail = vm.isUserEmail ? 'Email:' : 'Enter Email:'; - } - function changeUserAddressLabel(force) { - vm.isUserAddress = (force != undefined || vm.user.address != ''); - vm.label_userAddress = vm.isUserAddress ? 'Address:' : 'Enter Address:'; - } - function changeVehicleRegLabel(force) { - vm.isVehicleReg = (force != undefined || vm.vehicle.reg != ''); - vm.label_vehicleReg = vm.isVehicleReg ? 'Vehcile Registration Number:' : 'Enter Vehicle Registration Number:'; - } - // listen to changes in input fields [END] function validate() { if (vm.user.name == '') { - changeUserTab(true); - setTimeout(doFocus, 300); - utils.showSimpleToast('Please Enter Name'); - - function doFocus() { - $('#ami-user-name').focus(); - } - return false; + vm.user.name = "Anonymous"; } - return true; } // save to database function save() { - if (!validate()) return; - vm.user.memberships = vm.membershipChips; - if (!(vm.vehicle.reg == '' && vm.vehicle.manuf == '' && vm.vehicle.model == '')) { - vm.vehicle.reg = vm.vehicle.reg.replace(/\s/g, ''); - if (vm.isNextDueService) - vm.vehicle.nextdue = vm.nextDueDate; - amCustomers.addNewCustomer(vm.user, vm.vehicle).then(successfullSave).catch(failedSave); - } else + validate(); + var ndKeys = Object.keys(vm.vNextDue); + if (ndKeys.length > 0) + ndKeys.forEach(iterateNextDue); + if (vm.membershipChips.length > 0) + vm.user.memberships = vm.membershipChips; + if (vehicles && Object.keys(vehicles.length > 0)) + amCustomers.addNewCustomer(vm.user, vehicles).then(successfullSave).catch(failedSave); + else amCustomers.addNewCustomer(vm.user).then(successfullSave).catch(failedSave); + + function iterateNextDue(nd) { + if (vm.vNextDue[nd].isNextDue) + vehicles[nd].nextdue = moment(vm.vNextDue[nd].nextdue).format(); + } } function successfullSave(res) { diff --git a/src/app/components/customers/customers-edit.controller.js b/src/app/components/customers/customers-edit.controller.js index 348766af..542504c6 100644 --- a/src/app/components/customers/customers-edit.controller.js +++ b/src/app/components/customers/customers-edit.controller.js @@ -2,7 +2,7 @@ * Controller for Edit Customer component * @author ndkcha * @since 0.4.1 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -12,25 +12,19 @@ .controller('amCtrlCuUI', CustomerEditController) .controller('amCtrlMeD', MembershipEditDialogController); - CustomerEditController.$inject = ['$state', '$q', '$log', '$filter', '$mdDialog', 'utils', 'amCustomers']; + CustomerEditController.$inject = ['$rootScope', '$scope', '$state', '$q', '$log', '$filter', '$mdDialog', 'utils', 'amCustomers']; MembershipEditDialogController.$inject = ['$mdDialog', '$filter', 'membership', 'treatments']; - function CustomerEditController($state, $q, $log, $filter, $mdDialog, utils, amCustomers) { + function CustomerEditController($rootScope, $scope, $state, $q, $log, $filter, $mdDialog, utils, amCustomers) { // initialize view model var vm = this; // temporary named assignments var autofillVehicle = false; - var userDbInstance; + var userDbInstance, userMobile; + var nextDueDate = new Date(); // vm assignments to keep track of UI related elements - vm.label_userName = 'Enter Full Name'; - vm.label_userMobile = 'Enter Mobile Number'; - vm.label_userEmail = 'Enter Email:'; - vm.label_userAddress = 'Enter Address:'; - vm.label_vehicleReg = 'Enter Vehicle Registration Number'; - vm.label_vehicleManuf = 'Manufacturer:'; - vm.label_vehicleModel = 'Model:'; vm.user = { mobile: '', name: '', @@ -41,7 +35,8 @@ id: '', reg: '', manuf: '', - model: '' + model: '', + }; vm.manufacturers = []; vm.models = []; @@ -54,65 +49,186 @@ total: 0 }; vm.serviceStateList = ['Job Card', 'Estimate', 'Bill']; - vm.isNextDueService = false; - vm.nextDueDate = new Date(); - vm.nextDueDate.setMonth(vm.nextDueDate.getMonth() + 3); + vm.vNextDue = {}; + vm.customerTypeList = ['Lead', 'Customer', 'Agency']; + vm.paymentDone = 0; + vm.paymentDue = 0; + vm.currencySymbol = "Rs."; // function maps - vm.convertNameToTitleCase = convertNameToTitleCase; - vm.convertRegToCaps = convertRegToCaps; - vm.searchVehicleChange = searchVehicleChange; - vm.manufacturersQuerySearch = manufacturersQuerySearch; - vm.modelQuerySearch = modelQuerySearch; - vm.changeUserNameLabel = changeUserNameLabel; - vm.changeUserMobileLabel = changeUserMobileLabel; - vm.changeUserEmailLabel = changeUserEmailLabel; - vm.changeUserAddressLabel = changeUserAddressLabel; - vm.changeVehicleRegLabel = changeVehicleRegLabel; - vm.changeVehicleTab = changeVehicleTab; vm.changeVehicle = changeVehicle; - vm.isAddOperation = isAddOperation; - vm.chooseVehicle = chooseVehicle; vm.save = save; vm.queryMembershipChip = queryMembershipChip; vm.OnClickMembershipChip = OnClickMembershipChip; vm.OnAddMembershipChip = OnAddMembershipChip; vm.changeMembershipTab = changeMembershipTab; vm.goBack = goBack; - vm.changeServicesTab = changeServicesTab; vm.getServiceDate = getServiceDate; vm.editService = editService; - vm.deleteService = deleteService; vm.goToInvoice = goToInvoice; vm.autoCapitalizeCustomerAddress = autoCapitalizeCustomerAddress; - vm.autoCapitalizeVehicleModel = autoCapitalizeVehicleModel; vm.unsubscribeMembership = unsubscribeMembership; vm.IsServiceDue = IsServiceDue; vm.IsServiceStateIv = IsServiceStateIv; vm.IsServiceStateEs = IsServiceStateEs; vm.IsServiceStateJc = IsServiceStateJc; vm.getDate = getDate; + vm.IsVehicleSelected = IsVehicleSelected; + vm.editVehicle = editVehicle; + vm.convertNameToTitleCase = convertNameToTitleCase; + vm.checkExistingCustomerMobile = checkExistingCustomerMobile; + vm.IsVehicleAnonymous = IsVehicleAnonymous; // default execution steps if ($state.params.id != undefined) { + getCurrencySymbol(); getMemberships(getRegularTreatments, getVehicleTypes, getCustomer); - switch ($state.params.openTab) { - case 'services': - changeServicesTab(true); - break; - case 'vehicle': - changeVehicleTab(true); - break; - default: - setTimeout(focusCustomerMobile, 300); - break; - } + setTimeout(focusCustomerMobile, 300); } else { utils.showSimpleToast('Something went wrong!'); $state.go('restricted.customers.all'); } // function definitions + function IsVehicleAnonymous(service) { + return (service.vhcl_reg == 'Vehicle'); + } + + + function checkExistingCustomerMobile(ev) { + if (vm.user.mobile == '') + return; + vm.loadingBasedOnMobile = true; + amCustomers.getCustomerByMobile(vm.user.mobile).then(success).catch(failure); + + function success(res) { + vm.loadingBasedOnMobile = false; + if (vm.user.id == res.id) + return; + var confirm = $mdDialog.confirm() + .title('Do you want to edit customer details ?') + .textContent('Customer record for ' + res.name + ' with ' + vm.user.mobile + ' already exists') + .ariaLabel('Edit Customer') + .targetEvent(ev) + .ok('Yes') + .cancel('No'); + + $mdDialog.show(confirm).then(doEdit, ignore); + + function doEdit() { + $state.go('restricted.customers.edit', { + id: res.id + }); + } + + function ignore() { + vm.user.mobile = userMobile; + } + } + + function failure(err) { + vm.loadingBasedOnMobile = false; + } + } + + function convertNameToTitleCase() { + vm.user.name = utils.convertToTitleCase(vm.user.name); + } + + function getCurrencySymbol() { + amCustomers.getCurrencySymbol().then(success).catch(failure); + + function success(res) { + vm.currencySymbol = res; + } + + function failure(err) { + vm.currencySymbol = "Rs."; + } + } + + function editVehicle(id) { + changeVehicle(id); + $mdDialog.show({ + controller: 'amCtrlCuVeCRUD', + controllerAs: 'vm', + templateUrl: 'app/components/customers/tmpl/vehicle-crud.tmpl.html', + parent: angular.element(document.body), + targetEvent: event, + locals: { + vehicle: vm.vehicle + }, + clickOutsideToClose: true + }).then(closeVehicleDialog).catch(closeVehicleDialog); + + function closeVehicleDialog(res) { + if (!res) + return; + var vId = res.id; + if (res.id == undefined) + res.id = ''; + if (!userDbInstance.user.vehicles) + userDbInstance.user.vehicles = {}; + + var prefixVehicle = 'vhcl'; + + if (vId == undefined) + vId = utils.generateUUID(prefixVehicle); + + if (userDbInstance.user.vehicles[vId]) { + var tv = userDbInstance.user.vehicles[vId]; + if ((tv.manuf != res.manuf) || (tv.model != res.model)) { + vId = utils.generateUUID(prefixVehicle); + userDbInstance.user.vehicles[vId] = tv; + vm.vNextDue[vId] = vm.vNextDue[res.id]; + delete userDbInstance.user.vehicles[res.id]; + delete vm.vNextDue[res.id]; + } + } else + userDbInstance.user.vehicles[vId] = {}; + var intermvehicle = userDbInstance.user.vehicles[vId]; + intermvehicle.reg = res.reg; + intermvehicle.manuf = res.manuf; + intermvehicle.model = res.model; + + var longname = (intermvehicle.manuf ? intermvehicle.manuf + ' ' : '') + (intermvehicle.model ? intermvehicle.model + ' ' : '') + (intermvehicle.reg ? ((intermvehicle.manuf || intermvehicle.model) ? ' - ' : '') + intermvehicle.reg : ''); + var shortname = (longname.length <= 45) ? longname : longname.substr(0, 45) + '...'; + var isLongName = (longname.length > 45); + + var vfound = $filter('filter')(vm.possibleVehicleList, { + id: res.id + }, true); + + if (vfound.length == 1) { + vfound[0].id = vId + vfound[0].reg = res.reg; + vfound[0].manuf = res.manuf; + vfound[0].model = res.model; + vfound[0].name = longname; + vfound[0].shortname = shortname; + vfound[0].isLongName = isLongName; + } else { + vm.possibleVehicleList.push({ + id: vId, + reg: res.reg, + manuf: res.manuf, + model: res.model, + name: longname, + shortname: shortname, + isLongName: isLongName + }); + vm.vNextDue[vId] = { + isNextDue: false, + nextdue: nextDueDate + } + } + changeVehicle(vId); + } + } + + function IsVehicleSelected(id) { + return (vm.currentVehicleId == id); + } function getDate(date) { return moment(date).format('DD MMM YYYY'); @@ -145,7 +261,7 @@ $mdDialog.show(confirm).then(performDelete, ignoreDelete); function performDelete() { - console.info('membership deleted'); + // do nothing } function ignoreDelete() { @@ -157,14 +273,6 @@ $('#ami-customer-mobile').focus(); } - function autoCapitalizeVehicleModel() { - vm.vehicle.model = utils.autoCapitalizeWord(vm.vehicle.model); - } - - function autoCapitalizeVehicleManuf() { - vm.vehicle.manuf = utils.autoCapitalizeWord(vm.vehicle.manuf); - } - function autoCapitalizeCustomerAddress() { vm.user.address = utils.autoCapitalizeWord(vm.user.address); } @@ -178,40 +286,6 @@ fromState: 'customers.edit.services' }); } - - // delete service from UI - function deleteService(service, ev) { - var confirm = $mdDialog.confirm() - .textContent('Are you sure you want to delete the service ?') - .ariaLabel('Delete Customer') - .targetEvent(ev) - .ok('Yes') - .cancel('No'); - - $mdDialog.show(confirm).then(performDelete, ignoreDelete); - - function performDelete() { - amServices.deleteService(service.cstmr_id, service.vhcl_id, service.srvc_id).then(success).catch(failure); - } - - function ignoreDelete() { - console.info('nope'); - } - - - function success(res) { - if (res.ok) { - utils.showSimpleToast('Service has been deleted.'); - setTimeout(getServices, 200); - } else - failure(); - } - - function failure(err) { - console.warn(err); - utils.showSimpleToast('Service can not be deleted at moment. Please Try Again!'); - } - } // transit to state to view selected invoice function goToInvoice(service) { @@ -226,10 +300,6 @@ function getServiceDate(date) { return moment(date).format('DD MMM YYYY'); } - - function changeServicesTab(bool) { - vm.servicesTab = bool; - } function goBack() { var transitState = 'restricted.customers.all'; @@ -484,54 +554,42 @@ var pvl = []; vm.user.id = res._id; vm.user.mobile = res.user.mobile; + userMobile = res.user.mobile; vm.user.email = res.user.email; vm.user.name = res.user.name; vm.user.address = res.user.address; - changeUserMobileLabel(); - changeUserEmailLabel(); - changeUserNameLabel(); - changeUserAddressLabel(); + if (res.user.type) + vm.user.type = res.user.type; if (res.user.memberships) Object.keys(res.user.memberships).forEach(iterateMemberships); if (res.user.vehicles) Object.keys(res.user.vehicles).forEach(iterateVehicle, this); vm.serviceQuery.total = vm.services.length; vm.possibleVehicleList = pvl; - changeVehicle(pvl.length > 0 ? pvl[0].id : undefined); - vm.services.sort(dateSort); - - function dateSort(lhs, rhs) { - return rhs.srvc_date.localeCompare(lhs.srvc_date); - } + changeVehicle(undefined); + if (vm.user.type == vm.customerTypeList[0] && (vm.services.length > 0)) + vm.user.type = vm.customerTypeList[1]; + $scope.$apply(); function iterateVehicle(vId) { var vehicle = res.user.vehicles[vId]; + var longname = (vehicle.manuf ? vehicle.manuf + ' ' : '') + (vehicle.model ? vehicle.model + ' ' : '') + (vehicle.reg ? ((vehicle.manuf || vehicle.model) ? ' - ' : '') + vehicle.reg : ''); + var shortname = (longname.length <= 45) ? longname : longname.substr(0, 45) + '...'; + var isLongName = (longname.length > 45); + vm.vNextDue[vId] = { + isNextDue: (vehicle.nextdue != undefined), + nextdue: (vehicle.nextdue ? new Date(vehicle.nextdue) : nextDueDate) + } pvl.push({ id: vId, reg: vehicle.reg, manuf: vehicle.manuf, model: vehicle.model, - name: vehicle.manuf + ' - ' + vehicle.model + (vehicle.reg == '' ? '' : ', ' + vehicle.reg), + name: longname, + shortname: shortname, + isLongName: isLongName, nextdue: vehicle.nextdue }); - if (vehicle.services) - Object.keys(vehicle.services).forEach(iterateServices); - - function iterateServices(sId) { - var service = vehicle.services[sId]; - vm.services.push({ - cstmr_id: res._id, - vhcl_manuf: vehicle.manuf, - vhcl_model: vehicle.model, - vhcl_reg: vehicle.reg, - vhcl_id: vId, - srvc_id: sId, - srvc_date: service.date, - srvc_cost: service.cost, - srvc_status: utils.convertToTitleCase(service.status), - srvc_state: service.state - }); - } } function iterateMemberships(membership) { res.user.memberships[membership].name = membership; @@ -546,32 +604,72 @@ } } + function loadServices() { + vm.services = []; + vm.paymentDone = 0; + vm.paymentDue = 0; + if (vm.vehicle.id) { + if (userDbInstance.user && userDbInstance.user.vehicles && userDbInstance.user.vehicles[vm.vehicle.id]) + iterateVehicle(vm.vehicle.id); + } else { + if (userDbInstance.user && userDbInstance.user.vehicles) + Object.keys(userDbInstance.user.vehicles).forEach(iterateVehicle); + } + vm.services.sort(dateSort); + + function dateSort(lhs, rhs) { + return rhs.srvc_date.localeCompare(lhs.srvc_date); + } + + function iterateVehicle(vId) { + var vehicle = userDbInstance.user.vehicles[vId]; + if (vehicle.services) + Object.keys(vehicle.services).forEach(iterateServices); + + function iterateServices(sId) { + var service = vehicle.services[sId]; + var payreceived = (service.partialpayment) ? service.partialpayment.total : ((service.status == "paid") ? service.cost : 0); + vm.paymentDone += parseFloat(payreceived); + vm.paymentDue += ((service.status != "paid") ? (parseFloat(service.cost) - parseFloat(payreceived)) : 0); + vm.services.push({ + cstmr_id: userDbInstance._id, + vhcl_manuf: vehicle.manuf, + vhcl_model: vehicle.model, + vhcl_reg: vehicle.reg, + vhcl_id: vId, + srvc_id: sId, + srvc_date: service.date, + srvc_cost: service.cost, + srvc_status: utils.convertToTitleCase(service.status), + srvc_state: service.state + }); + } + } + } + function changeVehicle(id) { if (!id) { setDefaultVehicle(); + loadServices(); return; } var found = $filter('filter')(vm.possibleVehicleList, { id: id }, true); if (found.length > 0) { - vm.currentVehicle = found[0].name; + vm.currentVehicleId = found[0].id; vm.vehicle.id = found[0].id; vm.vehicle.reg = found[0].reg; vm.vehicle.manuf = found[0].manuf; vm.vehicle.model = found[0].model; - if (found[0].nextdue && (found[0].nextdue.localeCompare(moment().format()) > 0)) { - vm.isNextDueService = true; - vm.nextDueDate = new Date(found[0].nextdue); - } - changeVehicleRegLabel(); autofillVehicle = true; } else setDefaultVehicle(); + loadServices(); } function setDefaultVehicle() { - vm.currentVehicle = 'New Vehicle'; + vm.currentVehicleId = undefined; vm.vehicle.id = undefined; vm.vehicle.reg = ''; vm.vehicle.manuf = ''; @@ -579,128 +677,6 @@ autofillVehicle = false; } - // choose different existing vehicle - function chooseVehicle($mdOpenMenu, ev) { - $mdOpenMenu(ev); - } - - function convertNameToTitleCase() { - vm.user.name = utils.convertToTitleCase(vm.user.name); - } - - function convertRegToCaps() { - vm.vehicle.reg = vm.vehicle.reg.toUpperCase(); - } - - // query search for manufacturers [autocomplete] - function manufacturersQuerySearch() { - var tracker = $q.defer(); - var results = (vm.vehicle.manuf ? vm.manufacturers.filter(createFilterForManufacturers(vm.vehicle.manuf)) : vm.manufacturers); - - if (results.length > 0) { - return results; - } - - amCustomers.getManufacturers().then(allotManufacturers).catch(noManufacturers); - return tracker.promise; - - function allotManufacturers(res) { - vm.manufacturers = res; - results = (vm.vehicle.manuf ? vm.manufacturers.filter(createFilterForManufacturers(vm.vehicle.manuf)) : vm.manufacturers); - tracker.resolve(results); - } - - function noManufacturers(error) { - results = []; - tracker.resolve(results); - } - } - - // create filter for manufacturers' query list - function createFilterForManufacturers(query) { - var lcQuery = angular.lowercase(query); - return function filterFn(item) { - item = angular.lowercase(item); - return (item.indexOf(lcQuery) === 0); - } - } - - // query search for model [autocomplete] - function modelQuerySearch() { - var tracker = $q.defer(); - var results = (vm.vehicle.model ? vm.models.filter(createFilterForModel(vm.vehicle.model)) : vm.models); - - if (results.length > 0) - return results; - - amCustomers.getModels(vm.vehicle.manuf).then(allotModels).catch(noModels); - return tracker.promise; - - function allotModels(res) { - vm.models = res; - results = (vm.vehicle.model ? vm.models.filter(createFilterForModel(vm.vehicle.model)) : vm.models); - tracker.resolve(results); - } - - function noModels(err) { - results = []; - tracker.resolve(results); - } - } - - // create filter for models' query list - function createFilterForModel(query) { - var lcQuery = angular.lowercase(query); - return function filterFn(item) { - item = angular.lowercase(item); - return (item.indexOf(lcQuery) === 0); - } - } - - function searchVehicleChange(e) { - autoCapitalizeVehicleManuf(); - if (!autofillVehicle) { - vm.models = []; - vm.vehicle.model = ''; - autofillVehicle = false; - } else - autofillVehicle = false; - } - - // return boolean response to different configurations [BEGIN] - function isAddOperation() { - return false; - } - // return boolean response to different configurations [END] - - // change vehicle table selector variable - function changeVehicleTab(bool) { - vm.vehicleTab = bool; - } - - // listen to changes in input fields [BEGIN] - function changeUserNameLabel(force) { - vm.isUserName = (force != undefined || vm.user.name != ''); - vm.label_userName = vm.isUserName ? 'Name:' : 'Enter Full Name:'; - } - function changeUserMobileLabel(force) { - vm.isUserMobile = (force != undefined || vm.user.mobile != ''); - vm.label_userMobile = vm.isUserMobile ? 'Mobile:' : 'Enter Mobile Number:'; - } - function changeUserEmailLabel(force) { - vm.isUserEmail = (force != undefined || vm.user.email != ''); - vm.label_userEmail = vm.isUserEmail ? 'Email:' : 'Enter Email:'; - } - function changeUserAddressLabel(force) { - vm.isUserAddress = (force != undefined || vm.user.address != ''); - vm.label_userAddress = vm.isUserAddress ? 'Address:' : 'Enter Address:'; - } - function changeVehicleRegLabel(force) { - vm.isVehicleReg = (force != undefined || vm.vehicle.reg != ''); - vm.label_vehicleReg = vm.isVehicleReg ? 'Vehcile Registration Number:' : 'Enter Vehicle Registration Number:'; - } - // listen to changes in input fields [END] - function isSame() { var checkuser = userDbInstance.user.mobile == vm.user.mobile && userDbInstance.user.name == vm.user.name && userDbInstance.user.email == vm.user.email && userDbInstance.user.address == vm.user.address; var checkvehicle = (userDbInstance.user.vehicles && userDbInstance.user.vehicles[vm.vehicle.id] && userDbInstance.user.vehicles[vm.vehicle.id].reg == vm.vehicle.reg && userDbInstance.user.vehicles[vm.vehicle.id].manuf == vm.vehicle.manuf && userDbInstance.user.vehicles[vm.vehicle.id].model == vm.vehicle.model) || (vm.vehicle.reg == '' && vm.vehicle.manuf == '' && vm.vehicle.model == ''); @@ -709,10 +685,23 @@ // save to database function save() { + if (vm.user.name == '') + vm.user.name = "Anonymous"; userDbInstance.user.mobile = vm.user.mobile; - userDbInstance.user.name = vm.user.name; userDbInstance.user.email = vm.user.email; userDbInstance.user.address = vm.user.address; + userDbInstance.user.type = vm.user.type; + + if (userDbInstance.user.name != vm.user.name) { + userDbInstance._deleted = true; + amCustomers.saveCustomer(userDbInstance).then(doNothing).catch(doNothing); + var prefixUser = 'usr-' + angular.lowercase(vm.user.name).replace(' ', '-'); + userDbInstance._id = utils.generateUUID(prefixUser); + delete userDbInstance._deleted; + delete userDbInstance._rev; + } + + userDbInstance.user.name = vm.user.name; if (vm.membershipChips != undefined) { var smArray = $.extend([], vm.membershipChips); @@ -720,35 +709,21 @@ smArray.forEach(addMembershipsToUser); } - if (!((vm.vehicle.reg == '' || vm.vehicle.reg == undefined) && (vm.vehicle.manuf == '' || vm.vehicle.manuf == undefined) && (vm.vehicle.model == '' || vm.vehicle.model == undefined))) { - if (!userDbInstance.user.vehicles) - userDbInstance.user.vehicles = {} - var vehicleDbInstance = userDbInstance.user.vehicles[vm.vehicle.id]; - if (vehicleDbInstance) { - vehicleDbInstance.reg = vm.vehicle.reg; - vehicleDbInstance.manuf = vm.vehicle.manuf; - vehicleDbInstance.model = vm.vehicle.model; - if (vm.isNextDueService) - vehicleDbInstance.nextdue = vm.nextDueDate; - else if (vehicleDbInstance.nextdue) - delete vehicleDbInstance['nextdue']; - } else { - var prefixVehicle = 'vhcl' + ((vm.vehicle.manuf && vm.vehicle.model) ? '-' + angular.lowercase(vm.vehicle.manuf).replace(' ', '-') + '-' + angular.lowercase(vm.vehicle.model).replace(' ', '-') : ''); - var vo = { - reg: (vm.vehicle.reg == undefined ? '' : vm.vehicle.reg), - manuf: (vm.vehicle.manuf == undefined ? '' : vm.vehicle.manuf), - model: (vm.vehicle.model == undefined ? '' : vm.vehicle.model) - } - if (vm.isNextDueService) - vo.nextdue = vm.nextDueDate; - userDbInstance.user.vehicles[utils.generateUUID(prefixVehicle)] = vo; - } - } + if (Object.keys(vm.vNextDue)) + Object.keys(vm.vNextDue).forEach(iterateDueDates); if (vm.user.id) amCustomers.saveCustomer(userDbInstance).then(successfullSave).catch(failedSave); else failedSave(); + + function iterateDueDates(vId) { + var t = vm.vNextDue[vId]; + if (t.isNextDue) + userDbInstance.user.vehicles[vId].nextdue = moment(t.nextdue).format(); + else if (!t.isNextDue) + delete userDbInstance.user.vehicles[vId].nextdue; + } function addMembershipsToUser(membership) { var mTreatments = $.extend([], membership.treatments); @@ -769,6 +744,10 @@ delete membership.treatments[treatment.name]['$$hashKey']; } } + + function doNothing(res) { + // do nothing + } } function successfullSave(res) { diff --git a/src/app/components/customers/customers-viewall.controller.js b/src/app/components/customers/customers-viewall.controller.js index 5ea2947d..1a76da17 100644 --- a/src/app/components/customers/customers-viewall.controller.js +++ b/src/app/components/customers/customers-viewall.controller.js @@ -2,7 +2,7 @@ * Controller for View all Customers component * @author ndkcha * @since 0.4.1 - * @version 0.6.0 + * @version 0.7.0 */ /// @@ -36,14 +36,17 @@ vm.deleteCustomer = deleteCustomer; vm.editCustomer = editCustomer; vm.changeQueryMode = changeQueryMode; + vm.IsVehicleAnonymous = IsVehicleAnonymous; // default watchers $scope.$watch('vm.customerQuery', watchCustomerQuery); - - // default execution steps getCustomers(); // function definitions + + function IsVehicleAnonymous(vehicle) { + return (vehicle.reg == 'Vehicle'); + } function watchCustomerQuery(newValue, oldValue) { if(queryChangedPromise){ @@ -112,7 +115,7 @@ } function ignoreDelete() { - console.info('nope'); + // do nothing } function success(res) { diff --git a/src/app/components/customers/customers.factory.js b/src/app/components/customers/customers.factory.js index 01873495..61632cc0 100644 --- a/src/app/components/customers/customers.factory.js +++ b/src/app/components/customers/customers.factory.js @@ -2,7 +2,7 @@ * Factory that handles database interactions between customer database and controller * @author ndkcha * @since 0.4.1 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -11,9 +11,9 @@ angular.module('automintApp') .factory('amCustomers', CustomersFactory); - CustomersFactory.$inject = ['$q', '$http', 'utils', 'pdbCommon', 'pdbCustomers', 'pdbConfig', '$amRoot']; + CustomersFactory.$inject = ['$rootScope', '$q', '$http', 'utils', 'pdbMain']; - function CustomersFactory($q, $http, utils, pdbCommon, pdbCustomers, pdbConfig, $amRoot) { + function CustomersFactory($rootScope, $q, $http, utils, pdbMain) { // initialize factory variable and map functions var factory = { getCustomers: getCustomers, @@ -26,16 +26,34 @@ getMemberships: getMemberships, getRegularTreatments: getRegularTreatments, getVehicleTypes: getVehicleTypes, - getCustomerByMobile: getCustomerByMobile + getCustomerByMobile: getCustomerByMobile, + getCurrencySymbol: getCurrencySymbol }; return factory; // function definitions + function getCurrencySymbol() { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); + return tracker.promise; + + function getSettingsObject(res) { + if (res.currency) + tracker.resolve(res.currency); + else + failure('No Currency Symbol Found!'); + } + + function failure(err) { + tracker.reject(err); + } + } + function getCustomerByMobile(mobile) { var tracker = $q.defer(); - pdbCustomers.query(mapView, { + pdbMain.query(mapView, { include_docs: true, key: mobile }).then(success).catch(failure); @@ -82,13 +100,9 @@ function getVehicleTypes() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(failure); - } - function getSettingsObject(res) { if (res.vehicletypes) tracker.resolve(res.vehicletypes); @@ -104,13 +118,9 @@ function getRegularTreatments() { var tracker = $q.defer(); var treatments = []; - $amRoot.isTreatmentId().then(getConfigDocument).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(getConfigObject).catch(failure); return tracker.promise; - function getConfigDocument(res) { - pdbConfig.get($amRoot.docIds.treatment).then(getConfigObject).catch(failure); - } - function getConfigObject(res) { if (res.regular) Object.keys(res.regular).forEach(iterateTreatments); @@ -137,13 +147,9 @@ memberships: [], total: 0 } - $amRoot.isTreatmentId().then(getTreatmentsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(getTreatmentObject).catch(failure); return tracker.promise; - function getTreatmentsDoc(res) { - pdbConfig.get($amRoot.docIds.treatment).then(getTreatmentObject).catch(failure); - } - function getTreatmentObject(res) { if (res.memberships) Object.keys(res.memberships).forEach(iterateMemberships); @@ -182,13 +188,13 @@ var tracker = $q.defer(); var customers = []; if (query == '' || query == undefined) { - pdbCustomers.getAll({ + pdbMain.getAll({ include_docs: true, limit: limit, skip: --page * limit }).then(successBulk).catch(failure); } else { - pdbCustomers.query({ + pdbMain.query({ map: mapQuery, reduce: reduceQuery }, { @@ -250,9 +256,10 @@ } function iterateValues(value) { - var customer = {}, - vehicles = []; + var customer = {}, vehicles = []; if (value) { + if ($rootScope.amGlobals.IsConfigDoc(value._id) || (value.name == 'Anonymous')) + return; customer.id = value._id; customer.name = value.name; customer.mobile = value.mobile; @@ -283,8 +290,9 @@ res.rows.forEach(iterateRow); function iterateRow(row) { - var customer = {}, - vehicles = []; + if ($rootScope.amGlobals.IsConfigDoc(row.id) || (row.doc.user.name == 'Anonymous')) + return; + var customer = {}, vehicles = []; if (row.doc && row.doc.user) { customer.id = row.doc._id; customer.name = row.doc.user.name; @@ -327,7 +335,7 @@ function getManufacturers() { var tracker = $q.defer(); var manufacturers = []; - pdbCommon.get('manuf-models').then(success).catch(missDb); + $http.get('data/manuf_model.json').success(success).catch(failure); return tracker.promise; // success ? add manufacturers to an array and return it via promise @@ -336,11 +344,6 @@ tracker.resolve(manufacturers); } - // !success ? get manufacturer list from raw json file, then execute success sequence again - function missDb(error) { - $http.get('data/manuf_model.json').success(success).catch(failure); - } - // iterate through manufacturer list and get individual manufacturer function manufIterator(manuf) { if (!manuf.match(/\b_id|\b_rev/i)) @@ -357,7 +360,7 @@ function getModels(manufacturer) { var tracker = $q.defer(); var models = []; - pdbCommon.get('manuf-models').then(success).catch(missDb); + $http.get('data/manuf_model.json').success(success).catch(failure); return tracker.promise; // success ? add models to an array and return it via promise @@ -367,11 +370,6 @@ tracker.resolve(models); } - // !success ? get manufacturer list from raw json file, then execute success sequence again - function missDb(error) { - $http.get('data/manuf_model.json').success(success).catch(failure); - } - // throw an error via promise function failure(error) { tracker.reject(error); @@ -381,12 +379,12 @@ // delete customer from database function deleteCustomer(cId) { var tracker = $q.defer(); - pdbCustomers.get(cId).then(userFound).catch(failure); + pdbMain.get(cId).then(userFound).catch(failure); return tracker.promise; function userFound(res) { res._deleted = true; - pdbCustomers.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } function success(res) { @@ -401,7 +399,7 @@ // save customer to database function saveCustomer(document) { var tracker = $q.defer(); - pdbCustomers.save(document).then(success).catch(failure); + pdbMain.save(document).then(success).catch(failure); return tracker.promise; function success(response) { @@ -414,16 +412,11 @@ } // add new customer - function addNewCustomer(customer, vehicle) { - var prefixUser = 'usr-' + angular.lowercase(customer.name).replace(' ', '-'), - prefixVehicle; - - if (vehicle) { - prefixVehicle = 'vhcl' + ((vehicle.manuf && vehicle.model) ? '-' + angular.lowercase(vehicle.manuf).replace(' ', '-') + '-' + angular.lowercase(vehicle.model).replace(' ', '-') : ''); - customer.vehicles = {}; - delete vehicle.id; - customer.vehicles[utils.generateUUID(prefixVehicle)] = vehicle; - } + function addNewCustomer(customer, vehicles) { + var prefixUser = 'usr-' + angular.lowercase(customer.name).replace(' ', '-'); + + if (vehicles) + customer.vehicles = vehicles; if (customer.memberships != undefined) { var smArray = $.extend([], customer.memberships); @@ -433,7 +426,8 @@ var doc = { _id: utils.generateUUID(prefixUser), - creator: $amRoot.username, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, user: customer } @@ -462,7 +456,7 @@ // get customer from database function getCustomer(id) { - return pdbCustomers.get(id); + return pdbMain.get(id); } } })(); \ No newline at end of file diff --git a/src/app/components/customers/customers_add.html b/src/app/components/customers/customers_add.html index 849226b8..32db4bb9 100644 --- a/src/app/components/customers/customers_add.html +++ b/src/app/components/customers/customers_add.html @@ -1,4 +1,48 @@ arrow_back - Back - - - - -
-
- - person_pin - - - -
-
- - phone - - - - - email - - - + + + + done + Save + Save Customer + + + + + + +
+
+
+ +
-
- - home - - - +
+ +
-
-
- - Please wait -
- - done - Save - - - Add Vehicle - navigate_next - +
+ +
- - - - -
-
-
- Choose Vehicle: - - - {{vm.currentVehicle}} - - - - - {{vehicle.name}} - - - - - - New Vehicle - - - - - (To add new vehicle, click on the button above and select new vehicle) -
-
-
-
- Choose Manufacturer: - - - {{manuf}} - - -
-
- Choose Model: - - - {{model}} - +
+ + + {{type}} + +
+
+
+ + + + {{membership.name}} -
-
-
- - - -
e.g. GJ01AB9999
-
-
- Next Service Reminder: -
- - {{vm.getDate(vm.nextDueDate)}} -
-
+ + + {{$chip.name}} + + +
+
* Click on Membership for details
-
- - done - Save - - - Add Memberships - navigate_next - +
+ +
+
+ Vehicles:
- - - - - - - - - - - - - - - - - - - - - - - -
VehicleDateAmount
(Rs.)
Payment
{{service.vhcl_manuf + ' ' + service.vhcl_model}} ({{service.vhcl_reg}}){{vm.getServiceDate(service.srvc_date)}}{{service.srvc_cost}}{{service.srvc_status}}{{service.srvc_state}} - - delete - -
-
- -
- - -
-
- card_membership -
- - - {{membership.name}} - - - - {{$chip.name}} - - - -
+
+ {{vehicle.shortname}}{{vehicle.name}} +
+ edit + Edit
-
* Click on Membership for details
-
- - done - Save +
+
+
+ Next Service Reminder: +
+ + {{vm.getDate(vm.vNextDue[vm.vehicle.id].nextdue)}} +
+
+
+ + add + Add Vehicle
- - - +
+ + \ No newline at end of file diff --git a/src/app/components/customers/customers_edit.html b/src/app/components/customers/customers_edit.html new file mode 100644 index 00000000..383ef097 --- /dev/null +++ b/src/app/components/customers/customers_edit.html @@ -0,0 +1,274 @@ + + + arrow_back + + + + + done + Save + + + + + + +
+
+
+ + +
+
+ + +
+
+
+ + +
+
+
+ + + {{type}} + +
+
+ + {{vm.services.length}} +
+
+
+
+ + + + {{membership.name}} + + + + {{$chip.name}} + + + +
+
* Click on Membership for details
+
+
+
+ + {{vm.currencySymbol}} {{vm.paymentDone}} +
+
+ + {{vm.currencySymbol}} {{vm.paymentDue}} +
+
+
+ +
+
+ Vehicles: +
+ All Vehicles +
+
+
+ {{vehicle.shortname}}{{vehicle.name}} +
+ edit + Edit +
+
+
+
+
+ Next Service Reminder: +
+ + {{vm.getDate(vm.vNextDue[vm.vehicle.id].nextdue)}} +
+
+
+ + add + Add Vehicle + +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
VehicleDateAmount ({{vm.currencySymbol}})Payment
{{service.vhcl_manuf + ' ' + service.vhcl_model}} ({{service.vhcl_reg}}){{vm.getServiceDate(service.srvc_date)}}{{service.srvc_cost}}{{service.srvc_status}}{{service.srvc_state}}
+
+
+
+
\ No newline at end of file diff --git a/src/app/components/customers/customers_viewAll.html b/src/app/components/customers/customers_viewAll.html index f403de51..5badee83 100644 --- a/src/app/components/customers/customers_viewAll.html +++ b/src/app/components/customers/customers_viewAll.html @@ -37,7 +37,7 @@ {{customer.name}} {{customer.mobile}} {{customer.email}} - {{vehicle.manuf + ' ' + vehicle.model}} ({{vehicle.reg}})
+ {{vehicle.manuf + ' ' + vehicle.model}} ({{vehicle.reg}})
delete diff --git a/src/app/components/customers/tmpl/vehicle-crud.controller.js b/src/app/components/customers/tmpl/vehicle-crud.controller.js new file mode 100644 index 00000000..853261d4 --- /dev/null +++ b/src/app/components/customers/tmpl/vehicle-crud.controller.js @@ -0,0 +1,133 @@ +/** + * Controller for Dialog box for CRUD Operations on Particular Vehicle + * @author ndkcha + * @since 0.7.0 + * @version 0.7.0 + */ + +/// + +(function() { + angular.module('automintApp').controller('amCtrlCuVeCRUD', VehicleCRUDController); + + VehicleCRUDController.$inject = ['$mdDialog', '$q', 'utils', 'amCustomers', 'vehicle']; + + function VehicleCRUDController($mdDialog, $q, utils, amCustomers, vehicle) { + // initialize view model + var vm = this; + + // named assignments to keep track of temporary variables + var autofillVehicle = false; + + // named assignments to view model + vm.vehicle = vehicle; + vm.manufacturers = []; + vm.model = []; + + // function maps to view model + vm.manufacturersQuerySearch = manufacturersQuerySearch; + vm.modelQuerySearch = modelQuerySearch; + vm.searchVehicleChange = searchVehicleChange; + vm.autoCapitalizeVehicleModel = autoCapitalizeVehicleModel; + vm.convertRegToCaps = convertRegToCaps; + vm.save = save; + vm.cancel = cancel; + + // function definitions + + // query search for manufacturers [autocomplete] + function manufacturersQuerySearch() { + var tracker = $q.defer(); + var results = (vm.vehicle.manuf ? vm.manufacturers.filter(createFilterForManufacturers(vm.vehicle.manuf)) : vm.manufacturers); + + if (results.length > 0) { + return results; + } + + amCustomers.getManufacturers().then(allotManufacturers).catch(noManufacturers); + return tracker.promise; + + function allotManufacturers(res) { + vm.manufacturers = res; + results = (vm.vehicle.manuf ? vm.manufacturers.filter(createFilterForManufacturers(vm.vehicle.manuf)) : vm.manufacturers); + tracker.resolve(results); + } + + function noManufacturers(error) { + results = []; + tracker.resolve(results); + } + } + + // create filter for manufacturers' query list + function createFilterForManufacturers(query) { + var lcQuery = angular.lowercase(query); + return function filterFn(item) { + item = angular.lowercase(item); + return (item.indexOf(lcQuery) === 0); + } + } + + // query search for model [autocomplete] + function modelQuerySearch() { + var tracker = $q.defer(); + var results = (vm.vehicle.model ? vm.models.filter(createFilterForModel(vm.vehicle.model)) : vm.models); + + if (results.length > 0) + return results; + + amCustomers.getModels(vm.vehicle.manuf).then(allotModels).catch(noModels); + return tracker.promise; + + function allotModels(res) { + vm.models = res; + results = (vm.vehicle.model ? vm.models.filter(createFilterForModel(vm.vehicle.model)) : vm.models); + tracker.resolve(results); + } + + function noModels(err) { + results = []; + tracker.resolve(results); + } + } + + // create filter for models' query list + function createFilterForModel(query) { + var lcQuery = angular.lowercase(query); + return function filterFn(item) { + item = angular.lowercase(item); + return (item.indexOf(lcQuery) === 0); + } + } + + function searchVehicleChange(e) { + autoCapitalizeVehicleManuf(); + if (!autofillVehicle) { + vm.models = []; + vm.vehicle.model = ''; + autofillVehicle = false; + } else + autofillVehicle = false; + } + + function autoCapitalizeVehicleModel() { + vm.vehicle.model = utils.autoCapitalizeWord(vm.vehicle.model); + } + + function autoCapitalizeVehicleManuf() { + vm.vehicle.manuf = utils.autoCapitalizeWord(vm.vehicle.manuf); + } + + function convertRegToCaps() { + vm.vehicle.reg = vm.vehicle.reg.toUpperCase(); + } + + function save() { + $mdDialog.hide(vm.vehicle); + } + + function cancel() { + $mdDialog.cancel(); + } + } +})(); \ No newline at end of file diff --git a/src/app/components/customers/tmpl/vehicle-crud.tmpl.html b/src/app/components/customers/tmpl/vehicle-crud.tmpl.html new file mode 100644 index 00000000..30555d9a --- /dev/null +++ b/src/app/components/customers/tmpl/vehicle-crud.tmpl.html @@ -0,0 +1,66 @@ + + + + Edit Vehicle Info +
+
+ + + + {{manuf}} + + +
+
+ + + + {{model}} + + +
+
+ + +
+
+
+ + + done + Save + + + close + Cancel + + +
\ No newline at end of file diff --git a/src/app/components/dashboard/dashboard.controller-deps.js b/src/app/components/dashboard/dashboard.controller-deps.js index 01e0559d..df21f96a 100644 --- a/src/app/components/dashboard/dashboard.controller-deps.js +++ b/src/app/components/dashboard/dashboard.controller-deps.js @@ -2,7 +2,7 @@ * Controller for dashboard sub-views * @author ndkcha * @since 0.6.4 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -36,11 +36,16 @@ vm.services = unbilledServices; vm.editService = editService; vm.closeDialog = closeDialog; + vm.getCost = getCost; // default execution steps vm.services.sort(sortFunction); // function definitions + + function getCost(service) { + return (service.srvc_payreceived ? (parseFloat(service.srvc_cost) - parseFloat(service.srvc_payreceived)) : parseFloat(service.srvc_cost)); + } function sortFunction(lhs, rhs) { return (rhs.srvc_date.localeCompare(lhs.srvc_date)); @@ -98,6 +103,7 @@ // default execution steps populateYearRange(); + detectUnavailable(); // function mappings vm.IsNextYear = IsNextYear; @@ -111,6 +117,27 @@ // function definitions + function detectUnavailable() { + var newlist = []; + vm.selectedDateSet.forEach(iterateDateSet); + vm.selectedDateSet = newlist; + + function iterateDateSet(ds) { + var found = $filter('filter')(filterRange, { + year: ds.year, + month: ds.month + }, true); + + if (found.length == 1) { + newlist.push(found[0]); + } + } + + function deleteSelected(ds) { + vm.selectedDateSet.splice(ds, 1); + } + } + function confirm() { if (vm.selectedDateSet.length < 1) vm.selectedDateSet = currentTimeSet; @@ -204,12 +231,17 @@ vm.editCustomer = editCustomer; vm.deleteServiceReminder = deleteServiceReminder; vm.changeDate = changeDate; + vm.IsReminderInPast = IsReminderInPast; // default execution steps manageCustomers(dueCustomers); // function definitions + function IsReminderInPast(date) { + return (moment().format().localeCompare(moment(date).format()) > 0); + } + function changeDate(customer) { amDashboard.changeServiceReminderDate(customer.cstmr_id, customer.vhcl_id, moment(customer.vhcl_nextdue).format()).then(success).catch(failure); @@ -218,7 +250,7 @@ } function failure(err) { - console.warn(err); + // do nothing } } @@ -239,14 +271,13 @@ } function failure(err) { - console.warn(err); + // do nothing } } function editCustomer(cId) { $state.go('restricted.customers.edit', { id: cId, - openTab: 'vehicle', fromState: 'dashboard.nextdueservices' }); $mdDialog.hide(); @@ -264,7 +295,7 @@ amDashboard.getNextDueCustomers(vm.nsdcTime).then(generateNdcData).catch(failure); function failure(err) { - console.warn(err); + // do nothing } } diff --git a/src/app/components/dashboard/dashboard.controller.js b/src/app/components/dashboard/dashboard.controller.js index 73e00914..fbb55a23 100644 --- a/src/app/components/dashboard/dashboard.controller.js +++ b/src/app/components/dashboard/dashboard.controller.js @@ -2,7 +2,7 @@ * Controller for dashboard view * @author ndkcha * @since 0.4.1 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -12,9 +12,9 @@ angular.module('automintApp').controller('dashboardCtrl', DashboardController); - DashboardController.$inject = ['$state', '$filter', '$log', '$mdDialog', '$amRoot', 'utils', 'amDashboard']; + DashboardController.$inject = ['$rootScope', '$state', '$filter', '$log', '$mdDialog', '$amRoot', 'utils', 'amDashboard']; - function DashboardController($state, $filter, $log, $mdDialog, $amRoot, utils, amDashboard) { + function DashboardController($rootScope, $state, $filter, $log, $mdDialog, $amRoot, utils, amDashboard) { // initialize view model var vm = this; var ubServices = [], nwCustomers = [], filterRange = [], isNextDueServicesOpened = false; @@ -82,6 +82,7 @@ vm.nextServiceDueCustomers = []; vm.nsdcTimeRange = ['Today', 'This Week', 'This Month', 'All']; vm.nsdcTime = vm.nsdcTimeRange[0]; + vm.currencySymbol = "Rs."; // function maps vm.addNewService = addNewService; @@ -96,15 +97,83 @@ vm.IsNextDueFieldLong = IsNextDueFieldLong; vm.openNextDueServices = openNextDueServices; vm.IsNoNextDueReminders = IsNoNextDueReminders; + vm.IsReminderInPast = IsReminderInPast; + vm.refreshDashboard = refreshDashboard; // default execution steps + $rootScope.hidePreloader = true; initCurrentTimeSet(); getFilterMonths(); - $amRoot.ccViews(); processPreferences(); + getCurrencySymbol(); // function definitions + function refreshDashboard() { + $rootScope.busyApp.show = true; + $rootScope.busyApp.message = 'Refreshing Dashboard....'; + $rootScope.isOnChangeMainDbBlocked = true; + $amRoot.generateCacheDocs(true).then(fakeWait).catch(fakeWait); + + function fakeWait() { + $rootScope.isOnChangeMainDbBlocked = false; + setTimeout(reloadData, 1000); + } + + function reloadData() { + $rootScope.busyApp.show = false; + $state.go($state.current, {}, {reload: true}); + } + } + + function openCurrencyDialog() { + $mdDialog.show({ + controller: 'amCtrlDashCurrency', + controllerAs: 'vm', + templateUrl: 'app/components/dashboard/tmpl/dialog-setcurrency.tmpl.html', + parent: angular.element(document.body), + targetEvent: event, + clickOutsideToClose: false + }).then(success).catch(success); + + function success(res) { + if (!res) { + openCurrencyDialog(); + return; + } + vm.currencySymbol = res; + amDashboard.saveCurrencySymbol(vm.currencySymbol).then(success).catch(failure); + + function success(res) { + if (res.ok) + utils.showSimpleToast('Currency saved successfully!'); + else + failure(); + } + + function failure(err) { + utils.showSimpleToast('Could not save Currency at moment! Try Again!'); + openCurrencyDialog(); + } + } + } + + function IsReminderInPast(date) { + return (moment().format().localeCompare(date) > 0); + } + + function getCurrencySymbol() { + amDashboard.getCurrencySymbol().then(success).catch(failure); + + function success(res) { + vm.currencySymbol = res; + } + + function failure(err) { + openCurrencyDialog(); + } + } + function IsNoNextDueReminders() { return (vm.nextServiceDueCustomers.length == 0); } @@ -207,7 +276,6 @@ amDashboard.getNewCustomers(vm.currentTimeSet).then(generateNcpData).catch(failure); amDashboard.getProblemsAndVehicleTypes(vm.currentTimeSet).then(sortProblemsAndVehicleTypes).catch(failure); changeNsdcTimeRange(vm.nsdcTimeRange[0]); - console.warn(err.message); } } @@ -255,7 +323,7 @@ } function failure(err) { - console.info('failed to get filter months'); + // do nothing } } @@ -423,7 +491,7 @@ openDuePayments(); function iterateUnbilledServices(ubs) { - vm.totalPendingPayments += parseFloat(ubs.srvc_cost); + vm.totalPendingPayments += (ubs.srvc_payreceived) ? (parseFloat(ubs.srvc_cost) - parseFloat(ubs.srvc_payreceived)) : parseFloat(ubs.srvc_cost); } } @@ -465,6 +533,8 @@ ++vm.totalServicesDone; if (service.srvc_status == 'Paid') vm.totalRevenueEarned += parseFloat(service.srvc_cost); + else + vm.totalRevenueEarned += (service.srvc_payreceived ? parseFloat(service.srvc_payreceived) : 0); var d = moment(service.srvc_date).format('DD MMM YYYY'); if (!spd[d]) { spd[d] = 0; @@ -480,7 +550,7 @@ } function failure(err) { - console.warn(err); + // do nothing } } })();; \ No newline at end of file diff --git a/src/app/components/dashboard/dashboard.factory.js b/src/app/components/dashboard/dashboard.factory.js index a998896d..b8b375e5 100644 --- a/src/app/components/dashboard/dashboard.factory.js +++ b/src/app/components/dashboard/dashboard.factory.js @@ -2,7 +2,7 @@ * Factory that handles database interactions between dashboard dataset and controller * @author ndkcha * @since 0.6.0 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -10,9 +10,9 @@ (function() { angular.module('automintApp').factory('amDashboard', DashboardFactory); - DashboardFactory.$inject = ['$q', '$filter', 'utils', 'constants', 'pdbCache', 'pdbCustomers']; + DashboardFactory.$inject = ['$q', '$filter', '$rootScope', 'utils', 'constants', 'pdbMain', 'pdbCache']; - function DashboardFactory($q, $filter, utils, constants, pdbCache, pdbCustomers) { + function DashboardFactory($q, $filter, $rootScope, utils, constants, pdbMain, pdbCache) { // initialize dashboard factory and funtion mappings var factory = { getTotalCustomerServed: getTotalCustomerServed, @@ -21,21 +21,69 @@ getFilterMonths: getFilterMonths, getNextDueCustomers: getNextDueCustomers, deleteServiceReminder: deleteServiceReminder, - changeServiceReminderDate: changeServiceReminderDate + changeServiceReminderDate: changeServiceReminderDate, + getCurrencySymbol: getCurrencySymbol, + saveCurrencySymbol: saveCurrencySymbol } return factory; // function definitions + function saveCurrencySymbol(currency) { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds).then(getSettingsObject).catch(writeSettingsObject); + return tracker.promise; + + function getSettingsObject(res) { + res.currency = currency; + pdbMain.save(res).then(success).catch(failure); + } + + function writeSettingsObject(err) { + var doc = { + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, + currency: currency + } + pdbMain.save(doc).then(success).catch(failure); + } + + function success(res) { + tracker.resolve(res); + } + + function failure(err) { + tracker.reject(err); + } + } + + function getCurrencySymbol() { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); + return tracker.promise; + + function getSettingsObject(res) { + if (res.currency) + tracker.resolve(res.currency); + else + failure('No Currency Symbol Found!'); + } + + function failure(err) { + tracker.reject(err); + } + } + function changeServiceReminderDate(cId, vId, nextdue) { var tracker = $q.defer(); - pdbCustomers.get(cId).then(getCustomerDoc).catch(failure); + pdbMain.get(cId).then(getCustomerDoc).catch(failure); return tracker.promise; function getCustomerDoc(res) { res.user.vehicles[vId].nextdue = nextdue; - pdbCustomers.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } function success(res) { @@ -49,12 +97,12 @@ function deleteServiceReminder(cId, vId) { var tracker = $q.defer(); - pdbCustomers.get(cId).then(getCustomerDoc).catch(failure); + pdbMain.get(cId).then(getCustomerDoc).catch(failure); return tracker.promise; function getCustomerDoc(res) { delete res.user.vehicles[vId].nextdue; - pdbCustomers.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } function success(res) { @@ -68,7 +116,7 @@ function getNextDueCustomers(dateRange) { var tracker = $q.defer(); - pdbCache.get(constants.pdb_cache_views.view_services).then(generateNextDueCustomers).catch(failure); + pdbCache.get(constants.pdb_cache_views.view_next_due_vehicles).then(generateNextDueCustomers).catch(failure); return tracker.promise; function generateNextDueCustomers(res) { @@ -101,16 +149,17 @@ function iterateDateRange(dr) { if (dr.match(/_id|_rev/g)) return; - Object.keys(res[dr]).forEach(iterateService); + Object.keys(res[dr]).forEach(iterateVehicles); - function iterateService(sId) { - if (res[dr][sId].vhcl_nextdue && ((dateRange == 'All') || ((moment(res[dr][sId].vhcl_nextdue).format(dateFormat).localeCompare(startdate) >= 0) && (moment(res[dr][sId].vhcl_nextdue).format(dateFormat).localeCompare(enddate) <= 0)))) { + function iterateVehicles(vId) { + res[dr][vId].vhcl_id = vId; + if (res[dr][vId].vhcl_nextdue && ((dateRange == 'All') || ((moment(res[dr][vId].vhcl_nextdue).format(dateFormat).localeCompare(startdate) >= 0) && (moment(res[dr][vId].vhcl_nextdue).format(dateFormat).localeCompare(enddate) <= 0)))) { var cfound = $filter('filter')(result, { - cstmr_id: res[dr][sId].cstmr_id + cstmr_id: res[dr][vId].cstmr_id }, true); if (cfound.length == 0) - result.push(res[dr][sId]); + result.push(res[dr][vId]); } } } @@ -180,7 +229,7 @@ function getProblemsAndVehicleTypes(dateRange) { var problems = {}, vehicleTypes = {}; var tracker = $q.defer(); - pdbCustomers.getAll().then(success).catch(failure); + pdbMain.getAll().then(success).catch(failure); return tracker.promise; function success(res) { @@ -191,6 +240,8 @@ }); function iterateRows(row) { + if ($rootScope.amGlobals.IsConfigDoc(row.id)) + return; if (row.doc.user.vehicles) Object.keys(row.doc.user.vehicles).forEach(iterateVehicles); diff --git a/src/app/components/dashboard/dashboard.html b/src/app/components/dashboard/dashboard.html index f065e149..fa231541 100644 --- a/src/app/components/dashboard/dashboard.html +++ b/src/app/components/dashboard/dashboard.html @@ -75,9 +75,31 @@ .am-dashboard-table-nxtdue tr:hover td { color: #212121; } + + .amb-refresh { + outline: none; + cursor: pointer; + transition: background 300ms ease; + padding-right: 14px; + } + + .amb-refresh:hover { + background: rgba(0, 0, 0, 0.1); + } + + .amb-refresh:focus { + background: rgba(0, 0, 0, 0.1); + } - + +
+ + refresh + + Refresh Dashboard +
+
Showing data for : {{vm.ddTimeSet}} date_range @@ -100,7 +122,7 @@
Income
- Rs.$$$Rs.{{vm.totalRevenueEarned}} + {{vm.currencySymbol}} $$${{vm.currencySymbol}} {{vm.totalRevenueEarned}}
@@ -110,7 +132,7 @@
Due Payments
- Rs.{{vm.totalPendingPayments}} + {{vm.currencySymbol}} {{vm.totalPendingPayments}}
@@ -177,9 +199,9 @@ - - - + + +
{{vm.getNxtDueField(customer.cstmr_name)}}{{customer.cstmr_name}}{{vm.getNxtDueField(customer.cstmr_mobile)}}{{customer.cstmr_mobile}}{{vm.getNextDueVehicle(customer.vhcl_manuf,customer.vhcl_model,customer.vhcl_reg)}}{{vm.getNextDueVehicle(customer.vhcl_manuf,customer.vhcl_model,customer.vhcl_reg, true)}}{{vm.getNxtDueField(customer.cstmr_name)}}{{customer.cstmr_name}}{{vm.getNxtDueField(customer.cstmr_mobile)}}{{customer.cstmr_mobile}}{{vm.getNextDueVehicle(customer.vhcl_manuf,customer.vhcl_model,customer.vhcl_reg)}}{{vm.getNextDueVehicle(customer.vhcl_manuf,customer.vhcl_model,customer.vhcl_reg, true)}}
diff --git a/src/app/components/dashboard/tmpl/dashboard_due-payments.tmpl.html b/src/app/components/dashboard/tmpl/dashboard_due-payments.tmpl.html index b3c82b88..35b1da33 100644 --- a/src/app/components/dashboard/tmpl/dashboard_due-payments.tmpl.html +++ b/src/app/components/dashboard/tmpl/dashboard_due-payments.tmpl.html @@ -18,7 +18,7 @@ Mobile Vehicle Date - Cost + Payment Due @@ -27,7 +27,7 @@ {{service.cstmr_mobile}} {{service.vhcl_manuf + ' ' + service.vhcl_model}} ({{service.vhcl_reg}}) {{vm.getServiceDate(service.srvc_date)}} - {{service.srvc_cost}} + {{vm.getCost(service)}} diff --git a/src/app/components/dashboard/tmpl/dialog-setcurrency.controller.js b/src/app/components/dashboard/tmpl/dialog-setcurrency.controller.js new file mode 100644 index 00000000..067b13b7 --- /dev/null +++ b/src/app/components/dashboard/tmpl/dialog-setcurrency.controller.js @@ -0,0 +1,74 @@ +/** + * Controller for Set Currency Dialogbox + * @author ndkcha + * @since 0.7.0 + * @version 0.7.0 + */ + +/// + +(function() { + angular.module('automintApp').controller('amCtrlDashCurrency', CurrencyController); + + CurrencyController.$inject = ['$mdDialog', 'utils']; + + function CurrencyController($mdDialog, utils) { + // initialize view model + var vm = this; + + // named assignments for view model + vm.countries = [{ + name: 'India', + currency: 'Rs.' + }, { + name: 'North America', + currency: '$' + }]; + vm.selectedCountry = vm.countries[0]; + + // function mappings to view model + vm.IsCountrySelected = IsCountrySelected; + vm.selectCountry = selectCountry; + vm.changeCountry = changeCountry; + vm.save = save; + + // function definitions + + function focusCurrencyInput() { + $('#ami-currency-symbol').focus(); + } + + function selectCountry(country) { + vm.selectedCountry = country; + vm.isOtherCountry = false; + } + + function IsCountrySelected(country) { + return (vm.selectedCountry == country); + } + + function changeCountry(force) { + if (force != undefined) { + if (vm.currencySymbol == '') { + vm.isOtherCountry = false; + vm.selectedCountry = vm.countries[0]; + } else + vm.isOtherCountry = force; + } + if (vm.isOtherCountry) { + vm.selectedCountry = undefined; + setTimeout(focusCurrencyInput, 300); + } else + vm.selectedCountry = vm.countries[0]; + } + + function save() { + if ((vm.isOtherCountry == true) && vm.currencySymbol == '') { + utils.showSimpleToast('Please enter currency symbol. Or choose one of the countries.'); + return; + } + var currency = (vm.isOtherCountry) ? vm.currencySymbol : vm.selectedCountry.currency; + $mdDialog.hide(currency); + } + } +})(); \ No newline at end of file diff --git a/src/app/components/dashboard/tmpl/dialog-setcurrency.tmpl.html b/src/app/components/dashboard/tmpl/dialog-setcurrency.tmpl.html new file mode 100644 index 00000000..eff6e711 --- /dev/null +++ b/src/app/components/dashboard/tmpl/dialog-setcurrency.tmpl.html @@ -0,0 +1,36 @@ + + + +
+ Which country are you from ? +
+ + {{country.name}} + +
+
+ or Enter your currency: + +
+
+
+ + done + Done + Save Settings + +
+
+
\ No newline at end of file diff --git a/src/app/components/dashboard/tmpl/dialog_nextdueservices.tmpl.html b/src/app/components/dashboard/tmpl/dialog_nextdueservices.tmpl.html index 9b97c43a..5ecd657a 100644 --- a/src/app/components/dashboard/tmpl/dialog_nextdueservices.tmpl.html +++ b/src/app/components/dashboard/tmpl/dialog_nextdueservices.tmpl.html @@ -53,12 +53,12 @@ - {{customer.cstmr_name}} - {{customer.cstmr_mobile}} - {{customer.vhcl_manuf + ' ' + customer.vhcl_model}} ({{customer.vhcl_reg}}) + {{customer.cstmr_name}} + {{customer.cstmr_mobile}} + {{customer.vhcl_manuf + ' ' + customer.vhcl_model}} ({{customer.vhcl_reg}}) - {{vm.getDate(customer.vhcl_nextdue)}} + {{vm.getDate(customer.vhcl_nextdue)}} diff --git a/src/app/components/dashboard/tmpl/dialog_timefilter.html b/src/app/components/dashboard/tmpl/dialog_timefilter.html index 90cae099..29da0b7b 100644 --- a/src/app/components/dashboard/tmpl/dialog_timefilter.html +++ b/src/app/components/dashboard/tmpl/dialog_timefilter.html @@ -98,7 +98,7 @@ - + done Done diff --git a/src/app/components/inventory/inventory-edit.controller.js b/src/app/components/inventory/inventory-edit.controller.js index 367e4930..95991539 100644 --- a/src/app/components/inventory/inventory-edit.controller.js +++ b/src/app/components/inventory/inventory-edit.controller.js @@ -2,7 +2,7 @@ * Controller for Edit Inventory component * @author ndkcha * @since 0.6.1 - * @version 0.6.1 + * @version 0.7.0 */ /// @@ -10,9 +10,9 @@ (function() { angular.module('automintApp').controller('amCtrlInUI', EditInventoryController); - EditInventoryController.$inject = ['$state', 'utils', 'amInventory']; + EditInventoryController.$inject = ['$rootScope', '$state', 'utils', 'amInventory']; - function EditInventoryController($state, utils, amInventory) { + function EditInventoryController($rootScope, $state, utils, amInventory) { // Initialize view model var vm = this; diff --git a/src/app/components/inventory/inventory-viewall.controller.js b/src/app/components/inventory/inventory-viewall.controller.js index 7a616be6..4462f3e5 100644 --- a/src/app/components/inventory/inventory-viewall.controller.js +++ b/src/app/components/inventory/inventory-viewall.controller.js @@ -2,7 +2,7 @@ * Controller for View All Inventories component * @author ndkcha * @since 0.6.1 - * @version 0.6.1 + * @version 0.7.0 */ /// @@ -10,9 +10,9 @@ (function() { angular.module('automintApp').controller('amCtrlInRA', ViewAllInventoryController); - ViewAllInventoryController.$inject = ['$state', 'utils', 'amInventory']; + ViewAllInventoryController.$inject = ['$rootScope', '$state', 'utils', 'amInventory']; - function ViewAllInventoryController($state, utils, amInventory) { + function ViewAllInventoryController($rootScope, $state, utils, amInventory) { // Initialize view model var vm = this; diff --git a/src/app/components/inventory/inventory.factory.js b/src/app/components/inventory/inventory.factory.js index 732dd6f6..a74f7b9d 100644 --- a/src/app/components/inventory/inventory.factory.js +++ b/src/app/components/inventory/inventory.factory.js @@ -2,7 +2,7 @@ * Factory that handles database interactions between inventory database and controller * @author ndkcha * @since 0.6.1 - * @version 0.6.1 + * @version 0.7.0 */ /// @@ -10,9 +10,9 @@ (function() { angular.module('automintApp').factory('amInventory', InventoryFactory); - InventoryFactory.$inject = ['$q', '$amRoot', '$filter', 'utils', 'pdbConfig']; + InventoryFactory.$inject = ['$q', '$rootScope', '$filter', 'pdbMain']; - function InventoryFactory($q, $amRoot, $filter, utils, pdbConfig) { + function InventoryFactory($q, $rootScope, $filter, pdbMain) { // Initialize factory variable and function mappings var factory = { getInventory: getInventory, @@ -29,59 +29,51 @@ function getDisplayAsList() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(configFound).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(configDocFound).catch(failure); return tracker.promise; - function configFound(res) { - pdbConfig.get($amRoot.docIds.settings).then(configDocFound).catch(failure); - } - function configDocFound(res) { if (res.settings && res.settings.inventory) tracker.resolve(res.settings.inventory.displayAsList); else - failure(); + failure('Settings not found!'); } function failure(err) { - if (!err) { - err = { - success: false, - message: 'Setting not found!' - } - } tracker.reject(err); } } function changeDisplayAsList(displayAsList) { var tracker = $q.defer(); - $amRoot.isSettingsId().then(configFound).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(configDocFound).catch(writeNewConfig); return tracker.promise; - function configFound(res) { - pdbConfig.get($amRoot.docIds.settings).then(configDocFound).catch(writeNewConfig); - } function configDocFound(res) { if (!res.settings) res.settings = {}; if (!res.settings.inventory) res.settings.inventory = {}; res.settings.inventory['displayAsList'] = displayAsList; - pdbConfig.save(res).then(saveSuccess).catch(failure); + pdbMain.save(res).then(saveSuccess).catch(failure); } + function writeNewConfig(err) { - var doc = {}; - doc['_id'] = utils.generateUUID('sttngs'); - doc['creator'] = $amRoot.username; + var doc = { + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, + }; doc.settings = {}; doc.settings['inventory'] = {} doc.settings.inventory['displayAsList'] = displayAsList; - pdbConfig.save(doc).then(saveSuccess).catch(failure); + pdbMain.save(doc).then(saveSuccess).catch(failure); } + function saveSuccess(response) { tracker.resolve(response); } + function failure(error) { tracker.reject(error); } @@ -89,19 +81,15 @@ function deleteInventory(name) { var tracker = $q.defer(); - $amRoot.isInventoryId().then(getInventoryDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.inventory).then(getInventoryObj).catch(failure); return tracker.promise; - function getInventoryDoc(res) { - pdbConfig.get($amRoot.docIds.inventory).then(getInventoryObj).catch(failure); - } - function getInventoryObj(res) { if (res[name]) { res[name]._deleted = true; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } else - failure(); + failure('Object not found!'); } function success(res) { @@ -109,25 +97,15 @@ } function failure(err) { - if (!err) { - err = { - success: false, - message: 'Object Not Found!' - } - } tracker.reject(err); } } function getInventory(name) { var tracker = $q.defer(); - $amRoot.isInventoryId().then(getInventoryDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.inventory).then(getInventoryObj).catch(failure); return tracker.promise; - function getInventoryDoc(res) { - pdbConfig.get($amRoot.docIds.inventory).then(getInventoryObj).catch(failure); - } - function getInventoryObj(res) { if (res[name]) { var temp = res[name]; @@ -151,19 +129,15 @@ function getInventories() { var tracker = $q.defer(); var response = []; - $amRoot.isInventoryId().then(getInventoryDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.inventory).then(getInventoryObj).catch(failure); return tracker.promise; - function getInventoryDoc(res) { - pdbConfig.get($amRoot.docIds.inventory).then(getInventoryObj).catch(failure); - } - function getInventoryObj(res) { Object.keys(res).forEach(iterateInventories); tracker.resolve(response); function iterateInventories(name) { - if (name.match(/\b_id|\b_rev|\bcreator/i) || res[name]._deleted == true) + if (name.match(/\b_id|\b_rev|\bcreator|\bchannel/i) || res[name]._deleted == true) return; var temp = res[name]; temp.name = name; @@ -179,18 +153,14 @@ function saveInventory(inventory, operationMode) { var tracker = $q.defer(); - $amRoot.isInventoryId().then(getInventoryDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.inventory).then(getInventoryObj).catch(writeInventoryDoc); return tracker.promise; - function getInventoryDoc(res) { - pdbConfig.get($amRoot.docIds.inventory).then(getInventoryObj).catch(writeInventoryDoc); - } - function getInventoryObj(res) { if (!(res[inventory.name] && operationMode == 'add')) { res[inventory.name] = inventory; delete res[inventory.name].name; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } else { tracker.resolve({ ok: true, @@ -201,12 +171,13 @@ function writeInventoryDoc(err) { var doc = { - _id: utils.generateUUID('invntry'), - creator: $amRoot.username + _id: $rootScope.amGlobals.configDocIds.inventory, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel }; doc[inventory.name] = inventory; delete inventory.name; - pdbConfig.save(doc).then(success).catch(failure); + pdbMain.save(doc).then(success).catch(failure); } function success(res) { diff --git a/src/app/components/inventory/inventory_add.html b/src/app/components/inventory/inventory_add.html index 332e9ae7..80baa17f 100644 --- a/src/app/components/inventory/inventory_add.html +++ b/src/app/components/inventory/inventory_add.html @@ -1,6 +1,5 @@ arrow_back - Back
diff --git a/src/app/components/invoices/invoices-view.controller.js b/src/app/components/invoices/invoices-view.controller.js index 7002b8c9..14c71dc9 100644 --- a/src/app/components/invoices/invoices-view.controller.js +++ b/src/app/components/invoices/invoices-view.controller.js @@ -2,7 +2,7 @@ * Controller for View Invoice component * @author ndkcha * @since 0.5.0 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -18,19 +18,25 @@ .controller('amCtrlIvRI', InvoicesViewController) .controller('amCtrlCmI', ConfirmMailController); - InvoicesViewController.$inject = ['$q', '$log', '$state', '$window', '$mdDialog', 'utils', 'amInvoices']; + InvoicesViewController.$inject = ['$rootScope', '$q', '$log', '$state', '$window', '$mdDialog', 'utils', 'amInvoices']; ConfirmMailController.$inject = ['$mdDialog', 'utils', 'user']; - function InvoicesViewController($q, $log, $state, $window, $mdDialog, utils, amInvoices) { + function InvoicesViewController($rootScope, $q, $log, $state, $window, $mdDialog, utils, amInvoices) { // initialize view model var vm = this; var oCustomerEmail; + var rowCount = 0, membershipTreatmentCount = 0, packageTreatmentCount = 0, treatmentCount = 0, inventoryCount = 0, packageCount = {}, membershipCount = {}; // named assignments to keep track of UI elements vm.isFabOpen = true; vm.fabClass = ''; vm.subtotal = 0; + vm.currencySymbol = "Rs."; + vm.taxSettings = []; + vm.invoicePageSizeList = ['Single Page', 'A4']; + vm.invoicePageSize = vm.invoicePageSizeList[0]; + vm.pages = []; // function maps vm.printInvoice = printInvoice; @@ -51,24 +57,353 @@ vm.IsInvoiceAvailable = IsInvoiceAvailable; vm.IsSubtotalEnabled = IsSubtotalEnabled; vm.calculateSubtotal = calculateSubtotal; + vm.IsTaxEnabled = IsTaxEnabled; + vm.IsHeaderAvailable = IsHeaderAvailable; + vm.IsLastPage = IsLastPage; + vm.currentPage = currentPage; + vm.IsNotSinglePage = IsNotSinglePage; + vm.IsCustomerNotAnonymus = IsCustomerNotAnonymus; + vm.IsVehicleNotAnonymus = IsVehicleNotAnonymus; + vm.getIndexCount = getIndexCount; + + // electron watchers + eIpc.on('am-invoice-mail-sent', OnInvoiceMailSent); // default execution steps + if ($state.params.userId == undefined || $state.params.vehicleId == undefined || $state.params.serviceId == undefined) { utils.showSimpleToast('Something went wrong. Please try again!') $state.go('restricted.services.all'); return; } + getCurrencySymbol(); fillInvoiceDetails(); loadInvoiceWLogo(); + loadInvoiceFLogo(); getIvAlignMargins(); - - // electron watchers - eIpc.on('am-invoice-mail-sent', OnInvoiceMailSent); + getInvoicePageSize(); // function definitions + function getIndexCount(root) { + return (root - 1); + } + + function IsVehicleNotAnonymus() { + return (vm.vehicle.reg != 'Vehicle'); + } + + function IsCustomerNotAnonymus() { + return (vm.user.name != 'Anonymous'); + } + + function loadInvoiceFLogo() { + var source = localStorage.getItem('invoice-f-pic'); + vm.invoiceFLogo = source; + } + + function addInvoiceFLogo() { + var elems = document.getElementsByName('am-invoice-f-logo-holder'); + elems.forEach(iterateElements); + + function iterateElements(elem) { + if (elem.hasChildNodes()) + return; + var x = document.createElement("IMG"); + x.setAttribute("src", vm.invoiceFLogo); + elem.appendChild(x); + } + } + + function removeInvoiceFogo() { + var elems = document.getElementsByName('am-invoice-f-logo-holder'); + elems.forEach(iterateElements); + + function iterateElements(elem) { + while (elem.firstChild) { + elem.removeChild(elem.firstChild); + } + } + } + + function IsNotSinglePage() { + return (vm.pages.length > 1); + } + + function currentPage(index) { + return (index + 1); + } + + function IsLastPage(index) { + return (index == (vm.pages.length - 1)); + } + + function doPagination() { + vm.pages = []; + var membershippages = 0, packagepages = 0, treatmentpages = 0, inventorypages = 0; + if (rowCount > 15) { + var pageCount = Math.ceil(rowCount / 15); + var mtc = membershipTreatmentCount, ptc = packageTreatmentCount, tc = treatmentCount, ic = inventoryCount; + for (var i = 0; i < pageCount; i++) { + if (mtc > 15) { + var ms = 0, mst = 0; + Object.keys(membershipCount).forEach(iterateMemberships); + membershippages++; + pushPages(ms, 0, 0, 0); + mtc -= mst; + continue; + + function iterateMemberships(membership) { + mst += membershipCount[membership]; + if (mst < 15) { + ms++; + delete membershipCount[membership]; + } + } + } + var total = 0; + total = mtc + ptc; + if (total > 15) { + var ps = 0, ms = 0, pst = 0, mst = 0; + Object.keys(membershipCount).forEach(iterateMemberships); + Object.keys(packageCount).forEach(iteratePackages); + ptc = 15 - mtc; + packagepages++; + if (ms != 0) + membershippages++; + pushPages(ms, ps, 0, 0); + mtc = 0; + continue; + + function iterateMemberships(membership) { + mst += membershipCount[membership]; + if (mst < 15) { + ms++; + delete membershipCount[membership]; + } + } + + function iteratePackages(package) { + pst += packageCount[package]; + if (pst < 15) { + ps++; + delete packageCount[package]; + } + } + } + total = mtc + ptc + tc; + if (total > 15) { + var ps = 0, ms = 0, pst = 0, mst = 0; + Object.keys(membershipCount).forEach(iterateMemberships); + Object.keys(packageCount).forEach(iteratePackages); + tc = 15 - mtc - ptc; + if (ms != 0) + membershippages++; + if (ps != 0) + packagepages++; + treatmentpages++; + pushPages(ms, ps, tc, 0); + mtc = 0; + ptc = 0; + continue; + + function iterateMemberships(membership) { + mst += membershipCount[membership]; + if (mst < 15) { + ms++; + delete membershipCount[membership]; + } + } + + function iteratePackages(package) { + pst += packageCount[package]; + if (pst < 15) { + ps++; + delete packageCount[package]; + } + } + } + total = mtc + ptc + tc + ic; + if (total > 15) { + var ps = 0, ms = 0, pst = 0, mst = 0; + Object.keys(membershipCount).forEach(iterateMemberships); + Object.keys(packageCount).forEach(iteratePackages); + ic = 15 - mtc - ptc - tc; + if (ic == 0) + ic = 1; + if (ms != 0) + membershippages++; + if (ps != 0) + packagepages++; + if (tc != 0) + treatmentpages++; + inventorypages++; + pushPages(ms, ps, tc, ic); + mtc = 0; + ptc = 0; + tc = 0; + ic = inventoryCount - ic; + continue; + + function iterateMemberships(membership) { + mst += membershipCount[membership]; + if (mst < 15) { + ms++; + delete membershipCount[membership]; + } + } + + function iteratePackages(package) { + pst += packageCount[package]; + if (pst < 15) { + ps++; + delete packageCount[package]; + } + } + } + var ps = 0, ms = 0, pst = 0, mst = 0; + Object.keys(membershipCount).forEach(iterateMemberships); + Object.keys(packageCount).forEach(iteratePackages); + pushPages(ms, ps, tc, ic); + + function iterateMemberships(membership) { + mst += membershipCount[membership]; + if (mst < 15) { + ms++; + delete membershipCount[membership]; + } + } + + function iteratePackages(package) { + pst += packageCount[package]; + if (pst < 15) { + ps++; + delete packageCount[package]; + } + } + } + } else { + var ps = 0, ms = 0, pst = 0, mst = 0; + Object.keys(membershipCount).forEach(iterateMemberships); + Object.keys(packageCount).forEach(iteratePackages); + if (ms != 0) + membershippages++; + if (ps != 0) + packagepages++; + if (tc != 0) + treatmentpages++; + if (ic != 0) + inventorypages++; + + pushPages(ms, ps, treatmentCount, inventoryCount); + + function iterateMemberships(membership) { + mst += membershipCount[membership]; + if (mst < 15) { + ms++; + delete membershipCount[membership]; + } + } + + function iteratePackages(package) { + pst += packageCount[package]; + if (pst < 15) { + ps++; + delete packageCount[package]; + } + } + } + + function pushPages(pmtc, pptc, pagetc, pic) { + var index = vm.pages.length; + vm.pages.push({ + index: index, + membershippages: membershippages, + packagepages: packagepages, + treatmentpages: treatmentpages, + inventorypages: inventorypages, + membershipTreatmentCount: pmtc, + packageTreatmentCount: pptc, + treatmentCount: pagetc, + inventoryCount: pic + }); + } + } + + function IsHeaderAvailable() { + return ((vm.ivSettings && vm.ivSettings.display && vm.ivSettings.display.workshopDetails) || (vm.ivSettings && vm.ivSettings.display && vm.ivSettings.display.workshopLogo)); + } + + function getInvoicePageSize() { + amInvoices.getInvoicePageSize().then(success).catch(failure); + + function success(res) { + vm.invoicePageSize = res; + switch (res) { + case "A4": + A4Size(); + doPagination(); + break; + default: + normalPageSize(); + vm.pages.push({ + index: 0, + membershipTreatmentCount: membershipTreatmentCount, + packageTreatmentCount: packageTreatmentCount, + treatmentCount: treatmentCount, + inventoryCount: inventoryCount + }); + break; + } + } + + function failure(err) { + success(vm.invoicePageSizeList[1]); + } + } + + function normalPageSize() { + vm.pageWidth = "100%"; + vm.pageHeight = "auto"; + } + + function A4Size() { + vm.pageWidth = "210mm"; + vm.pageHeight = "297mm"; + } + + function IsTaxEnabled() { + var iTe = false; + vm.taxSettings.forEach(iterateTaxes); + return iTe; + + function iterateTaxes(tax) { + if (tax.isTaxApplied && (tax.tax > 0)) + iTe = true; + } + } + + function getCurrencySymbol() { + amInvoices.getCurrencySymbol().then(success).catch(failure); + + function success(res) { + vm.currencySymbol = res; + } + + function failure(err) { + vm.currencySymbol = "Rs."; + } + } + function IsSubtotalEnabled() { - return (vm.isDiscountApplied || vm.isRoundOff || (vm.sTaxSettings && vm.sTaxSettings.applyTax) || (vm.vatSettings && vm.vatSettings.applyTax)); + var isTaxEnabled = false; + vm.taxSettings.forEach(iterateTaxes); + return (vm.isDiscountApplied || vm.isRoundOffVal || isTaxEnabled); + + function iterateTaxes(tax) { + if (tax.isTaxApplied) + isTaxEnabled = true; + } } function calculateSubtotal() { @@ -128,7 +463,7 @@ } function failure(err) { - console.info('Cound not find margin settings'); + // do nothing } } @@ -171,17 +506,7 @@ function iterateInventories(inventory) { if (inventory.qty == undefined) inventory.qty = 1; - if (vm.vatSettings.applyTax) { - inventory.amount = inventory.rate; - if (vm.vatSettings.inclusive) { - inventory.rate = (inventory.amount * 100) / (vm.vatSettings.tax + 100); - inventory.tax = (inventory.rate * vm.vatSettings.tax / 100); - } else { - inventory.tax = (inventory.rate * vm.vatSettings.tax / 100); - inventory.amount = Math.round(inventory.rate + inventory.tax); - } - } - inventory.total = (inventory.rate * inventory.qty) + ((inventory.tax ? inventory.tax : 0) * inventory.qty); + inventory.total = inventory.rate * inventory.qty; inventory.total = (inventory.total % 1 != 0) ? inventory.total.toFixed(2) : parseInt(inventory.total); } } @@ -198,24 +523,59 @@ } function fillServiceDetails(res) { + rowCount = 0, membershipTreatmentCount = 0, packageTreatmentCount = 0, treatmentCount = 0, inventoryCount = 0; vm.user = res.user; oCustomerEmail = res.user.email; vm.vehicle = res.vehicle; vm.service = res.service; vm.isRoundOff = (vm.service.roundoff != undefined); vm.isDiscountApplied = (vm.service.discount != undefined); - vm.sTaxSettings = { - applyTax: res.service.serviceTax.applyTax, - inclusive: (res.service.serviceTax.taxIncType == 'inclusive'), - tax: res.service.serviceTax.tax - }; - vm.vatSettings = { - applyTax: res.service.vat.applyTax, - inclusive: (res.service.vat.taxIncType == 'inclusive'), - tax: res.service.vat.tax - } + if (vm.isDiscountApplied) + vm.discountValue = (vm.service.discount.amount || vm.service.discount.total); + if (res.service.taxes) + Object.keys(res.service.taxes).forEach(iterateTaxes); calculateInventoryValues(); + if (vm.service.memberships) + Object.keys(vm.service.memberships).forEach(iterateMemberships); + if (vm.service.packages) + Object.keys(vm.service.packages).forEach(iteratePackages); + if (vm.service.problems) { + rowCount += vm.service.problems.length; + treatmentCount += vm.service.problems.length; + } + if (vm.service.inventories) { + rowCount += vm.service.inventories.length; + inventoryCount += vm.service.inventories.length; + } calculateSubtotal(); + + function iteratePackages(package) { + var tempp = vm.service.packages[package]; + packageCount[package] = Object.keys(tempp.treatments).length; + rowCount += Object.keys(tempp.treatments).length; + packageTreatmentCount += Object.keys(tempp.treatments).length; + } + + function iterateMemberships(membership) { + var tempm = vm.service.memberships[membership]; + membershipCount[membership] = Object.keys(tempm.treatments).length; + rowCount += Object.keys(tempm.treatments).length; + membershipTreatmentCount += Object.keys(tempm.treatments).length; + } + + function iterateTaxes(tax) { + var t = res.service.taxes[tax]; + + vm.taxSettings.push({ + tax: t.tax, + inclusive: (t.type == "inclusive"), + isTaxApplied: t.isTaxApplied, + isForTreatments: t.isForTreatments, + isForInventory: t.isForInventory, + percent: t.percent, + name: tax + }); + } } function failure(err) { @@ -276,12 +636,22 @@ function success(res) { vm.ivSettings = res; + if (!res.display) + return; if (res.display.workshopLogo) - addInvoiceWLogo(); + setTimeout(addInvoiceWLogo, 1000); + if (res.display.footerLogo) + setTimeout(addInvoiceFLogo, 1000); } function failure(err) { - console.warn(err); + vm.ivSettings = { + display: { + workshopLogo: false, + footerLogo: false, + workshopDetails: false + } + } $log.info('Could not load display settings!'); } } @@ -318,7 +688,7 @@ amInScTw.src = ic.toDataURL(); } } - var printObj = document.getElementById('am-invoice-body'); + var printObj = document.getElementById('am-invoice-mail-body'); ammPrint.doPrint(printObj.innerHTML); if (vm.workshop && vm.workshop.social && vm.workshop.social.enabled) { if (IsSocialFacebook()) { @@ -354,12 +724,12 @@ amInvoices.saveCustomerEmail($state.params.userId, vm.user.email).then(respond).catch(respond); function respond(res) { - console.info(res); + // do nothing } } function cancelMailInvoice() { - console.info('cancelled'); + // do nothing } } @@ -369,11 +739,6 @@ utils.showSimpleToast(vm.user.name + '\'s email has not been set. Email can not be sent!'); return; } - var t = document.getElementById('am-invoice-body'); - if (vm.alignmentMargins && vm.alignmentMargins.enabled) { - t.style.paddingTop = 0; - t.style.paddingBottom = 0; - } var amInScFb = document.getElementById('am-invoice-social-facebook'); var amInScIn = document.getElementById('am-invoice-social-instagram'); var amInScTw = document.getElementById('am-invoice-social-twitter'); @@ -395,6 +760,7 @@ } } removeInvoiceWLogo(); + removeInvoiceFogo(); var printObj = document.getElementById('am-invoice-mail-body'); utils.showSimpleToast('Sending Mail...'); ammMailApi.send(printObj.innerHTML, vm.user, (vm.workshop) ? vm.workshop.name : undefined, (vm.ivSettings) ? vm.ivSettings.emailsubject : undefined); @@ -414,10 +780,8 @@ } if (vm.ivSettings.display.workshopLogo) addInvoiceWLogo(); - if (vm.alignmentMargins && vm.alignmentMargins.enabled) { - t.style.paddingTop = vm.alignmentMargins.top + 'cm'; - t.style.paddingBottom = vm.alignmentMargins.bottom + 'cm'; - } + if (vm.ivSettings.display.footerLogo) + addInvoiceFLogo(); } function goBack() { @@ -431,8 +795,7 @@ case 'customers.edit.services': transitState = 'restricted.customers.edit'; transitParams = { - id: $state.params.userId, - openTab: 'services' + id: $state.params.userId } break; } @@ -441,20 +804,28 @@ } function addInvoiceWLogo() { - var elem = document.getElementById('am-invoice-w-logo-holder'); - if (elem.hasChildNodes()) - return; - var x = document.createElement("IMG"); - x.setAttribute("src", vm.invoiceWLogo); - x.setAttribute("width", "250"); - x.setAttribute("height", "125"); - elem.appendChild(x); + var elems = document.getElementsByName('am-invoice-w-logo-holder'); + elems.forEach(iterateElements); + + function iterateElements(elem) { + if (elem.hasChildNodes()) + return; + var x = document.createElement("IMG"); + x.setAttribute("src", vm.invoiceWLogo); + x.setAttribute("width", "250"); + x.setAttribute("height", "125"); + elem.appendChild(x); + } } function removeInvoiceWLogo() { - var elem = document.getElementById('am-invoice-w-logo-holder'); - while (elem.firstChild) { - elem.removeChild(elem.firstChild); + var elems = document.getElementsByName('am-invoice-w-logo-holder'); + elems.forEach(iterateElements); + + function iterateElements(elem) { + while (elem.firstChild) { + elem.removeChild(elem.firstChild); + } } } } diff --git a/src/app/components/invoices/invoices.factory.js b/src/app/components/invoices/invoices.factory.js index 1f92fb9c..53e33cd3 100644 --- a/src/app/components/invoices/invoices.factory.js +++ b/src/app/components/invoices/invoices.factory.js @@ -2,7 +2,7 @@ * Factory that handles database interactions between invoices database and controller * @author ndkcha * @since 0.5.0 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -11,30 +11,66 @@ angular.module('automintApp') .factory('amInvoices', InvoicesFactory); - InvoicesFactory.$inject = ['$q', '$amRoot', 'pdbCustomers', 'pdbConfig']; + InvoicesFactory.$inject = ['$q', '$rootScope', 'pdbMain']; - function InvoicesFactory($q, $amRoot, pdbCustomers, pdbConfig) { + function InvoicesFactory($q, $rootScope, pdbMain) { // initialize factory variable and function mappings var factory = { getServiceDetails: getServiceDetails, getWorkshopDetails: getWorkshopDetails, getIvSettings: getIvSettings, getIvAlignMargins: getIvAlignMargins, - saveCustomerEmail: saveCustomerEmail + saveCustomerEmail: saveCustomerEmail, + getCurrencySymbol: getCurrencySymbol, + getInvoicePageSize: getInvoicePageSize } return factory; // function definitions + function getInvoicePageSize() { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); + return tracker.promise; + + function getSettingsObject(res) { + if (res.settings && res.settings.invoices && res.settings.invoices.pageSize) + tracker.resolve(res.settings.invoices.pageSize); + else + failure('No PageSize Found!'); + } + + function failure(err) { + tracker.reject(err); + } + } + + function getCurrencySymbol() { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); + return tracker.promise; + + function getSettingsObject(res) { + if (res.currency) + tracker.resolve(res.currency); + else + failure('No Currency Symbol Found!'); + } + + function failure(err) { + tracker.reject(err); + } + } + function saveCustomerEmail(userId, email) { var tracker = $q.defer(); - pdbCustomers.get(userId).then(getUserObject).catch(failure); + pdbMain.get(userId).then(getUserObject).catch(failure); return tracker.promise; function getUserObject(res) { res.user.email = email; - pdbCustomers.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } function success(res) { @@ -48,13 +84,9 @@ function getIvAlignMargins() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(failure); - } - function getSettingsObject(res) { if (res.settings && res.settings.invoices && res.settings.invoices.margin) tracker.resolve(res.settings.invoices.margin); @@ -76,7 +108,7 @@ // get service details from database function getServiceDetails(userId, vehicleId, serviceId) { var tracker = $q.defer(); - pdbCustomers.get(userId).then(getUserObject).catch(failure); + pdbMain.get(userId).then(getUserObject).catch(failure); return tracker.promise; function getUserObject(res) { @@ -170,13 +202,9 @@ // get workshop details from database function getWorkshopDetails() { var tracker = $q.defer(); - $amRoot.isWorkshopId().then(getWorkshopDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.workshop).then(getWorkshopObject).catch(failure); return tracker.promise; - function getWorkshopDoc(res) { - pdbConfig.get($amRoot.docIds.workshop).then(getWorkshopObject).catch(failure); - } - function getWorkshopObject(res) { if (res.workshop) tracker.resolve(res.workshop); @@ -197,13 +225,9 @@ // get display configurations function getIvSettings() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(failure); - } - function getSettingsObject(res) { if (res.settings && res.settings.invoices) tracker.resolve(res.settings.invoices); diff --git a/src/app/components/invoices/invoices_view.html b/src/app/components/invoices/invoices_view.html index 25e1b5b0..7bdef89d 100644 --- a/src/app/components/invoices/invoices_view.html +++ b/src/app/components/invoices/invoices_view.html @@ -13,29 +13,28 @@ arrow_back - Back
email - Email + Email print - Print + Print sms - SMS + SMS edit - Edit Service + Edit Service
- -
-
+ +
+
@@ -51,19 +50,20 @@ .am-invoice-table td { font-size: small; - padding: 1rem; + padding: 12px; } .am-invoice-table .m-d { - padding: 1rem 1rem 0.3rem 1rem !important; + padding: 12px 12px 2px 12px !important; } .am-invoice-table .m-dt { - padding: 0.3rem 1rem 0.3rem 1rem !important; + padding: 2px 12px 2px 12px !important; font-size: 9pt; } + .am-invoice-table .m-dtl { - padding: 0.3rem 1rem 1rem 1rem !important; + padding: 2px 12px 12px 12px !important; font-size: 9pt; } @@ -74,7 +74,7 @@ .am-invoice-table .row td { border-top: 1px solid #ECEFF1; } - + .am-invoice-table .dark-line td { border-top: 2px solid #37474F; } @@ -82,17 +82,17 @@ .am-invoice-table .total td { border-top: 1px solid #ECEFF1; font-weight: 800; - padding: 0.5rem 1rem 1rem 1rem !important; + padding: 8px 12px 12px 12px !important; } - + .am-invoice-table .subt td { border-top: 1px solid #ECEFF1; - padding: 0.5rem 1rem 0.5rem 1rem !important; + padding: 8px 12px 8px 12px !important; } .am-invoice-table .tax td { border-top: 2px solid #37474F; - padding: 1rem 1rem 0.5rem 1rem !important; + padding: 12px 12px 8px 12px !important; } .am-invoice-link { @@ -107,7 +107,7 @@ } .am-invoice-w-area { - font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif; + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; width: 100%; } @@ -123,7 +123,7 @@ .am-invoice-w-area .parent .right { padding-right: 2rem; } - + a { text-decoration: none; color: #757575; @@ -133,15 +133,28 @@ display: table; transition: all 500ms ease; } - + a:hover { color: #424242; } + + .am-flex-box { + height: 100%; + display: flex; + flex-direction: column; + } + + @media print { + #am-actual-invoice-body { + page-break-after: always; + } + } - -
+ +
+
 
@@ -152,17 +165,17 @@

{{vm.workshop.name}}

{{vm.workshop.label_phone}} {{vm.workshop.phone}}
-
+
+
-
-
+
@@ -177,7 +190,7 @@

{{vm.workshop.name}}

- + @@ -189,7 +202,7 @@

{{vm.workshop.name}}

- + @@ -199,64 +212,58 @@

{{vm.workshop.name}}

- + - + - + - + - + - + - + - - - - - - - + - - + + - + - - + + - + - + - + - + - +
-

{{vm.user.name}}

- {{vm.vehicle.manuf + ' ' + vm.vehicle.model}}
{{vm.vehicle.reg}}
+

{{vm.user.name}}

+ {{vm.vehicle.manuf + ' ' + vm.vehicle.model}}
{{vm.vehicle.reg}}
Qty Amount
{{key}}  
{{package.name}} - {{treatment.name}} Rs. {{treatment.rate | number: (vm.sTaxSettings.applyTax) ? ((vm.sTaxSettings.inclusive) ? 2 : 0) : 0}}{{vm.currencySymbol}} {{treatment.rate}}
{{problem.details}} Rs. {{problem.rate | number: (vm.sTaxSettings.applyTax) ? ((vm.sTaxSettings.inclusive) ? 2 : 0) : 0}}{{vm.currencySymbol}} {{problem.rate}}
{{inventory.name}}Rs. {{inventory.rate | number: (vm.vatSettings.applyTax) ? ((vm.vatSettings.inclusive) ? 2 : 0) : 0}}{{vm.currencySymbol}} {{inventory.rate}} {{inventory.qty}}Rs. {{inventory.total}}{{vm.currencySymbol}} {{inventory.total}}
Sub TotalRs. {{vm.subtotal}}
Service Tax ({{vm.sTaxSettings.tax}}%) Rs. {{vm.calculateServiceTax()}}{{vm.currencySymbol}} {{vm.subtotal}}
VAT ({{vm.vatSettings.tax}}%)
Discount Rs. {{vm.calculateVat()}}{{vm.currencySymbol}} {{vm.discountValue}}
Discount ({{vm.service.discount.percent}}%)
{{tax.name}} ({{tax.percent}}%) Rs. {{vm.service.discount.amount}}{{vm.currencySymbol}} {{tax.tax}}
Round Off Rs. {{vm.service.roundoff}}{{vm.currencySymbol}} {{vm.service.roundoff}}
Total Rs. {{vm.service.cost | number: (vm.sTaxSettings.applyTax) ? ((vm.sTaxSettings.inclusive) ? 2 : 0) : 0}}{{vm.currencySymbol}} {{vm.service.cost}}
-
-
-
Follow Us:
+
+
+
Follow Us:
-
+
 
diff --git a/src/app/components/services/services-add.controller.js b/src/app/components/services/services-add.controller.js index 529d6b2a..6d1b1932 100644 --- a/src/app/components/services/services-add.controller.js +++ b/src/app/components/services/services-add.controller.js @@ -2,39 +2,35 @@ * Controller for Add Service module * @author ndkcha * @since 0.4.1 - * @version 0.6.5 + * @version 0.7.0 */ /// (function() { - angular.module('automintApp') - .controller('amCtrlSeCI', ServiceAddController) - .controller('amCtrlMeD', MembershipEditDialogController); + angular.module('automintApp').controller('amCtrlSeCI', ServiceAddController); - ServiceAddController.$inject = ['$scope', '$state', '$q', '$log', '$filter', '$timeout', '$mdEditDialog', '$mdDialog', '$mdSidenav', 'utils', 'amServices']; - MembershipEditDialogController.$inject = ['$mdDialog', '$filter', 'membership', 'treatments']; + ServiceAddController.$inject = ['$rootScope', '$scope', '$state', '$q', '$log', '$filter', '$timeout', '$mdEditDialog', '$mdDialog', '$mdSidenav', 'utils', 'amServices']; /* ====== NOTE ======= > Do not create new method named moment() since it is used by moment.js */ - function ServiceAddController($scope, $state, $q, $log, $filter, $timeout, $mdEditDialog, $mdDialog, $mdSidenav, utils, amServices) { + function ServiceAddController($rootScope, $scope, $state, $q, $log, $filter, $timeout, $mdEditDialog, $mdDialog, $mdSidenav, utils, amServices) { // initialize view model var vm = this; // temporary named assignments - var autofillVehicle = false, - flagGetUserBasedOnMobile = true, - olInvoiceNo = 1, - olJobCardNo = 1, - olEstimateNo = 1, - transitIds = undefined, - transitInterState = undefined, - forceStopCalCost = false, - serviceTcRo = 0, - serviceTcDc = 0; + var autofillVehicle = false; + var flagGetUserBasedOnMobile = true; + var olInvoiceNo = 1, olJobCardNo = 1, olEstimateNo = 1; + var transitIds = undefined, transitInterState = undefined; + var forceStopCalCost = false; + var serviceTcRo = 0, serviceTcDc = 0; + var treatmentTotal = 0, inventoryTotal = 0; + var dTreatmentTax, dInventoryTax, dTreatment, dInventory; + var taxSettingsSnap = [], lastServiceState; // vm assignments to keep track of UI related elements vm.vehicleTypeList = []; @@ -61,12 +57,17 @@ invoiceno: 1, jobcardno: 1, estimateno: 1, - problems: [] + problems: [], + taxes: { + inventory: 0, + treatments: 0 + }, + subtotal: 0 }; vm.problem = { details: '', rate: '', - tax: '', + tax: {}, amount: '' }; vm.servicestatus = true; @@ -80,14 +81,12 @@ vm.membershipChips = []; vm.serviceTypeList = ['Treatments', 'Package', 'Membership']; vm.roundedOffVal = 0; - vm.discountPercentage = 0; - vm.discountValue = 0; vm.inventories = []; vm.selectedInventories = []; vm.inventory = { name: '', rate: '', - tax: '', + tax: {}, qty: 1, amount: '', total: '' @@ -101,9 +100,16 @@ vm.label_invoice = 'Invoice'; vm.isNextDueService = false; vm.nextDueDate = new Date(); - vm.nextDueDate.setMonth(vm.nextDueDate.getMonth() + 3); vm.problemFocusIndex = -1; vm.inventoryFocusIndex = -1; + vm.discount = { + treatment: 0, + part: 0, + total: 0 + }; + vm.taxSettings = []; + vm.currencySymbol = "Rs."; + vm.areTaxesHidden = false; // named assignments to handle behaviour of UI elements vm.redirect = { @@ -132,24 +138,19 @@ vm.save = save; vm.queryMembershipChip = queryMembershipChip; vm.OnClickMembershipChip = OnClickMembershipChip; - vm.calculateCost = calculateCost; vm.OnAddMembershipChip = OnAddMembershipChip; vm.navigateToSubscribeMembership = navigateToSubscribeMembership; vm.goBack = goBack; vm.changeProblemRate = changeProblemRate; - vm.changeServiceTax = changeServiceTax; - vm.OnServiceTaxEnabledChange = OnServiceTaxEnabledChange; + vm.OnTaxEnabledChange = OnTaxEnabledChange; vm.convertPbToTitleCase = convertPbToTitleCase; - vm.calculateTax = calculateTax; vm.convertInToTitleCase = convertInToTitleCase; - vm.changeVat = changeVat; vm.onInventorySelected = onInventorySelected; vm.onInventoryDeselected = onInventoryDeselected; vm.changeInventoryRate = changeInventoryRate; vm.inventoryQuerySearch = inventoryQuerySearch; vm.updateInventoryDetails = updateInventoryDetails; vm.finalizeNewInventory = finalizeNewInventory; - vm.calculateVat = calculateVat; vm.changeQty = changeQty; vm.changeInventoryTotal = changeInventoryTotal; vm.populateRoD = populateRoD; @@ -169,14 +170,8 @@ vm.IsMembershipEnabled = IsMembershipEnabled; vm.IsPackageEnabled = IsPackageEnabled; vm.convertVehicleTypeToAF = convertVehicleTypeToAF; - vm.IsTreatmentAmountEditable = IsTreatmentAmountEditable; - vm.IsTreatmentAmountText = IsTreatmentAmountText; - vm.IsPackageEnabled = IsPackageEnabled; vm.changeDisplayAsList = changeDisplayAsList; - vm.IsTreatmentRateDisplayed = IsTreatmentRateDisplayed; vm.changeInventoryAsList = changeInventoryAsList; - vm.IsInventoryTotalEditable = IsInventoryTotalEditable; - vm.IsInventoryTotalText = IsInventoryTotalText; vm.IsServiceStateSelected = IsServiceStateSelected; vm.selectServiceState = selectServiceState; vm.WhichServiceStateEnabled = WhichServiceStateEnabled; @@ -194,13 +189,31 @@ vm.getDate = getDate; vm.IsProblemFocusIndex = IsProblemFocusIndex; vm.IsInventoryFocusIndex = IsInventoryFocusIndex; + vm.openPartialPaymentBox = openPartialPaymentBox; + vm.calculateDue = calculateDue; + vm.IsPartialPayment = IsPartialPayment; + vm.changeServiceStatus = changeServiceStatus; + vm.openDiscountBox = openDiscountBox; + vm.OnDiscountStateChange = OnDiscountStateChange; + vm.findVehicleByReg = findVehicleByReg; + vm.IsCustomerNotAnonymus = IsCustomerNotAnonymus; + vm.goToDashboard = goToDashboard; + vm.IsCustomerSelected = IsCustomerSelected; + vm.openCustomerProfile = openCustomerProfile; + vm.openTd = openTd; + vm.openId = openId; + + // watchers + $(window).on('resize', OnWindowResize); // default execution steps + setCoverPic(); changeUserInfoState(true); // ammToDo: Enable this while commiting setTimeout(focusUserName, 700); // changeServiceInfoState(true); // ammToDo: Testing Purpose, Disable while commiting buildDelayedToggler('service-details-left'); + getCurrencySymbol(); getDefaultServiceType(); getTreatmentDisplayFormat(); getInventoriesSettings(); @@ -212,11 +225,306 @@ getLastEstimateNo(); getLastJobCardNo(); - // watchers - $(window).on('resize', OnWindowResize); - // function definitions + function openId(event, inventory) { + $mdDialog.show({ + controller: 'amCtrlSeId', + controllerAs: 'vm', + templateUrl: 'app/components/services/tmpl2/dialog-id.html', + parent: angular.element(document.body), + targetEvent: event, + locals: { + inventory: inventory + }, + clickOutsideToClose: true + }).then(success).catch(success); + + function success(res) { + // do nothing + } + } + + function openTd(event, problem) { + $mdDialog.show({ + controller: 'amCtrlSeTd', + controllerAs: 'vm', + templateUrl: 'app/components/services/tmpl2/dialog-td.html', + parent: angular.element(document.body), + targetEvent: event, + locals: { + problem: problem + }, + clickOutsideToClose: true + }).then(success).catch(success); + + function success(res) { + if (!res) + return; + problem.orgcost = res.orgcost; + } + } + + function openCustomerProfile() { + $state.go('restricted.customers.edit', { + id: vm.user.id + }); + } + + function IsCustomerSelected() { + if (vm.user.id == undefined) + return false; + return (vm.user.id != ''); + } + + function goToDashboard() { + if ($state.params.fromState == 'locked') + $rootScope.isAutomintLocked = true; + $mdSidenav('main-nav-left').close() + $state.go('restricted.dashboard'); + } + + function IsCustomerNotAnonymus() { + return (vm.user.name != 'Anonymous'); + } + + function findVehicleByReg() { + var vfound = $filter('filter')(vm.possibleVehicleList, { + reg: vm.vehicle.reg + }, true); + + if (vfound.length == 1) { + changeVehicle(vfound[0].id); + } + } + + function getCurrencySymbol() { + amServices.getCurrencySymbol().then(success).catch(failure); + + function success(res) { + vm.currencySymbol = res; + } + + function failure(err) { + vm.currencySymbol = "Rs."; + } + } + + function calculate() { + calculateSubtotal(); + calculateTotalDiscount(); + calculateTaxes(); + calculateCost(); + } + + function calculateTaxes() { + vm.taxSettings.forEach(iterateTaxes); + vm.service.problems.forEach(iterateProblems); + if (vm.problem.details != '') + iterateProblem(vm.problem); + if (vm.packages) + vm.packages.forEach(iteratePackages); + vm.selectedInventories.forEach(iterateInventories); + if (vm.inventory.name != '') + iterateInventory(vm.inventory); + if (vm.isDiscountApplied && (parseFloat(vm.discount.total) > 0)) { + vm.taxSettings.forEach(iterateTaxes); + vm.taxSettings.forEach(iterateTaxesAfter); + } + + function iterateTaxesAfter(tax) { + if (tax.isTaxApplied && tax.isForTreatments) + tax.tax += (dTreatment * tax.percent / 100); + if (tax.isTaxApplied && tax.isForInventory) + tax.tax += (dInventory * tax.percent / 100); + tax.tax = (tax.tax % 1 != 0) ? parseFloat(tax.tax.toFixed(2)) : parseInt(tax.tax); + } + + function iterateTaxes(tax) { + tax.tax = 0; + } + + function iteratePackages(package) { + if (!package.checked) + return; + package.selectedTreatments.forEach(iterateProblems); + } + + function iterateInventories(inventory) { + if (!inventory.checked) + return; + if (inventory.tax) { + Object.keys(inventory.tax).forEach(iterateTaxes); + + function iterateTaxes(tax) { + var found = $filter('filter')(vm.taxSettings, { + name: tax + }, true); + + if (found.length == 1) { + if (!found[0].isTaxApplied) + return; + if (!found[0].tax) + found[0].tax = 0; + found[0].tax += (inventory.tax[tax] * (inventory.qty ? inventory.qty : 1)); + found[0].tax = (found[0].tax % 1 != 0) ? parseFloat(found[0].tax.toFixed(2)) : parseInt(found[0].tax); + } + } + } + } + + function iterateProblems(problem) { + if (!problem.checked) + return; + if (problem.tax) { + Object.keys(problem.tax).forEach(iterateTaxes); + + function iterateTaxes(tax) { + var found = $filter('filter')(vm.taxSettings, { + name: tax + }, true); + + if (found.length == 1) { + if (!found[0].isTaxApplied) + return; + if (!found[0].tax) + found[0].tax = 0; + found[0].tax += problem.tax[tax]; + found[0].tax = (found[0].tax % 1 != 0) ? parseFloat(found[0].tax.toFixed(2)) : parseInt(found[0].tax); + } + } + } + } + + function iterateProblem(problem) { + if (problem.tax) { + Object.keys(problem.tax).forEach(iterateTaxes); + + function iterateTaxes(tax) { + if (problem.tax[tax] > 0) { + var found = $filter('filter')(vm.taxSettings, { + name: tax + }, true); + + if (found.length == 1) { + if (!found[0].isTaxApplied) + return; + if (!found[0].tax) + found[0].tax = 0; + found[0].tax += problem.tax[tax]; + found[0].tax = (found[0].tax % 1 != 0) ? parseFloat(found[0].tax.toFixed(2)) : parseInt(found[0].tax); + } + } + } + } + } + + function iterateInventory(inventory) { + if (inventory.tax) { + Object.keys(inventory.tax).forEach(iterateTaxes); + + function iterateTaxes(tax) { + if (inventory.tax[tax] > 0) { + var found = $filter('filter')(vm.taxSettings, { + name: tax + }, true); + + if (found.length == 1) { + if (!found[0].isTaxApplied) + return; + if (!found[0].tax) + found[0].tax = 0; + found[0].tax += (inventory.tax[tax] * (inventory.qty ? inventory.qty : 1)); + found[0].tax = (found[0].tax % 1 != 0) ? parseFloat(found[0].tax.toFixed(2)) : parseInt(found[0].tax); + } + } + } + } + } + } + + function OnDiscountStateChange() { + calculateDiscount(); + calculate(); + } + + function openDiscountBox() { + $mdDialog.show({ + controller: 'amCtrlSeDc', + controllerAs: 'vm', + templateUrl: 'app/components/services/tmpl/dialog_discount.html', + parent: angular.element(document.body), + targetEvent: event, + locals: { + currencySymbol: vm.currencySymbol, + treatmentLength: (vm.selectedProblems.length ? vm.selectedProblems.length : 0) + ((parseFloat(vm.problem.amount) > 0) ? 1 : 0), + partLength: (vm.selectedInventories.length ? vm.selectedInventories.length : 0) + ((parseFloat(vm.inventory.amount) > 0) ? 1 : 0), + discountObj: vm.discount, + partTotal: inventoryTotal, + treatmentTotal: treatmentTotal + }, + clickOutsideToClose: true + }).then(success).catch(success); + + function success(res) { + if (!res) + return; + vm.discount.treatment = res.treatment; + vm.discount.part = res.part; + vm.discount.total = res.total; + calculate(); + } + } + + function changeServiceStatus() { + if (vm.servicestatus) { + if (vm.service.partialpayment) { + if ((vm.service.partialpayment.total - vm.service.cost) != 0) { + vm.service.partialpayment[moment().format()] = vm.service.cost - vm.service.partialpayment.total; + vm.service.partialpayment.total = vm.service.cost; + } + } + } else { + vm.service.partialpayment = { + total: 0 + } + } + } + + function IsPartialPayment() { + return (vm.service.partialpayment && !vm.servicestatus); + } + + function calculateDue() { + return (vm.service.cost - vm.service.partialpayment.total); + } + + function openPartialPaymentBox() { + $mdDialog.show({ + controller: 'amCtrlSePp', + controllerAs: 'vm', + templateUrl: 'app/components/services/tmpl/dialog_partialpayment.html', + parent: angular.element(document.body), + targetEvent: event, + locals: { + currencySymbol: vm.currencySymbol, + totalCost: vm.service.cost, + partialPayments: vm.service.partialpayment + }, + clickOutsideToClose: true + }).then(success).catch(success); + + function success(res) { + if (!res) { + vm.servicestatus = vm.service.partialpayment ? ((vm.service.partialpayment.total - vm.service.cost) == 0) : true; + return; + } + if (res.total) + vm.servicestatus = ((parseFloat(res.total) - parseFloat(vm.service.cost)) == 0); + vm.service.partialpayment = res; + } + } + function IsInventoryFocusIndex(index) { return (vm.inventoryFocusIndex == index); } @@ -257,7 +565,14 @@ } function IsSubtotalEnabled() { - return (vm.isDiscountApplied || vm.isRoundOffVal || (vm.sTaxSettings && vm.sTaxSettings.applyTax) || (vm.vatSettings && vm.vatSettings.applyTax)); + var isTaxEnabled = false; + vm.taxSettings.forEach(iterateTaxes); + return (vm.isDiscountApplied || vm.isRoundOffVal || isTaxEnabled); + + function iterateTaxes(tax) { + if (tax.isTaxApplied) + isTaxEnabled = true; + } } function isRoD() { @@ -272,22 +587,29 @@ function calculateSubtotal() { var totalCost = 0; + treatmentTotal = 0, inventoryTotal = 0; vm.service.problems.forEach(iterateProblem); - iterateProblem(vm.problem); + if (vm.problem.details != '') + totalCost += (vm.problem.rate) ? parseFloat(vm.problem.rate) : 0; vm.selectedInventories.forEach(iterateInventories); - iterateInventories(vm.inventory); - if (vm.serviceType == vm.serviceTypeList[1]) { + if (vm.inventory.name != '') + totalCost += (vm.inventory.rate) ? (parseFloat(vm.inventory.rate) * parseFloat(vm.inventory.qty)) : 0; + if (vm.packages) { vm.packages.forEach(iteratePackages); } totalCost = (totalCost % 1 != 0) ? totalCost.toFixed(2) : parseInt(totalCost); - return totalCost; + vm.service.subtotal = parseFloat(totalCost); function iterateProblem(element) { - totalCost += parseFloat(element.rate ? (element.rate * (element.checked ? 1 : 0)) : 0); + var temp = parseFloat(element.rate ? (element.rate * (element.checked ? 1 : 0)) : 0); + totalCost += temp; + treatmentTotal += temp; } function iterateInventories(element) { - totalCost += parseFloat(element.rate ? ((element.rate * element.qty) * (element.checked ? 1 : 0)) : 0); + var temp = parseFloat(element.rate ? ((element.rate * element.qty) * (element.checked ? 1 : 0)) : 0); + totalCost += temp; + inventoryTotal += temp; } function iteratePackages(package) { @@ -297,7 +619,9 @@ } function ipt(treatment) { - totalCost += treatment.rate[vm.vehicle.type.toLowerCase().replace(' ', '-')]; + var temp = treatment.amount[convertVehicleTypeToAF()]; + totalCost += temp; + treatmentTotal += temp; } } @@ -334,6 +658,29 @@ function selectServiceState(state) { vm.service.state = state; vm.label_invoice = (vm.service.state == vm.serviceStateList[2]) ? 'Invoice' : 'Send'; + if (vm.service.state != vm.serviceStateList[2]) { + vm.areTaxesHidden = true; + if ((lastServiceState == vm.serviceStateList[2]) || !lastServiceState) { + taxSettingsSnap = []; + vm.taxSettings.forEach(iterateTaxes); + } + } else { + vm.areTaxesHidden = false; + vm.taxSettings = []; + taxSettingsSnap.forEach(restoreTaxes); + } + lastServiceState = vm.service.state; + OnTaxEnabledChange(); + + function restoreTaxes(tax) { + vm.taxSettings.push(tax); + } + + function iterateTaxes(tax) { + var t = $.extend({}, tax) + taxSettingsSnap.push(t); + tax.isTaxApplied = false; + } } function IsServiceStateSelected(state) { @@ -348,48 +695,25 @@ $('#ami-display-as').focus(); } - function IsInventoryTotalText() { - return (vm.vatSettings && !vm.vatSettings.inclusive && vm.vatSettings.applyTax); - } - - function IsInventoryTotalEditable() { - return (vm.vatSettings && (vm.vatSettings.inclusive || !vm.vatSettings.applyTax)); - } - function changeInventoryAsList(bool) { vm.displayInventoriesAsList = bool; setTimeout(focusShowAllInventoriesButton, 300); } - function IsTreatmentRateDisplayed() { - return (vm.sTaxSettings && vm.sTaxSettings.applyTax && !vm.sTaxSettings.inclusive); - } - function changeDisplayAsList(bool) { vm.displayTreatmentAsList = bool; setTimeout(focusShowAllTreatmentsButton, 300); } function IsPackageEnabled() { - return (vm.packages.length < 1); - } - - function IsTreatmentAmountText() { - return (vm.sTaxSettings && !vm.sTaxSettings.inclusive && vm.sTaxSettings.applyTax); - } - - function IsTreatmentAmountEditable() { - return (vm.sTaxSettings && (vm.sTaxSettings.inclusive || !vm.sTaxSettings.applyTax)); + return false; + // return (vm.packages && (vm.packages.length > 0)); } function convertVehicleTypeToAF() { return (vm.vehicle.type.toLowerCase().replace(' ', '-')); } - function IsPackageEnabled() { - return (vm.serviceType == vm.serviceTypeList[1]); - } - function IsMembershipEnabled() { return (vm.serviceType == vm.serviceTypeList[2]); } @@ -514,7 +838,7 @@ $mdDialog.show(confirm).then(performDelete, ignoreDelete); function performDelete() { - console.info('deleted'); + // do nothing } function ignoreDelete() { @@ -527,20 +851,6 @@ changeInventoryRate(inventory); } - function calculateVat() { - var totalTax = 0.0; - vm.selectedInventories.forEach(iterateInventories); - iterateInventories(vm.inventory); - totalTax = (totalTax % 1 != 0) ? totalTax.toFixed(2) : totalTax; - return totalTax; - - function iterateInventories(element) { - if ((vm.vatSettings && !vm.vatSettings.applyTax) || !element.tax || !element.checked) - return; - totalTax += parseFloat(element.tax * element.qty); - } - } - function getInventoriesSettings() { amServices.getInventoriesSettings().then(success).catch(failure); @@ -555,12 +865,16 @@ function finalizeNewInventory(isFromAutocomplete) { vm.inventory.name = vm.inventory.name.trim(); + vm.inventoryFocusIndex = -1; if (vm.inventory.name != '') { if (isFromAutocomplete) updateInventoryDetails(); var found = $filter('filter')(vm.inventories, { name: vm.inventory.name }, true); + var foundExisting = $filter('filter')(vm.selectedInventories, { + name: vm.inventory.name + }, true); if (found.length == 1) { found[0].checked = true; found[0].rate = vm.inventory.rate; @@ -568,7 +882,10 @@ found[0].qty = vm.inventory.qty; found[0].amount = vm.inventory.amount; found[0].total = vm.inventory.total; - vm.selectedInventories.push(found[0]); + if (foundExisting.length == 0) + vm.selectedInventories.push(found[0]); + else + foundExisting[0] = found[0]; } else { vm.inventories.push({ name: vm.inventory.name, @@ -584,12 +901,12 @@ vm.inventory.name = ''; vm.inventory.amount = ''; vm.inventory.rate = ''; - vm.inventory.tax = ''; + vm.inventory.tax = {}; vm.inventory.qty = 1; vm.inventory.total = ''; - calculateCost(); - if (isFromAutocomplete) - vm.inventoryFocusIndex = vm.selectedInventories.length - 1; + calculate(); + if (isFromAutocomplete || foundExisting.length != 0) + vm.inventoryFocusIndex = (foundExisting.length == 0) ? vm.selectedInventories.length - 1 : vm.selectedInventories.indexOf(foundExisting[0]); else setTimeout(focusNewInventoryName, 300); } @@ -605,37 +922,36 @@ name: vm.inventory.name }, true); if (found.length == 1) { - var rate; - if (vm.vatSettings.applyTax) - rate = (vm.vatSettings.inclusive) ? found[0].amount : found[0].rate; - else - rate = found[0].rate; - vm.inventory.amount = (rate == '' || rate == undefined ? vm.inventory.amount : rate); - if (vm.vatSettings.applyTax) { - if (vm.vatSettings.inclusive) { - vm.inventory.rate = (vm.inventory.amount * 100) / (vm.vatSettings.tax + 100); - vm.inventory.tax = (vm.inventory.rate * vm.vatSettings.tax / 100); - } else { - vm.inventory.rate = (rate == '' || rate == undefined ? vm.inventory.rate : rate); - vm.inventory.tax = (vm.inventory.rate * vm.vatSettings.tax / 100); - vm.inventory.amount = Math.round(vm.inventory.rate + vm.inventory.tax); - } - } else { - if (vm.vatSettings.inclusive) - vm.inventory.rate = (rate == '' || rate == undefined ? vm.inventory.rate : rate); - else { - vm.inventory.amount = (rate == '' || rate == undefined ? vm.inventory.amount : rate); - vm.inventory.rate = (rate == '' || rate == undefined ? vm.inventory.rate : rate); - } - } + var taxable = vm.inventory.amount; + vm.inventory.tax = {}; + vm.taxSettings.forEach(iterateTaxes); + vm.inventory.rate = taxable; vm.inventory.total = vm.inventory.amount * vm.inventory.qty; vm.inventory.checked = true; - calculateCost(); + calculate(); + + function iterateTaxes(tax) { + if (!tax.isForInventory) + return; + if (tax.isTaxApplied) { + if (tax.inclusive) { + var temptax = 0; + vm.inventory.rate = (taxable * 100) / (tax.percent + 100); + temptax = (vm.inventory.rate * tax.percent / 100); + vm.inventory.tax[tax.name] = temptax; + taxable = vm.inventory.rate; + } else { + var temptax = 0; + temptax = (taxable * tax.percent / 100); + vm.inventory.tax[tax.name] = temptax; + } + } + } } } else { vm.inventory.checked = false; vm.inventory.rate = ''; - vm.inventory.tax = 0; + vm.inventory.tax = {}; vm.inventory.amount = ''; vm.inventory.total = ''; } @@ -670,26 +986,35 @@ function success(res) { vm.inventories = res; - getVatSettings(); + getInventoryTax(); } function failure(err) { vm.inventories = []; - getVatSettings(); + getInventoryTax(); } } - function getVatSettings() { - amServices.getVatSettings().then(success).catch(failure); + function getInventoryTax() { + amServices.getInventoryTax().then(success).catch(failure); function success(res) { - vm.vatSettings = res; - vm.orgApplyVat = res.applyTax; - changeVat(); + res.forEach(iterateTaxes); + OnTaxEnabledChange(); + + function iterateTaxes(tax) { + tax.tax = 0; + var found = $filter('filter')(vm.taxSettings, { + name: tax.name + }, true); + + if (found.length == 0) + vm.taxSettings.push(tax); + } } function failure(err) { - vm.vatSettings = {}; + // do nothing } } @@ -697,62 +1022,52 @@ vm.inventory.name = utils.autoCapitalizeWord(vm.inventory.name); } - function changeVat() { - vm.inventories.forEach(iterateInventories); - changeInventoryRate(vm.inventory, true); - - function iterateInventories(inventory) { - changeInventoryRate(inventory, true); - } - } - function changeQty(inventory) { - inventory.total = ((vm.vatSettings.applyTax ? inventory.amount : inventory.rate) * inventory.qty); - calculateCost(); - - if (!vm.vatSettings.applyTax) - inventory.amount = inventory.rate; + inventory.total = (inventory.amount * inventory.qty); + calculate(); } function changeInventoryRate(inventory, force) { - if (vm.vatSettings.applyTax) { - if (vm.vatSettings.inclusive) { - inventory.rate = (inventory.amount * 100) / (vm.vatSettings.tax + 100); - inventory.tax = (inventory.rate * vm.vatSettings.tax / 100); - } else { - if (!inventory.rate) - inventory.rate = inventory.amount; - inventory.tax = (inventory.rate * vm.vatSettings.tax / 100); - inventory.amount = inventory.rate + inventory.tax; - } - } else if (force) { - if (vm.vatSettings.inclusive) - inventory.rate = inventory.amount; - else - inventory.amount = inventory.rate; - } else - inventory.rate = inventory.amount; + var taxable = inventory.amount; + inventory.tax = {}; + vm.taxSettings.forEach(iterateTaxes); + inventory.rate = taxable; changeQty(inventory); - calculateCost(); + calculate(); + + function iterateTaxes(tax) { + if (!tax.isForInventory) + return; + if (tax.isTaxApplied) { + if (tax.inclusive) { + var temptax = 0; + inventory.rate = (taxable * 100) / (tax.percent + 100); + temptax = (inventory.rate * tax.percent / 100); + inventory.tax[tax.name] = temptax; + taxable = inventory.rate; + } else { + var temptax = 0; + temptax = (taxable * tax.percent / 100); + inventory.tax[tax.name] = temptax; + } + } + } } function convertPbToTitleCase() { vm.problem.details = utils.autoCapitalizeWord(vm.problem.details); } - function OnServiceTaxEnabledChange() { + function OnTaxEnabledChange() { vm.service.problems.forEach(iterateProblems); + changeProblemRate(vm.problem, true); calculatePackageTax(); + vm.inventories.forEach(iterateInventories); + changeInventoryRate(vm.inventory, true); - function iterateProblems(problem) { - changeProblemRate(problem, true); + function iterateInventories(inventory) { + changeInventoryRate(inventory, true); } - } - - function changeServiceTax() { - vm.service.problems.forEach(iterateProblems); - changeProblemRate(vm.problem, true); - calculatePackageTax(); function iterateProblems(problem) { changeProblemRate(problem, true); @@ -760,39 +1075,51 @@ } function changeProblemRate(problem, force) { - if (vm.sTaxSettings.applyTax) { - if (vm.sTaxSettings.inclusive) { - problem.rate = (problem.amount * 100) / (vm.sTaxSettings.tax + 100); - problem.tax = (problem.rate * vm.sTaxSettings.tax / 100); - } else { - if (!problem.rate) - problem.rate = problem.amount; - problem.tax = (problem.rate * vm.sTaxSettings.tax / 100); - problem.amount = problem.rate + problem.tax; + var taxable = problem.amount; + problem.tax = {}; + vm.taxSettings.forEach(iterateTaxes); + problem.rate = parseFloat(taxable); + calculate(); + + function iterateTaxes(tax) { + if (!tax.isForTreatments) + return; + if (tax.isTaxApplied) { + if (tax.inclusive) { + var temptax = 0; + problem.rate = (taxable * 100) / (tax.percent + 100); + temptax = (problem.rate * tax.percent / 100); + problem.tax[tax.name] = temptax; + taxable = problem.rate; + } else { + var temptax = 0; + temptax = (taxable * tax.percent / 100); + problem.tax[tax.name] = temptax; + } } - } else if (force) { - if (vm.sTaxSettings.inclusive) - problem.rate = problem.amount; - else - problem.amount = problem.rate; - } else - problem.rate = problem.amount; - calculateCost(); + } } - function getServiceTaxSettings() { - amServices.getServiceTaxSettings().then(success).catch(failure); + function getTreatmentsTax() { + amServices.getTreatmentsTax().then(success).catch(failure); function success(res) { - vm.sTaxSettings = res; - vm.orgApplyTax = res.applyTax; - changeServiceTax(); + res.forEach(iterateTaxes); getPackages(); - OnServiceTaxEnabledChange(); + OnTaxEnabledChange(); + + function iterateTaxes(tax) { + tax.tax = 0; + var found = $filter('filter')(vm.taxSettings, { + name: tax.name + }, true); + + if (found.length == 0) + vm.taxSettings.push(tax); + } } function failure(err) { - vm.sTaxSettings = {}; getPackages(); } } @@ -815,7 +1142,7 @@ } break; case 'locked': - transitState = 'locked'; + $rootScope.isAutomintLocked = true; break; } } @@ -839,7 +1166,7 @@ $mdDialog.show({ controller: 'amCtrlMeD', controllerAs: 'vm', - templateUrl: 'app/components/services/service_membership.edit-template.html', + templateUrl: 'app/components/services/tmpl/dialog_membership.edit-template.html', parent: angular.element(document.body), targetEvent: event, locals: { @@ -1061,7 +1388,7 @@ var total = 0; package.selectedTreatments.forEach(it); package.total = total; - calculateCost(); + calculate(); return total; function it(t) { @@ -1069,23 +1396,29 @@ } } - function changeTreatmentTax(treatment, force) { + function changeTreatmentTax(problem, force) { var cvt = vm.vehicle.type.toLowerCase().replace(' ', '-'); - if (vm.sTaxSettings.applyTax) { - if (treatment.tax == undefined) - treatment.tax = {}; - if (vm.sTaxSettings.inclusive) { - treatment.rate[cvt] = (treatment.amount[cvt] * 100) / (vm.sTaxSettings.tax + 100); - treatment.tax[cvt] = (treatment.rate[cvt] * vm.sTaxSettings.tax / 100); - } else { - treatment.tax[cvt] = (treatment.rate[cvt] * vm.sTaxSettings.tax / 100); - treatment.amount[cvt] = treatment.rate[cvt] + treatment.tax[cvt]; + var taxable = problem.amount[cvt]; + problem.tax = {}; + vm.taxSettings.forEach(iterateTaxes); + problem.rate[cvt] = parseFloat(taxable); + + function iterateTaxes(tax) { + if (!tax.isForTreatments) + return; + if (tax.isTaxApplied) { + if (tax.inclusive) { + var temptax = 0; + problem.rate[cvt] = (taxable * 100) / (tax.percent + 100); + temptax = (problem.rate[cvt] * tax.percent / 100); + problem.tax[tax.name] = temptax; + taxable = problem.rate[cvt]; + } else { + var temptax = 0; + temptax = (taxable * tax.percent / 100); + problem.tax[tax.name] = temptax; + } } - } else if (force) { - if (vm.sTaxSettings.inclusive) - treatment.rate[cvt] = treatment.amount[cvt]; - else - treatment.amount[cvt] = treatment.rate[cvt]; } } @@ -1182,7 +1515,6 @@ } function failure(err) { - console.log(err); setDefaultVehicle(); } } @@ -1281,8 +1613,6 @@ vm.user.name = res.name; vm.user.address = (res.address == undefined) ? '' : res.address; if (res.memberships) { - if (Object.keys(res.memberships).length > 0) - vm.serviceType = vm.serviceTypeList[2]; Object.keys(res.memberships).forEach(iterateMemberships); } vm.possibleVehicleList = res.possibleVehicleList; @@ -1345,7 +1675,6 @@ } vm.isNextDueService = false; vm.nextDueDate = new Date(); - vm.nextDueDate.setMonth(vm.nextDueDate.getMonth() + 3); autofillVehicle = false; } @@ -1432,39 +1761,61 @@ // vehicle manufacturer is updated from UI, clear model list to populate new list w.r.t. manufacturer function searchVehicleChange() { autoCapitalizeVehicleManuf(); - if (!autofillVehicle) { - vm.models = []; - vm.vehicle.model = ''; + if (autofillVehicle) { autofillVehicle = false; + return; } + vm.currentVehicle = 'New Vehicle'; + vm.vehicle.id = undefined; + vm.vehicle.model = ''; + vm.vehicle.reg = ''; + vm.models = []; + if (vm.vehicleTypeList.length > 0) { + vm.vehicle.type = vm.vehicleTypeList[0]; + changeVehicleType(); + } + vm.isNextDueService = false; + vm.nextDueDate = new Date(); } // replace all the treatment values with updated vehicle type function changeVehicleType() { + if (vm.vehicleTypeList.length < 1) + return; vm.service.problems.forEach(iterateProblem); iterateProblem(vm.problem); calculatePackageTax(); - calculateCost(); + calculate(); function iterateProblem(problem) { var found = $filter('filter')(vm.treatments, { name: problem.details }); if (found.length == 1) { - var rate = found[0].rate[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')]; - if (vm.sTaxSettings.applyTax) { - if (vm.sTaxSettings.inclusive) { - problem.amount = (rate == '' || rate == undefined ? problem.amount : rate); - problem.rate = (problem.amount * 100) / (vm.sTaxSettings.tax + 100); - problem.tax = (problem.rate * vm.sTaxSettings.tax / 100); - } else { - problem.rate = (rate == '' || rate == undefined ? problem.rate : rate); - problem.tax = (problem.rate * vm.sTaxSettings.tax / 100); - problem.amount = problem.rate + problem.tax; + problem.amount = found[0].rate[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')]; + var taxable = problem.amount; + problem.tax = {}; + vm.taxSettings.forEach(iterateTaxes); + problem.rate = parseFloat(taxable); + if (found[0].orgcost && found[0].orgcost[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')]) + problem.orgcost = found[0].orgcost[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')]; + + function iterateTaxes(tax) { + if (!tax.isForTreatments) + return; + if (tax.isTaxApplied) { + if (tax.inclusive) { + var temptax = 0; + problem.rate = (taxable * 100) / (tax.percent + 100); + temptax = (problem.rate * tax.percent / 100); + problem.tax[tax.name] = temptax; + taxable = problem.rate; + } else { + var temptax = 0; + temptax = (taxable * tax.percent / 100); + problem.tax[tax.name] = temptax; + } } - } else { - problem.rate = (rate == '' || rate == undefined ? problem.rate : rate); - problem.amount = (rate == '' || rate == undefined ? problem.rate : rate); } } } @@ -1494,15 +1845,18 @@ // load treatment list into problem list function loadTreatmentIntoProblems() { vm.treatments.forEach(iterateTreatment); - getServiceTaxSettings(); + getTreatmentsTax(); function iterateTreatment(treatment) { - vm.service.problems.push({ + var p = { details: treatment.name, rate: treatment.rate[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')], amount: treatment.rate[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')], checked: false - }); + }; + if (treatment.orgcost && treatment.orgcost[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')]) + p.orgcost = treatment.orgcost[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')]; + vm.service.problems.push(p); } } @@ -1535,11 +1889,55 @@ } function populateRoD() { + var isTreatmentTaxed = false, isInventoryTaxed = false, treatmentTaxPercent = 0, inventoryTaxPercent = 0; + vm.taxSettings.forEach(iterateTaxes); if (vm.isDiscountApplied) { - vm.discountValue = serviceTcDc - vm.service.cost; - calculateDiscount(false); + var noTerminate = true, tp = 0.5, ip = 1 - tp; + if (treatmentTotal == 0) { + tp = 0; + ip = 1; + } else if (inventoryTotal == 0) { + ip = 0; + tp = 1; + } + while (noTerminate) { + var xt = (tp * vm.service.cost * 100) / (treatmentTaxPercent + 100); + if (treatmentTotal < xt) { + tp -= 0.1; + ip = 1 - tp; + if (tp < 0) + break; + continue; + } + vm.discount.treatment = treatmentTotal - xt; + var xi = (ip * vm.service.cost * 100) / (inventoryTaxPercent + 100); + if (inventoryTotal < xi) { + ip -= 0.1; + tp = 1 - ip; + if (ip < 0) + break; + continue; + } + vm.discount.part = inventoryTotal - xi; + noTerminate = false; + } + + vm.discount.total = parseFloat(vm.discount.treatment) + parseFloat(vm.discount.part); + vm.discount.total = (vm.discount.total % 1 != 0) ? parseFloat(vm.discount.total.toFixed(2)) : parseInt(vm.discount.total); + calculate(); } else if (vm.isRoundOffVal) vm.roundedOffVal = vm.service.cost - serviceTcRo; + + function iterateTaxes(tax) { + if (tax.isTaxApplied && tax.isForTreatments) { + isTreatmentTaxed = true; + treatmentTaxPercent += tax.percent; + } + if (tax.isTaxApplied && tax.isForInventory) { + isInventoryTaxed = true; + inventoryTaxPercent += tax.percent; + } + } } function calculateRoundOff(isRoundOffManual) { @@ -1549,20 +1947,54 @@ vm.roundedOffVal = (totalCost - ot); vm.roundedOffVal = (vm.roundedOffVal % 1 != 0) ? parseFloat(vm.roundedOffVal.toFixed(2)) : parseInt(vm.roundedOffVal); } - calculateCost(); + calculate(); } - function calculateDiscount(isDiscountByPercent) { - var totalCost = vm.service.cost; - if (isDiscountByPercent) { - vm.discountValue = totalCost * parseFloat(vm.discountPercentage) / 100; - vm.discountValue = (isNaN(vm.discountValue) || vm.discountValue == null) ? '' : vm.discountValue; - vm.discountValue = (vm.discountValue % 1 != 0) ? parseFloat(vm.discountValue.toFixed(2)) : parseInt(vm.discountValue); - } else if (vm.discountValue != '') { - vm.discountPercentage = 100 * parseFloat(vm.discountValue) / totalCost; - vm.discountPercentage = (vm.discountPercentage % 1 != 0) ? parseFloat(vm.discountPercentage.toFixed(1)) : parseInt(vm.discountPercentage); + function calculateDiscount() { + var treatmentLength = (vm.selectedProblems.length ? vm.selectedProblems.length : 0) + ((parseFloat(vm.problem.amount) > 0) ? 1 : 0); + var partLength = (vm.selectedInventories.length ? vm.selectedInventories.length : 0) + ((parseFloat(vm.inventory.amount) > 0) ? 1 : 0); + if (partLength > 0) { + var dv2 = vm.discount.total * 0.5; + var partValue = (dv2 > inventoryTotal) ? inventoryTotal : dv2; + vm.discount.part = (treatmentLength > 0) ? partValue : vm.discount.total; + } else + vm.discount.part = 0; + if (treatmentLength > 0) { + var treatmentValue = vm.discount.total - vm.discount.part; + if (treatmentValue > treatmentTotal) { + treatmentValue = treatmentTotal; + vm.discount.part = vm.discount.total - treatmentValue; + } + vm.discount.treatment = (partLength > 0) ? treatmentValue : vm.discount.total; + } else + vm.discount.treatment = 0; + calculate(); + } + + function calculateTotalDiscount() { + if (!vm.isDiscountApplied) + return; + var isTreatmentTaxed = false, isInventoryTaxed = false, treatmentTaxPercent = 0, inventoryTaxPercent = 0; + dTreatment = treatmentTotal - vm.discount.treatment; + dInventory = inventoryTotal - vm.discount.part; + + vm.taxSettings.forEach(iterateTaxes); + + dTreatmentTax = (isTreatmentTaxed) ? (dTreatment * treatmentTaxPercent / 100) : 0; + dInventoryTax = (isInventoryTaxed) ? (dInventory * inventoryTaxPercent / 100) : 0; + dTreatmentTax = (dTreatmentTax % 1 != 0) ? parseFloat(dTreatmentTax.toFixed(2)) : dTreatmentTax; + dInventoryTax = (dInventoryTax % 1 != 0) ? parseFloat(dInventoryTax.toFixed(2)) : dInventoryTax; + + function iterateTaxes(tax) { + if (tax.isTaxApplied && tax.isForTreatments) { + isTreatmentTaxed = true; + treatmentTaxPercent += tax.percent; + } + if (tax.isTaxApplied && tax.isForInventory) { + isInventoryTaxed = true; + inventoryTaxPercent += tax.percent; + } } - calculateCost(); } function changeForceStopCalCost(bool) { @@ -1572,18 +2004,11 @@ function calculateCost() { if (forceStopCalCost) return; - var totalCost = 0; - vm.service.problems.forEach(iterateProblem); - iterateProblem(vm.problem); - vm.selectedInventories.forEach(iterateInventories); - iterateInventories(vm.inventory); - if (vm.serviceType == vm.serviceTypeList[1]) { - vm.packages.forEach(iteratePackages); - } + var totalCost = 0, taxes = 0; + var discountedSubtotal = parseFloat(dTreatment + dTreatmentTax) + parseFloat(dInventory + dInventoryTax); + vm.taxSettings.forEach(iterateTaxes); + totalCost = (vm.isDiscountApplied && (vm.discount.total > 0)) ? Math.round(discountedSubtotal) : (parseFloat(vm.service.subtotal) + parseFloat(taxes)); serviceTcDc = totalCost; - if (vm.isDiscountApplied) { - totalCost = vm.isDiscountApplied && !isNaN(vm.discountValue) ? totalCost - vm.discountValue : totalCost; - } serviceTcRo = totalCost; if (vm.isRoundOffVal) { totalCost += parseFloat(vm.roundedOffVal); @@ -1591,69 +2016,35 @@ } totalCost = (totalCost % 1 != 0) ? parseFloat(totalCost.toFixed(2)) : totalCost; totalCost = (totalCost % 1).toFixed(2) == 0.00 ? Math.round(totalCost) : totalCost; + totalCost = (totalCost % 1).toFixed(2) == 0.99 ? Math.round(totalCost) : totalCost; vm.service.cost = parseFloat(totalCost); - function iterateProblem(element) { - totalCost += parseFloat(element.amount ? (element.amount * (element.checked ? 1 : 0)) : 0); - } - - function iterateInventories(element) { - totalCost += parseFloat(element.total ? (element.total * (element.checked ? 1 : 0)) : 0); - } - - function iteratePackages(package) { - if (!package.checked) - return; - package.selectedTreatments.forEach(ipt); - } - - function ipt(treatment) { - totalCost += treatment.amount[vm.vehicle.type.toLowerCase().replace(' ', '-')]; - } - } - - function calculateTax() { - var totalTax = 0.0; - iterateProblems(vm.problem); - vm.service.problems.forEach(iterateProblems); - if (vm.serviceType == vm.serviceTypeList[1]) - vm.packages.forEach(iteratePackages); - totalTax = (totalTax % 1 != 0) ? totalTax.toFixed(2) : parseInt(totalTax); - return totalTax; - - function iterateProblems(problem) { - if ((vm.sTaxSettings && !vm.sTaxSettings.applyTax) || !problem.tax || !problem.checked) - return; - totalTax += parseFloat(problem.tax); - } - - function iteratePackages(package) { - if (!package.checked) - return; - package.selectedTreatments.forEach(ipt); - } - - function ipt(treatment) { - if ((vm.sTaxSettings && !vm.sTaxSettings.applyTax) || !treatment.tax) - return; - totalTax += parseFloat(treatment.tax[vm.vehicle.type.toLowerCase().replace(' ', '-')]); + function iterateTaxes(tax) { + taxes += tax.tax; } } function finalizeNewProblem(isFromAutocomplete) { vm.problem.details = vm.problem.details.trim(); + vm.problemFocusIndex = -1; if (vm.problem.details != '') { if (isFromAutocomplete) updateTreatmentDetails(); var found = $filter('filter')(vm.service.problems, { details: vm.problem.details }, true); + var foundExisting = $filter('filter')(vm.selectedProblems, { + details: vm.problem.details + }, true); if (found.length == 1) { found[0].checked = true; found[0].rate = vm.problem.rate; found[0].tax = vm.problem.tax; found[0].amount = vm.problem.amount; - vm.selectedProblems.push(found[0]); + if (foundExisting.length == 0) + vm.selectedProblems.push(found[0]); + else + foundExisting[0] = found[0]; } else { vm.service.problems.push({ details: vm.problem.details, @@ -1667,10 +2058,10 @@ vm.problem.details = ''; vm.problem.amount = ''; vm.problem.rate = ''; - vm.problem.tax = ''; - calculateCost(); - if (isFromAutocomplete) - vm.problemFocusIndex = vm.selectedProblems.length - 1; + vm.problem.tax = {}; + calculate(); + if (isFromAutocomplete || foundExisting.length != 0) + vm.problemFocusIndex = (foundExisting.length == 0) ? vm.selectedProblems.length - 1 : vm.selectedProblems.indexOf(foundExisting[0]); else setTimeout(focusNewProblemDetails, 300); } @@ -1688,27 +2079,34 @@ if (found.length == 1) { var rate = found[0].rate[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')]; vm.problem.amount = (rate == '' || rate == undefined ? vm.problem.amount : rate); - if (vm.sTaxSettings.applyTax) { - if (vm.sTaxSettings.inclusive) { - vm.problem.rate = (vm.problem.amount * 100) / (vm.sTaxSettings.tax + 100); - vm.problem.tax = (vm.problem.rate * vm.sTaxSettings.tax / 100); - } else { - vm.problem.rate = (rate == '' || rate == undefined ? vm.problem.rate : rate); - vm.problem.tax = (vm.problem.rate * vm.sTaxSettings.tax / 100); - vm.problem.amount = vm.problem.rate + vm.problem.tax; + var taxable = vm.problem.amount; + vm.problem.tax = {}; + vm.taxSettings.forEach(iterateTaxes); + vm.problem.rate = taxable; + vm.problem.checked = true; + calculate(); + + function iterateTaxes(tax) { + if (!tax.isForTreatments) + return; + if (tax.isTaxApplied) { + if (tax.inclusive) { + var temptax = 0; + vm.problem.rate = (taxable * 100) / (tax.percent + 100); + temptax = (vm.problem.rate * tax.percent / 100); + vm.problem.tax[tax.name] = temptax; + taxable = vm.problem.rate; + } else { + var temptax = 0; + temptax = (taxable * tax.percent / 100); + vm.problem.tax[tax.name] = temptax; + } } - } else { - if (vm.sTaxSettings.inclusive) - vm.problem.rate = (rate == '' || rate == undefined ? vm.problem.rate : rate); - else - vm.problem.amount = (rate == '' || rate == undefined ? vm.problem.amount : rate); } - vm.problem.checked = true; - calculateCost(); } } else { vm.problem.rate = ''; - vm.problem.tax = 0; + vm.problem.tax = {}; vm.problem.amount = ''; vm.problem.checked = false; } @@ -1716,28 +2114,18 @@ function validate() { if (vm.user.name == '') { - changeUserInfoState(true); - setTimeout(doFocus, 300); - utils.showSimpleToast('Please Enter Name'); - - function doFocus() { - $('#ami-user-name').focus(); - } - return false + vm.user.name = 'Anonymous'; } var isVehicleBlank = (vm.vehicle.manuf == undefined || vm.vehicle.manuf == '') && (vm.vehicle.model == undefined || vm.vehicle.model == '') && (vm.vehicle.reg == undefined || vm.vehicle.reg == ''); if (isVehicleBlank) { - changeVehicleInfoState(true); - utils.showSimpleToast('Please Enter At Least One Vehicle Detail'); - return false; + vm.vehicle.reg = 'Vehicle'; } - return true; } // save to database function save(redirect) { - if (!validate()) return; + validate(); switch (vm.serviceType) { case vm.serviceTypeList[0]: if (checkBasic() == false) { @@ -1758,6 +2146,8 @@ } break; } + if (vm.problem.details) + finalizeNewProblem(); vm.service.problems = vm.selectedProblems; var options = { isLastInvoiceNoChanged: (vm.service.invoiceno == olInvoiceNo), @@ -1765,46 +2155,24 @@ isLastJobCardNoChanged: (vm.service.jobcardno == olJobCardNo) } vm.user.memberships = vm.membershipChips; - switch (vm.serviceType) { - case vm.serviceTypeList[1]: - vm.packages.forEach(addPkToService); - break; - case vm.serviceTypeList[2]: - vm.membershipChips.forEach(addMsToService); - break; - } + if (vm.packages) + vm.packages.forEach(addPkToService); + if (vm.membershipChips) + vm.membershipChips.forEach(addMsToService); vm.service.status = vm.servicestatus ? 'paid' : 'due'; vm.service.date = moment(vm.service.date).format(); if (vm.isNextDueService) vm.vehicle.nextdue = moment(vm.nextDueDate).format(); - if (vm.isDiscountApplied) { - vm.service['discount'] = { - percent: parseFloat(vm.discountPercentage), - amount: parseFloat(vm.discountValue) - } - } + if (vm.isDiscountApplied) + vm.service.discount = vm.discount; if (vm.isRoundOffVal) { vm.service['roundoff'] = vm.roundedOffVal; } - if (vm.problem.details) - vm.service.problems.push(vm.problem); vm.service.problems.forEach(iterateProblems); - if (vm.sTaxSettings != undefined) { - vm.service.serviceTax = { - applyTax: vm.sTaxSettings.applyTax, - taxIncType: (vm.sTaxSettings.inclusive) ? 'inclusive' : 'exclusive', - tax: vm.sTaxSettings.tax - }; - } - if (vm.vatSettings != undefined) { - vm.service.vat = { - applyTax: vm.vatSettings.applyTax, - taxIncType: (vm.vatSettings.inclusive) ? 'inclusive' : 'exclusive', - tax: vm.vatSettings.tax - } - } + vm.service.taxes = {}; + vm.taxSettings.forEach(iterateTaxes); if (vm.inventory.name) - vm.selectedInventories.push(vm.inventory); + finalizeNewInventory(); vm.selectedInventories.forEach(iterateInventories); vm.service.inventories = vm.selectedInventories; switch (vm.service.state) { @@ -1823,6 +2191,17 @@ } amServices.saveService(vm.user, vm.vehicle, vm.service, options).then(success).catch(failure); + function iterateTaxes(tax) { + vm.service.taxes[tax.name] = { + tax: tax.tax, + type: (tax.inclusive) ? "inclusive" : "exclusive", + isTaxApplied: tax.isTaxApplied, + isForTreatments: tax.isForTreatments, + isForInventory: tax.isForInventory, + percent: tax.percent + } + } + function addMsToService(membership) { if (!membership.checked) return; @@ -1848,19 +2227,13 @@ } function iterateProblems(problem) { - if (!vm.sTaxSettings || (vm.sTaxSettings && !vm.sTaxSettings.applyTax && vm.sTaxSettings.inclusive)) - problem.rate = problem.amount; delete problem.checked; - delete problem['amount']; delete problem['$$hashKey']; } function iterateInventories(inventory) { - if (!vm.vatSettings || (vm.vatSettings && vm.vatSettings.applyTax && vm.vatSettings.inclusive)) - inventory.rate = inventory.amount; delete inventory.checked; delete inventory['total']; - delete inventory['amount']; delete inventory['$$hashKey']; } @@ -1926,149 +2299,4 @@ } } } - - function MembershipEditDialogController($mdDialog, $filter, membership, treatments) { - var editMsVm = this; - editMsVm.treatment = { - details: '' - }; - editMsVm.membership = { - name: membership.name, - occurences: membership.occurences, - duration: membership.duration - }; - editMsVm.selectedTreatments = []; - editMsVm.treatments = treatments; - editMsVm.confirmDialog = confirmDialog; - editMsVm.treatmentQuerySearch = treatmentQuerySearch; - editMsVm.finalizeNewTreatment = finalizeNewTreatment; - editMsVm.updateTreatmentDetails = updateTreatmentDetails; - - loadDefaultOccDur(); - loadMemberships(); - - function loadMemberships() { - membership.treatments.forEach(iterateTreatments); - - function iterateTreatments(treatment) { - var found = $filter('filter')(editMsVm.treatments, { - name: treatment.name - }, true); - - if (found.length == 1) { - found[0].given.occurences = treatment.given.occurences; - found[0].given.duration = treatment.given.duration; - found[0].used.occurences = treatment.used.occurences; - found[0].used.duration = treatment.used.duration; - editMsVm.selectedTreatments.push(found[0]); - } else { - editMsVm.treatments.push(treatment); - editMsVm.selectedTreatments.push(editMsVm.treatments[editMsVm.treatments.length - 1]); - } - } - } - - function updateTreatmentDetails() { - var found = $filter('filter')(editMsVm.treatments, { - name: editMsVm.treatment.details - }); - if (found.length == 1 && found[0].name == editMsVm.treatment.details) { - editMsVm.treatment.occurences = found[0].given.occurences; - editMsVm.treatment.duration = found[0].given.duration; - } else { - editMsVm.treatment.occurences = editMsVm.membership.occurences - editMsVm.treatment.duration = editMsVm.membership.duration; - } - } - - // query search for treatments [autocomplete] - function treatmentQuerySearch() { - var tracker = $q.defer(); - var results = (editMsVm.treatment.details ? editMsVm.treatments.filter(createFilterForTreatments(editMsVm.treatment.details)) : editMsVm.treatments); - - return results; - } - - // create filter for users' query list - function createFilterForTreatments(query) { - var lcQuery = angular.lowercase(query); - return function filterFn(item) { - return (angular.lowercase(item.name).indexOf(lcQuery) === 0); - } - } - - function finalizeNewTreatment(btnClicked) { - editMsVm.treatment.details = editMsVm.treatment.details.trim(); - if (editMsVm.treatment.details != '') { - var found = $filter('filter')(editMsVm.treatments, { - name: editMsVm.treatment.details - }, true); - if (found.length == 1 && found[0].name == editMsVm.treatment.details) { - found[0].checked = true; - found[0].rate = editMsVm.treatment.rate; - found[0].given.duration = editMsVm.treatment.duration; - found[0].given.occurences = editMsVm.treatment.occurences; - found[0].used.duration = 0; - found[0].used.occurences = 0; - editMsVm.selectedTreatments.push(found[0]); - } else { - editMsVm.treatments.push({ - name: editMsVm.treatment.details, - rate: editMsVm.treatment.rate, - given: { - duration: editMsVm.treatment.duration, - occurences: editMsVm.treatment.occurences, - }, - used: { - duration: 0, - occurences: 0 - }, - checked: true - }); - editMsVm.selectedTreatments.push(editMsVm.treatments[editMsVm.treatments.length - 1]); - } - editMsVm.treatment.details = ''; - editMsVm.treatment.rate = {}; - editMsVm.treatment.occurences = editMsVm.membership.occurences; - editMsVm.treatment.duration = editMsVm.membership.duration; - angular.element('#new-treatment-details').find('input')[0].focus(); - } - if (btnClicked) - angular.element('#new-treatment-details').find('input')[0].focus(); - } - - function loadDefaultOccDur() { - editMsVm.treatments.forEach(iterateTreatments); - - function iterateTreatments(treatment) { - if (!treatment.given) { - treatment.given = { - occurences: membership.occurences, - duration: membership.duration - } - } - if (!treatment.used) { - treatment.used = { - occurences: 0, - duration: 0 - } - } - } - } - - function confirmDialog() { - membership.treatments = editMsVm.selectedTreatments; - membership.selectedTreatments = []; - membership.treatments.forEach(makeSelectedTreatments); - $mdDialog.hide(); - - function makeSelectedTreatments(treatment) { - if (membership.calculateTOccurenceLeft(treatment) != 0 && membership.calculateTDurationLeft(treatment) != 0) { - treatment.checked = true; - membership.selectedTreatments.push(treatment); - } else - treatment.checked = false; - } - } - } })(); \ No newline at end of file diff --git a/src/app/components/services/services-edit.controller.js b/src/app/components/services/services-edit.controller.js index fcc6709f..366d656d 100644 --- a/src/app/components/services/services-edit.controller.js +++ b/src/app/components/services/services-edit.controller.js @@ -2,43 +2,39 @@ * Controller for Edit Service component * @author ndkcha * @since 0.4.1 - * @version 0.6.5 + * @version 0.7.0 */ /// (function() { - angular.module('automintApp') - .controller('amCtrlSeUI', ServiceEditController) - .controller('amCtrlMeD', MembershipEditDialogController); + angular.module('automintApp').controller('amCtrlSeUI', ServiceEditController); - ServiceEditController.$inject = ['$scope', '$state', '$q', '$log', '$filter', '$timeout', '$mdEditDialog', '$mdDialog', '$mdSidenav', 'utils', 'amServices']; - MembershipEditDialogController.$inject = ['$mdDialog', '$filter', 'membership', 'treatments']; + ServiceEditController.$inject = ['$rootScope', '$scope', '$state', '$q', '$log', '$filter', '$timeout', '$mdEditDialog', '$mdDialog', '$mdSidenav', 'utils', 'amServices']; /* ====== NOTE ======= > Do not create new method named moment() since it is used by moment.js */ - function ServiceEditController($scope, $state, $q, $log, $filter, $timeout, $mdEditDialog, $mdDialog, $mdSidenav, utils, amServices) { + function ServiceEditController($rootScope, $scope, $state, $q, $log, $filter, $timeout, $mdEditDialog, $mdDialog, $mdSidenav, utils, amServices) { // initialize view model var vm = this; // temporary named assignments - var autofillVehicle = false, - isDiscountByPercent = true, - isManualRoundOff = false, - isFirstTimeLoad = true, - serviceTcRo = 0, - serviceTcDc = 0, - forceStopCalCost = false, - olInvoiceNo = 0, - olJobCardNo = 0, - olEstimateNo = 0, - isInvoice = false, - isEstimate = false, - isJobCard = false, - wasNextDueService = false; + var autofillVehicle = false; + var isDiscountByPercent = true, isManualRoundOff = false; + var isFirstTimeLoad = true; + var serviceTcRo = 0, serviceTcDc = 0; + var forceStopCalCost = false; + var olInvoiceNo = 0, olJobCardNo = 0, olEstimateNo = 0; + var isInvoice = false, isEstimate = false, isJobCard = false; + var wasNextDueService = false; + var treatmentTotal = 0, inventoryTotal = 0; + var dTreatmentTax, dInventoryTax, dTreatment, dInventory; + var taxSettingsSnap = [], lastServiceState; + var orgVehicle = {}, userMobile = undefined; + var isPackageAvailInService = false; // vm assignments to keep track of UI related elements vm.vehicleTypeList = []; @@ -65,12 +61,17 @@ invoiceno: undefined, jobcardno: undefined, estimateno: undefined, - problems: [] + problems: [], + taxes: { + inventory: 0, + treatments: 0 + }, + subtotal: 0 }; vm.problem = { details: '', rate: '', - tax: '', + tax: {}, amount: '' }; vm.manufacturers = []; @@ -82,14 +83,12 @@ vm.membershipChips = []; vm.serviceTypeList = ['Treatments', 'Package', 'Membership']; vm.roundedOffVal = 0; - vm.discountPercentage = 0; - vm.discountValue = 0; vm.inventories = []; vm.selectedInventories = []; vm.inventory = { name: '', rate: '', - tax: '', + tax: {}, qty: 1, amount: '', total: '' @@ -103,9 +102,16 @@ vm.label_invoice = 'Invoice'; vm.isNextDueService = false; vm.nextDueDate = new Date(); - vm.nextDueDate.setMonth(vm.nextDueDate.getMonth() + 3); vm.problemFocusIndex = -1; vm.inventoryFocusIndex = -1; + vm.discount = { + treatment: 0, + part: 0, + total: 0 + }; + vm.taxSettings = []; + vm.currencySymbol = "Rs."; + vm.areTaxesHidden = false; // named assignments to handle behaviour of UI elements vm.redirect = { @@ -128,24 +134,19 @@ vm.save = save; vm.queryMembershipChip = queryMembershipChip; vm.OnClickMembershipChip = OnClickMembershipChip; - vm.calculateCost = calculateCost; vm.OnAddMembershipChip = OnAddMembershipChip; vm.navigateToSubscribeMembership = navigateToSubscribeMembership; vm.goBack = goBack; vm.changeProblemRate = changeProblemRate; - vm.changeServiceTax = changeServiceTax; - vm.OnServiceTaxEnabledChange = OnServiceTaxEnabledChange; + vm.OnTaxEnabledChange = OnTaxEnabledChange; vm.convertPbToTitleCase = convertPbToTitleCase; - vm.calculateTax = calculateTax; vm.convertInToTitleCase = convertInToTitleCase; - vm.changeVat = changeVat; vm.onInventorySelected = onInventorySelected; vm.onInventoryDeselected = onInventoryDeselected; vm.changeInventoryRate = changeInventoryRate; vm.inventoryQuerySearch = inventoryQuerySearch; vm.updateInventoryDetails = updateInventoryDetails; vm.finalizeNewInventory = finalizeNewInventory; - vm.calculateVat = calculateVat; vm.changeQty = changeQty; vm.changeInventoryTotal = changeInventoryTotal; vm.populateRoD = populateRoD; @@ -165,14 +166,8 @@ vm.IsMembershipEnabled = IsMembershipEnabled; vm.IsPackageEnabled = IsPackageEnabled; vm.convertVehicleTypeToAF = convertVehicleTypeToAF; - vm.IsTreatmentAmountEditable = IsTreatmentAmountEditable; - vm.IsTreatmentAmountText = IsTreatmentAmountText; - vm.IsPackageEnabled = IsPackageEnabled; vm.changeDisplayAsList = changeDisplayAsList; - vm.IsTreatmentRateDisplayed = IsTreatmentRateDisplayed; vm.changeInventoryAsList = changeInventoryAsList; - vm.IsInventoryTotalEditable = IsInventoryTotalEditable; - vm.IsInventoryTotalText = IsInventoryTotalText; vm.IsServiceStateSelected = IsServiceStateSelected; vm.selectServiceState = selectServiceState; vm.WhichServiceStateEnabled = WhichServiceStateEnabled; @@ -190,20 +185,339 @@ vm.getDate = getDate; vm.IsProblemFocusIndex = IsProblemFocusIndex; vm.IsInventoryFocusIndex = IsInventoryFocusIndex; + vm.openPartialPaymentBox = openPartialPaymentBox; + vm.calculateDue = calculateDue; + vm.IsPartialPayment = IsPartialPayment; + vm.changeServiceStatus = changeServiceStatus; + vm.openDiscountBox = openDiscountBox; + vm.OnDiscountStateChange = OnDiscountStateChange; + vm.selectUserBasedOnMobile = selectUserBasedOnMobile; + vm.IsCustomerNotAnonymus = IsCustomerNotAnonymus; + vm.goToDashboard = goToDashboard; + vm.IsCustomerSelected = IsCustomerSelected; + vm.openCustomerProfile = openCustomerProfile; + vm.openTd = openTd; + vm.openId = openId; + + // watchers + $(window).on('resize', OnWindowResize); // default execution steps setCoverPic(); buildDelayedToggler('service-details-left'); changeServiceInfoState(true); + getCurrencySymbol(); getVehicleTypes(); getPackages(); getMemberships(); - // watchers - $(window).on('resize', OnWindowResize); - // function definitions + function openId(event, inventory) { + $mdDialog.show({ + controller: 'amCtrlSeId', + controllerAs: 'vm', + templateUrl: 'app/components/services/tmpl2/dialog-id.html', + parent: angular.element(document.body), + targetEvent: event, + locals: { + inventory: inventory + }, + clickOutsideToClose: true + }).then(success).catch(success); + + function success(res) { + // do nothing + } + } + + function openTd(event, problem) { + $mdDialog.show({ + controller: 'amCtrlSeTd', + controllerAs: 'vm', + templateUrl: 'app/components/services/tmpl2/dialog-td.html', + parent: angular.element(document.body), + targetEvent: event, + locals: { + problem: problem + }, + clickOutsideToClose: true + }).then(success).catch(success); + + function success(res) { + if (!res) + return; + problem.orgcost = res.orgcost; + } + } + + function openCustomerProfile() { + $state.go('restricted.customers.edit', { + id: vm.user.id + }); + } + + function IsCustomerSelected() { + if (vm.user.id == undefined) + return false; + return (vm.user.id != ''); + } + + function goToDashboard() { + $mdSidenav('main-nav-left').close() + $state.go('restricted.dashboard'); + } + + function IsCustomerNotAnonymus() { + return (vm.user.name != 'Anonymous'); + } + + function selectUserBasedOnMobile() { + if (vm.user.mobile != '') { + vm.loadingBasedOnMobile = true; + amServices.getCustomerByMobile(vm.user.mobile).then(success).catch(failure); + } + + function success(res) { + vm.loadingBasedOnMobile = false; + if (vm.user.id != res.id) { + utils.showSimpleToast('This mobile number is already in registered with ' + res.name); + vm.user.mobile = userMobile; + } + } + + function failure(err) { + vm.loadingBasedOnMobile = false; + } + } + + function getCurrencySymbol() { + amServices.getCurrencySymbol().then(success).catch(failure); + + function success(res) { + vm.currencySymbol = res; + } + + function failure(err) { + vm.currencySymbol = "Rs."; + } + } + + function calculate() { + calculateSubtotal(); + calculateTotalDiscount(); + calculateTaxes(); + calculateCost(); + } + + function calculateTaxes() { + vm.taxSettings.forEach(iterateTaxes); + vm.service.problems.forEach(iterateProblems); + if (vm.problem.details != '') + iterateProblem(vm.problem); + if (vm.packages) + vm.packages.forEach(iteratePackages); + vm.selectedInventories.forEach(iterateInventories); + if (vm.inventory.name != '') + iterateInventory(vm.inventory); + if (vm.isDiscountApplied && (parseFloat(vm.discount.total) > 0)) { + vm.taxSettings.forEach(iterateTaxes); + vm.taxSettings.forEach(iterateTaxesAfter); + } + + function iterateTaxesAfter(tax) { + if (tax.isTaxApplied && tax.isForTreatments) + tax.tax += (dTreatment * tax.percent / 100); + if (tax.isTaxApplied && tax.isForInventory) + tax.tax += (dInventory * tax.percent / 100); + tax.tax = (tax.tax % 1 != 0) ? parseFloat(tax.tax.toFixed(2)) : parseInt(tax.tax); + } + + function iterateTaxes(tax) { + tax.tax = 0; + } + + function iteratePackages(package) { + if (!package.checked) + return; + package.selectedTreatments.forEach(iterateProblems); + } + + function iterateInventories(inventory) { + if (!inventory.checked) + return; + if (inventory.tax) { + Object.keys(inventory.tax).forEach(iterateTaxes); + + function iterateTaxes(tax) { + var found = $filter('filter')(vm.taxSettings, { + name: tax + }, true); + + if (found.length == 1) { + if (!found[0].isTaxApplied) + return; + if (!found[0].tax) + found[0].tax = 0; + found[0].tax += (inventory.tax[tax] * (inventory.qty ? inventory.qty : 1)); + found[0].tax = (found[0].tax % 1 != 0) ? parseFloat(found[0].tax.toFixed(2)) : parseInt(found[0].tax); + } + } + } + } + + function iterateProblems(problem) { + if (!problem.checked) + return; + if (problem.tax) { + Object.keys(problem.tax).forEach(iterateTaxes); + + function iterateTaxes(tax) { + var found = $filter('filter')(vm.taxSettings, { + name: tax + }, true); + + if (found.length == 1) { + if (!found[0].isTaxApplied) + return; + if (!found[0].tax) + found[0].tax = 0; + found[0].tax += problem.tax[tax]; + found[0].tax = (found[0].tax % 1 != 0) ? parseFloat(found[0].tax.toFixed(2)) : parseInt(found[0].tax); + } + } + } + } + + function iterateProblem(problem) { + if (problem.tax) { + Object.keys(problem.tax).forEach(iterateTaxes); + + function iterateTaxes(tax) { + if (problem.tax[tax] > 0) { + var found = $filter('filter')(vm.taxSettings, { + name: tax + }, true); + + if (found.length == 1) { + if (!found[0].isTaxApplied) + return; + if (!found[0].tax) + found[0].tax = 0; + found[0].tax += problem.tax[tax]; + found[0].tax = (found[0].tax % 1 != 0) ? parseFloat(found[0].tax.toFixed(2)) : parseInt(found[0].tax); + } + } + } + } + } + + function iterateInventory(inventory) { + if (inventory.tax) { + Object.keys(inventory.tax).forEach(iterateTaxes); + + function iterateTaxes(tax) { + if (inventory.tax[tax] > 0) { + var found = $filter('filter')(vm.taxSettings, { + name: tax + }, true); + + if (found.length == 1) { + if (!found[0].isTaxApplied) + return; + if (!found[0].tax) + found[0].tax = 0; + found[0].tax += (inventory.tax[tax] * (inventory.qty ? inventory.qty : 1)); + found[0].tax = (found[0].tax % 1 != 0) ? parseFloat(found[0].tax.toFixed(2)) : parseInt(found[0].tax); + } + } + } + } + } + } + + function OnDiscountStateChange() { + calculateDiscount(); + calculate(); + } + + function openDiscountBox() { + $mdDialog.show({ + controller: 'amCtrlSeDc', + controllerAs: 'vm', + templateUrl: 'app/components/services/tmpl/dialog_discount.html', + parent: angular.element(document.body), + targetEvent: event, + locals: { + currencySymbol: vm.currencySymbol, + treatmentLength: (vm.selectedProblems.length ? vm.selectedProblems.length : 0) + ((parseFloat(vm.problem.amount) > 0) ? 1 : 0), + partLength: (vm.selectedInventories.length ? vm.selectedInventories.length : 0) + ((parseFloat(vm.inventory.amount) > 0) ? 1 : 0), + discountObj: vm.discount, + partTotal: inventoryTotal, + treatmentTotal: treatmentTotal + }, + clickOutsideToClose: true + }).then(success).catch(success); + + function success(res) { + if (!res) + return; + vm.discount.treatment = res.treatment; + vm.discount.part = res.part; + vm.discount.total = res.total; + calculate(); + } + } + + function changeServiceStatus() { + if (vm.servicestatus) { + if (vm.service.partialpayment) { + if ((vm.service.partialpayment.total - vm.service.cost) != 0) { + vm.service.partialpayment[moment().format()] = vm.service.cost - vm.service.partialpayment.total; + vm.service.partialpayment.total = vm.service.cost; + } + } + } else { + vm.service.partialpayment = { + total: 0 + } + } + } + + function IsPartialPayment() { + return (vm.service.partialpayment && !vm.servicestatus); + } + + function calculateDue() { + return (vm.service.cost - vm.service.partialpayment.total); + } + + function openPartialPaymentBox() { + $mdDialog.show({ + controller: 'amCtrlSePp', + controllerAs: 'vm', + templateUrl: 'app/components/services/tmpl/dialog_partialpayment.html', + parent: angular.element(document.body), + targetEvent: event, + locals: { + currencySymbol: vm.currencySymbol, + totalCost: vm.service.cost, + partialPayments: vm.service.partialpayment + }, + clickOutsideToClose: true + }).then(success).catch(success); + + function success(res) { + if (!res) { + vm.servicestatus = vm.service.partialpayment ? ((vm.service.partialpayment.total - vm.service.cost) == 0) : true; + return; + } + if (res.total) + vm.servicestatus = ((parseFloat(res.total) - parseFloat(vm.service.cost)) == 0); + vm.service.partialpayment = res; + } + } + function IsInventoryFocusIndex(index) { return (vm.inventoryFocusIndex == index); } @@ -244,7 +558,14 @@ } function IsSubtotalEnabled() { - return (vm.isDiscountApplied || vm.isRoundOffVal || (vm.sTaxSettings && vm.sTaxSettings.applyTax) || (vm.vatSettings && vm.vatSettings.applyTax)); + var isTaxEnabled = false; + vm.taxSettings.forEach(iterateTaxes); + return (vm.isDiscountApplied || vm.isRoundOffVal || isTaxEnabled); + + function iterateTaxes(tax) { + if (tax.isTaxApplied) + isTaxEnabled = true; + } } function isRoD() { @@ -259,22 +580,29 @@ function calculateSubtotal() { var totalCost = 0; + treatmentTotal = 0, inventoryTotal = 0; vm.service.problems.forEach(iterateProblem); - iterateProblem(vm.problem); + if (vm.problem.details != '') + totalCost += (vm.problem.rate) ? parseFloat(vm.problem.rate) : 0; vm.selectedInventories.forEach(iterateInventories); - iterateInventories(vm.inventory); - if (vm.serviceType == vm.serviceTypeList[1]) { + if (vm.inventory.name != '') + totalCost += (vm.inventory.rate) ? (parseFloat(vm.inventory.rate) * parseFloat(vm.inventory.qty)) : 0; + if (vm.packages) { vm.packages.forEach(iteratePackages); } totalCost = (totalCost % 1 != 0) ? totalCost.toFixed(2) : parseInt(totalCost); - return totalCost; + vm.service.subtotal = parseFloat(totalCost); function iterateProblem(element) { - totalCost += parseFloat(element.rate ? (element.rate * (element.checked ? 1 : 0)) : 0); + var temp = parseFloat(element.rate ? (element.rate * (element.checked ? 1 : 0)) : 0); + totalCost += temp; + treatmentTotal += temp; } function iterateInventories(element) { - totalCost += parseFloat(element.rate ? ((element.rate * element.qty) * (element.checked ? 1 : 0)) : 0); + var temp = parseFloat(element.rate ? ((element.rate * element.qty) * (element.checked ? 1 : 0)) : 0); + totalCost += temp; + inventoryTotal += temp; } function iteratePackages(package) { @@ -284,7 +612,9 @@ } function ipt(treatment) { - totalCost += treatment.rate[vm.vehicle.type.toLowerCase().replace(' ', '-')]; + var temp = treatment.amount[convertVehicleTypeToAF()]; + totalCost += temp; + treatmentTotal += temp; } } @@ -356,52 +686,52 @@ function selectServiceState(state) { vm.service.state = state; vm.label_invoice = (vm.service.state == vm.serviceStateList[2]) ? 'Invoice' : 'Send'; - } + if (vm.service.state != vm.serviceStateList[2]) { + vm.areTaxesHidden = true; + if ((lastServiceState == vm.serviceStateList[2]) || !lastServiceState) { + taxSettingsSnap = []; + vm.taxSettings.forEach(iterateTaxes); + } + } else { + vm.areTaxesHidden = false; + vm.taxSettings = []; + taxSettingsSnap.forEach(restoreTaxes); + } + lastServiceState = vm.service.state; + OnTaxEnabledChange(); - function IsServiceStateSelected(state) { - return (vm.service.state == state); - } + function restoreTaxes(tax) { + vm.taxSettings.push(tax); + } - function IsInventoryTotalText() { - return (vm.vatSettings && !vm.vatSettings.inclusive && vm.vatSettings.applyTax); + function iterateTaxes(tax) { + var t = $.extend({}, tax) + taxSettingsSnap.push(t); + tax.isTaxApplied = false; + } } - function IsInventoryTotalEditable() { - return (vm.vatSettings && (vm.vatSettings.inclusive || !vm.vatSettings.applyTax)); + function IsServiceStateSelected(state) { + return (vm.service.state == state); } function changeInventoryAsList(bool) { vm.displayInventoriesAsList = bool; } - function IsTreatmentRateDisplayed() { - return (vm.sTaxSettings && vm.sTaxSettings.applyTax && !vm.sTaxSettings.inclusive); - } - function changeDisplayAsList(bool) { vm.displayTreatmentAsList = bool; } function IsPackageEnabled() { - return (vm.packages.length < 1); - } - - function IsTreatmentAmountText() { - return (vm.sTaxSettings && !vm.sTaxSettings.inclusive && vm.sTaxSettings.applyTax); - } - - function IsTreatmentAmountEditable() { - return (vm.sTaxSettings && (vm.sTaxSettings.inclusive || !vm.sTaxSettings.applyTax)); + return isPackageAvailInService; + // return (vm.packages && (vm.packages.length > 0)); } function convertVehicleTypeToAF() { return (vm.vehicle.type.toLowerCase().replace(' ', '-')); } - function IsPackageEnabled() { - return (vm.serviceType == vm.serviceTypeList[1]); - } - function IsMembershipEnabled() { return (vm.serviceType == vm.serviceTypeList[2]); } @@ -526,7 +856,7 @@ $mdDialog.show(confirm).then(performDelete, ignoreDelete); function performDelete() { - console.info('deleted'); + // do nothing } function ignoreDelete() { @@ -539,28 +869,18 @@ changeInventoryRate(inventory); } - function calculateVat() { - var totalTax = 0.0; - vm.selectedInventories.forEach(iterateInventories); - iterateInventories(vm.inventory); - totalTax = (totalTax % 1 != 0) ? totalTax.toFixed(2) : totalTax; - return totalTax; - - function iterateInventories(element) { - if ((vm.vatSettings && !vm.vatSettings.applyTax) || !element.tax || !element.checked) - return; - totalTax += parseFloat(element.tax * (element.qty ? element.qty : 1)); - } - } - function finalizeNewInventory(isFromAutocomplete) { vm.inventory.name = vm.inventory.name.trim(); + vm.inventoryFocusIndex = -1; if (vm.inventory.name != '') { if (isFromAutocomplete) updateInventoryDetails(); var found = $filter('filter')(vm.inventories, { name: vm.inventory.name }, true); + var foundExisting = $filter('filter')(vm.selectedInventories, { + name: vm.inventory.name + }, true); if (found.length == 1) { found[0].checked = true; found[0].rate = vm.inventory.rate; @@ -568,7 +888,10 @@ found[0].qty = vm.inventory.qty; found[0].amount = vm.inventory.amount; found[0].total = vm.inventory.total; - vm.selectedInventories.push(found[0]); + if (foundExisting.length == 0) + vm.selectedInventories.push(found[0]); + else + foundExisting[0] = found[0]; } else { vm.inventories.push({ name: vm.inventory.name, @@ -581,15 +904,15 @@ }); vm.selectedInventories.push(vm.inventories[vm.inventories.length - 1]); } - calculateCost(); vm.inventory.name = ''; vm.inventory.amount = ''; vm.inventory.rate = ''; - vm.inventory.tax = ''; + vm.inventory.tax = {}; vm.inventory.qty = 1; vm.inventory.total = ''; - if (isFromAutocomplete) - vm.inventoryFocusIndex = vm.selectedInventories.length - 1; + calculate(); + if (isFromAutocomplete || foundExisting.length != 0) + vm.inventoryFocusIndex = (foundExisting.length == 0) ? vm.selectedInventories.length - 1 : vm.selectedInventories.indexOf(foundExisting[0]); else setTimeout(focusNewInventoryName, 300); } @@ -605,43 +928,44 @@ name: vm.inventory.name }, true); if (found.length == 1) { - var rate; - if (vm.vatSettings.applyTax) - rate = (vm.vatSettings.inclusive) ? found[0].amount : found[0].rate; - else - rate = found[0].rate; - vm.inventory.amount = (rate == '' || rate == undefined ? vm.inventory.amount : rate); - if (vm.vatSettings.applyTax) { - if (vm.vatSettings.inclusive) { - vm.inventory.rate = (vm.inventory.amount * 100) / (vm.vatSettings.tax + 100); - vm.inventory.tax = (vm.inventory.rate * vm.vatSettings.tax / 100); - } else { - vm.inventory.rate = (rate == '' || rate == undefined ? vm.inventory.rate : rate); - vm.inventory.tax = (vm.inventory.rate * vm.vatSettings.tax / 100); - vm.inventory.amount = Math.round(vm.inventory.rate + vm.inventory.tax); - } - } else { - if (vm.vatSettings.inclusive) - vm.inventory.rate = (rate == '' || rate == undefined ? vm.inventory.rate : rate); - else - vm.inventory.amount = (rate == '' || rate == undefined ? vm.inventory.amount : rate); - } + var taxable = vm.inventory.amount; + vm.inventory.tax = {}; + vm.taxSettings.forEach(iterateTaxes); + vm.inventory.rate = taxable; vm.inventory.total = vm.inventory.amount * vm.inventory.qty; vm.inventory.checked = true; - calculateCost(); + calculate(); + + function iterateTaxes(tax) { + if (!tax.isForInventory) + return; + if (tax.isTaxApplied) { + if (tax.inclusive) { + var temptax = 0; + vm.inventory.rate = (taxable * 100) / (tax.percent + 100); + temptax = (vm.inventory.rate * tax.percent / 100); + vm.inventory.tax[tax.name] = temptax; + taxable = vm.inventory.rate; + } else { + var temptax = 0; + temptax = (taxable * tax.percent / 100); + vm.inventory.tax[tax.name] = temptax; + } + } + } } } else { vm.inventory.checked = false; vm.inventory.rate = ''; - vm.inventory.tax = 0; + vm.inventory.tax = {}; vm.inventory.amount = ''; vm.inventory.total = ''; } } function changeQty(inventory) { - inventory.total = ((vm.vatSettings.applyTax ? inventory.amount : inventory.rate) * inventory.qty); - calculateCost(); + inventory.total = (inventory.amount * inventory.qty); + calculate(); } function inventoryQuerySearch() { @@ -674,13 +998,13 @@ function success(res) { vm.inventories = res; addExistingInventories(existingInventories); - getVatSettings(); + getInventoryTax(); } function failure(err) { vm.inventories = []; addExistingInventories(existingInventories); - getVatSettings(); + getInventoryTax(); } } @@ -697,16 +1021,22 @@ if (found.length == 1) { found[0].checked = true; found[0].rate = inventory.rate; - found[0].amount = inventory.rate; + found[0].amount = (inventory.amount) ? inventory.amount : inventory.rate; found[0].qty = inventory.qty; + found[0].orgcost = inventory.orgcost; + found[0].vendor = inventory.vendor; + found[0].purchasedate = inventory.purchasedate; vm.selectedInventories.push(found[0]); } else { vm.inventories.push({ name: inventory.name, rate: inventory.rate, - amount: inventory.rate, + amount: (inventory.amount) ? inventory.amount : inventory.rate, qty: inventory.qty, - checked: true + checked: true, + orgcost: inventory.orgcost, + vendor: inventory.vendor, + purchasedate: inventory.purchasedate }); vm.selectedInventories.push(vm.inventories[vm.inventories.length - 1]); } @@ -714,24 +1044,26 @@ } } - function getVatSettings() { - amServices.getVatSettings().then(success).catch(failure); + function getInventoryTax() { + amServices.getInventoryTax().then(success).catch(failure); function success(res) { - vm.vatSettings = res; - vm.orgApplyVat = res.applyTax; - if (vm.service.vat != undefined) { - vm.vatSettings.applyTax = vm.service.vat.applyTax; - vm.vatSettings.tax = vm.service.vat.tax; - if (!res.applyTax) - vm.orgApplyVat = vm.service.vat.applyTax; - vm.vatSettings.inclusive = (vm.service.vat.taxIncType == 'inclusive') ? true : false; + res.forEach(iterateTaxes); + OnTaxEnabledChange(); + + function iterateTaxes(tax) { + tax.tax = 0; + tax.isTaxApplied = false; + var found = $filter('filter')(vm.taxSettings, { + name: tax.name + }, true); + + if (found.length == 0) + vm.taxSettings.push(tax); } - changeVat(); } function failure(err) { - vm.vatSettings = {}; vm.inventories.forEach(iterateInventories); function iterateInventories(inventory) { @@ -759,34 +1091,46 @@ } function changeInventoryRate(inventory, force) { - if (vm.vatSettings.applyTax) { - if (vm.vatSettings.inclusive) { - inventory.rate = (inventory.amount * 100) / (vm.vatSettings.tax + 100); - inventory.tax = (inventory.rate * vm.vatSettings.tax / 100); - } else { - if (!inventory.rate) - inventory.rate = inventory.amount; - inventory.tax = (inventory.rate * vm.vatSettings.tax / 100); - inventory.amount = inventory.rate + inventory.tax; - } - } else if (force) { - if (vm.vatSettings.inclusive) - inventory.rate = inventory.amount; - else - inventory.amount = inventory.rate; - } else - inventory.rate = inventory.amount; + var taxable = inventory.amount; + inventory.tax = {}; + vm.taxSettings.forEach(iterateTaxes); + inventory.rate = taxable; changeQty(inventory); - calculateCost(); + calculate(); + + function iterateTaxes(tax) { + if (!tax.isForInventory) + return; + if (tax.isTaxApplied) { + if (tax.inclusive) { + var temptax = 0; + inventory.rate = (taxable * 100) / (tax.percent + 100); + temptax = (inventory.rate * tax.percent / 100); + inventory.tax[tax.name] = temptax; + taxable = inventory.rate; + } else { + var temptax = 0; + temptax = (taxable * tax.percent / 100); + inventory.tax[tax.name] = temptax; + } + } + } } function convertPbToTitleCase() { vm.problem.details = utils.autoCapitalizeWord(vm.problem.details); } - function OnServiceTaxEnabledChange() { + function OnTaxEnabledChange() { vm.service.problems.forEach(iterateProblems); + changeProblemRate(vm.problem, true); calculatePackageTax(); + vm.inventories.forEach(iterateInventories); + changeInventoryRate(vm.inventory, true); + + function iterateInventories(inventory) { + changeInventoryRate(inventory, true); + } function iterateProblems(problem) { changeProblemRate(problem, true); @@ -804,57 +1148,52 @@ } function changeProblemRate(problem, force) { - if (vm.sTaxSettings.applyTax) { - if (vm.sTaxSettings.inclusive) { - if (!problem.amount) { - var r = parseFloat(problem.rate) - problem.amount = Math.round(r + (r * vm.sTaxSettings.tax / 100)); + var taxable = problem.amount; + problem.tax = {}; + vm.taxSettings.forEach(iterateTaxes); + problem.rate = parseFloat(taxable); + calculate(); + + function iterateTaxes(tax) { + if (!tax.isForTreatments) + return; + if (tax.isTaxApplied) { + if (tax.inclusive) { + var temptax = 0; + problem.rate = (taxable * 100) / (tax.percent + 100); + temptax = (problem.rate * tax.percent / 100); + problem.tax[tax.name] = temptax; + taxable = problem.rate; + } else { + var temptax = 0; + temptax = (taxable * tax.percent / 100); + problem.tax[tax.name] = temptax; } - problem.rate = (problem.amount * 100) / (vm.sTaxSettings.tax + 100); - problem.tax = (problem.rate * vm.sTaxSettings.tax / 100); - } else { - if (!problem.rate) - problem.rate = problem.amount; - problem.tax = (problem.rate * vm.sTaxSettings.tax / 100); - problem.amount = problem.rate + problem.tax; } - } else if (force) { - if (vm.sTaxSettings.inclusive) { - if (!problem.amount) - problem.amount = parseFloat(problem.rate); - problem.rate = problem.amount; - } else - problem.amount = problem.rate; - } else - problem.rate = problem.amount; - calculateCost(); + } } - function getServiceTaxSettings() { - amServices.getServiceTaxSettings().then(success).catch(failure); + function getTreatmentsTax() { + amServices.getTreatmentsTax().then(success).catch(failure); function success(res) { - vm.sTaxSettings = res; - vm.orgApplyTax = res.applyTax; - if (vm.service.serviceTax != undefined) { - vm.sTaxSettings.applyTax = vm.service.serviceTax.applyTax; - vm.sTaxSettings.tax = vm.service.serviceTax.tax; - if (!res.applyTax) - vm.orgApplyTax = vm.service.serviceTax.applyTax; - vm.sTaxSettings.inclusive = (vm.service.serviceTax.taxIncType == 'inclusive') ? true : false; - } - vm.service.problems.forEach(iterateProblems); - changeServiceTax(); - OnServiceTaxEnabledChange(); + res.forEach(iterateTaxes); + OnTaxEnabledChange(); + + function iterateTaxes(tax) { + tax.tax = 0; + tax.isTaxApplied = false; + var found = $filter('filter')(vm.taxSettings, { + name: tax.name + }, true); - function iterateProblems(problem) { - if (problem.checked) - delete problem.amount; + if (found.length == 0) + vm.taxSettings.push(tax); } } function failure(err) { - vm.sTaxSettings = {}; + // do nothing } } @@ -880,8 +1219,7 @@ case 'customers.edit.services': transitState = 'restricted.customers.edit'; transitParams = { - id: $state.params.userId, - openTab: 'services' + id: $state.params.userId } break; } @@ -906,7 +1244,7 @@ $mdDialog.show({ controller: 'amCtrlMeD', controllerAs: 'vm', - templateUrl: 'app/components/services/service_membership.edit-template.html', + templateUrl: 'app/components/services/tmpl/dialog_membership.edit-template.html', parent: angular.element(document.body), targetEvent: event, locals: { @@ -1113,7 +1451,7 @@ var total = 0; package.selectedTreatments.forEach(it); package.total = total; - calculateCost(); + calculate(); return total; function it(t) { @@ -1121,23 +1459,29 @@ } } - function changeTreatmentTax(treatment, force) { + function changeTreatmentTax(problem, force) { var cvt = vm.vehicle.type.toLowerCase().replace(' ', '-'); - if (vm.sTaxSettings.applyTax) { - if (treatment.tax == undefined) - treatment.tax = {}; - if (vm.sTaxSettings.inclusive) { - treatment.rate[cvt] = (treatment.amount[cvt] * 100) / (vm.sTaxSettings.tax + 100); - treatment.tax[cvt] = (treatment.rate[cvt] * vm.sTaxSettings.tax / 100); - } else { - treatment.tax[cvt] = (treatment.rate[cvt] * vm.sTaxSettings.tax / 100); - treatment.amount[cvt] = treatment.rate[cvt] + treatment.tax[cvt]; + var taxable = problem.amount[cvt]; + problem.tax = {}; + vm.taxSettings.forEach(iterateTaxes); + problem.rate[cvt] = parseFloat(taxable); + + function iterateTaxes(tax) { + if (!tax.isForTreatments) + return; + if (tax.isTaxApplied) { + if (tax.inclusive) { + var temptax = 0; + problem.rate[cvt] = (taxable * 100) / (tax.percent + 100); + temptax = (problem.rate[cvt] * tax.percent / 100); + problem.tax[tax.name] = temptax; + taxable = problem.rate[cvt]; + } else { + var temptax = 0; + temptax = (taxable * tax.percent / 100); + problem.tax[tax.name] = temptax; + } } - } else if (force) { - if (vm.sTaxSettings.inclusive) - treatment.rate[cvt] = treatment.amount[cvt]; - else - treatment.amount[cvt] = treatment.rate[cvt]; } } @@ -1202,19 +1546,23 @@ function success(res) { autofillVehicle = true; vm.user.id = $state.params.userId; - vm.user.name = res.name; + vm.user.name = (res.name == 'Anonymous') ? '' : res.name; vm.user.email = res.email; vm.user.mobile = res.mobile; + userMobile = res.mobile; vm.user.address = res.address; if (res.memberships) Object.keys(res.memberships).forEach(iterateMemberships); vm.vehicle.id = $state.params.vehicleId; - vm.vehicle.reg = res.vehicle.reg; + vm.vehicle.reg = (res.vehicle.reg == 'Vehicle') ? '' : res.vehicle.reg; + orgVehicle vm.vehicle.manuf = res.vehicle.manuf; vm.vehicle.model = res.vehicle.model; vm.vehicle.type = res.vehicle.type; if (res.vehicle.service.packages) { vm.serviceType = vm.serviceTypeList[1]; + if (Object.keys(res.vehicle.service.packages).length > 0) + isPackageAvailInService = true; Object.keys(res.vehicle.service.packages).forEach(iteratePackages); } if (res.vehicle.service.memberships) { @@ -1234,23 +1582,19 @@ vm.service.cost = res.vehicle.service.cost; vm.service.odo = res.vehicle.service.odo; vm.service.status = res.vehicle.service.status; + if (res.vehicle.service.partialpayment) + vm.service.partialpayment = res.vehicle.service.partialpayment; vm.service.state = (res.vehicle.service.state == undefined) ? vm.serviceStateList[2] : res.vehicle.service.state; vm.label_invoice = (vm.service.state == vm.serviceStateList[2]) ? 'Invoice' : 'Send'; - if (res.vehicle.service.discount) { - vm.isDiscountApplied = true; - isDiscountByPercent = false; - vm.discountPercentage = parseFloat(res.vehicle.service.discount.percent); - vm.discountValue = parseFloat(res.vehicle.service.discount.amount); - } if (res.vehicle.service.roundoff) { vm.isRoundOffVal = true; isManualRoundOff = vm.isRoundOffVal; vm.roundedOffVal = parseFloat(res.vehicle.service.roundoff); } - if (res.vehicle.service.serviceTax != undefined) - vm.service.serviceTax = res.vehicle.service.serviceTax; - if (res.vehicle.service.vat != undefined) - vm.service.vat = res.vehicle.service.vat; + if (res.vehicle.service.taxes) { + vm.taxSettings = []; + Object.keys(res.vehicle.service.taxes).forEach(iterateTaxes); + } vm.servicestatus = (res.vehicle.service.status == 'paid'); getRegularTreatments(res.vehicle.service.problems); getInventories(res.vehicle.service.inventories); @@ -1269,6 +1613,29 @@ getLastJobCardNo(); getLastEstimateNo(); getLastInvoiceNo(); + if (res.vehicle.service.discount) { + vm.isDiscountApplied = true; + if (res.vehicle.service.discount.amount) { + vm.discount.total = res.vehicle.service.discount.amount; + calculateDiscount(); + } else { + vm.discount = res.vehicle.service.discount; + } + } + + function iterateTaxes(tax) { + var t = res.vehicle.service.taxes[tax]; + + vm.taxSettings.push({ + tax: t.tax, + inclusive: (t.type == "inclusive"), + isTaxApplied: t.isTaxApplied, + isForTreatments: t.isForTreatments, + isForInventory: t.isForInventory, + percent: t.percent, + name: tax + }); + } function iterateMemberships(membership) { res.memberships[membership].name = membership; @@ -1431,27 +1798,37 @@ vm.service.problems.forEach(iterateProblem); iterateProblem(vm.problem); calculatePackageTax(); - calculateCost(); + calculate(); function iterateProblem(problem) { var found = $filter('filter')(vm.treatments, { name: problem.details }); if (found.length == 1) { - var rate = found[0].rate[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')]; - if (vm.sTaxSettings.applyTax) { - if (vm.sTaxSettings.inclusive) { - problem.amount = (rate == '' || rate == undefined ? problem.amount : rate); - problem.rate = (problem.amount * 100) / (vm.sTaxSettings.tax + 100); - problem.tax = (problem.rate * vm.sTaxSettings.tax / 100); - } else { - problem.rate = (rate == '' || rate == undefined ? problem.rate : rate); - problem.tax = (problem.rate * vm.sTaxSettings.tax / 100); - problem.amount = problem.rate + problem.tax; + problem.amount = found[0].rate[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')]; + var taxable = problem.amount; + problem.tax = {}; + vm.taxSettings.forEach(iterateTaxes); + problem.rate = parseFloat(taxable); + if (found[0].orgcost && found[0].orgcost[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')]) + problem.orgcost = found[0].orgcost[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')]; + + function iterateTaxes(tax) { + if (!tax.isForTreatments) + return; + if (tax.isTaxApplied) { + if (tax.inclusive) { + var temptax = 0; + problem.rate = (taxable * 100) / (tax.percent + 100); + temptax = (problem.rate * tax.percent / 100); + problem.tax[tax.name] = temptax; + taxable = problem.rate; + } else { + var temptax = 0; + temptax = (taxable * tax.percent / 100); + problem.tax[tax.name] = temptax; + } } - } else { - problem.rate = (rate == '' || rate == undefined ? problem.rate : rate); - problem.amount = (rate == '' || rate == undefined ? problem.rate : rate); } } } @@ -1482,7 +1859,7 @@ function loadTreatmentIntoProblems(existingProblems) { vm.treatments.forEach(iterateTreatment); existingProblems.forEach(iterateProblem); - getServiceTaxSettings(); + getTreatmentsTax(); function iterateProblem(problem) { var found = $filter('filter')(vm.service.problems, { @@ -1491,28 +1868,33 @@ if (found.length == 1) { found[0].checked = true; found[0].rate = problem.rate; - found[0].amount = Math.round(problem.rate); + found[0].amount = (problem.amount) ? problem.amount : Math.round(problem.rate); found[0].tax = problem.tax; + found[0].orgcost = problem.orgcost; vm.selectedProblems.push(found[0]); } else { vm.service.problems.push({ details: problem.details, rate: problem.rate, - amount: Math.round(problem.rate), + amount: (problem.amount) ? problem.amount : Math.round(problem.rate), tax: problem.tax, - checked: true + checked: true, + orgcost: problem.orgcost }); vm.selectedProblems.push(vm.service.problems[vm.service.problems.length - 1]); } } function iterateTreatment(treatment) { - vm.service.problems.push({ + var p = { details: treatment.name, rate: treatment.rate[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')], - amount: treatment.rate[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')], + amount: (treatment.amount) ? treatment.amount : treatment.rate[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')], checked: false - }); + }; + if (treatment.orgcost && treatment.orgcost[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')]) + p.orgcost = treatment.orgcost[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')]; + vm.service.problems.push(p); } } @@ -1545,11 +1927,55 @@ } function populateRoD() { + var isTreatmentTaxed = false, isInventoryTaxed = false, treatmentTaxPercent = 0, inventoryTaxPercent = 0; + vm.taxSettings.forEach(iterateTaxes); if (vm.isDiscountApplied) { - vm.discountValue = serviceTcDc - vm.service.cost; - calculateDiscount(false); + var noTerminate = true, tp = 0.5, ip = 1 - tp; + if (treatmentTotal == 0) { + tp = 0; + ip = 1; + } else if (inventoryTotal == 0) { + ip = 0; + tp = 1; + } + while (noTerminate) { + var xt = (tp * vm.service.cost * 100) / (treatmentTaxPercent + 100); + if (treatmentTotal < xt) { + tp -= 0.1; + ip = 1 - tp; + if (tp < 0) + break; + continue; + } + vm.discount.treatment = treatmentTotal - xt; + var xi = (ip * vm.service.cost * 100) / (inventoryTaxPercent + 100); + if (inventoryTotal < xi) { + ip -= 0.1; + tp = 1 - ip; + if (ip < 0) + break; + continue; + } + vm.discount.part = inventoryTotal - xi; + noTerminate = false; + } + + vm.discount.total = parseFloat(vm.discount.treatment) + parseFloat(vm.discount.part); + vm.discount.total = (vm.discount.total % 1 != 0) ? parseFloat(vm.discount.total.toFixed(2)) : parseInt(vm.discount.total); + calculate(); } else if (vm.isRoundOffVal) vm.roundedOffVal = vm.service.cost - serviceTcRo; + + function iterateTaxes(tax) { + if (tax.isTaxApplied && tax.isForTreatments) { + isTreatmentTaxed = true; + treatmentTaxPercent += tax.percent; + } + if (tax.isTaxApplied && tax.isForInventory) { + isInventoryTaxed = true; + inventoryTaxPercent += tax.percent; + } + } } function calculateRoundOff(isRoundOffManual) { @@ -1559,20 +1985,54 @@ vm.roundedOffVal = (totalCost - ot); vm.roundedOffVal = (vm.roundedOffVal % 1 != 0) ? parseFloat(vm.roundedOffVal.toFixed(2)) : parseInt(vm.roundedOffVal); } - calculateCost(); + calculate(); } function calculateDiscount(isDiscountByPercent) { - var totalCost = vm.service.cost; - if (isDiscountByPercent) { - vm.discountValue = totalCost * parseFloat(vm.discountPercentage) / 100; - vm.discountValue = (isNaN(vm.discountValue) || vm.discountValue == null) ? '' : vm.discountValue; - vm.discountValue = (vm.discountValue % 1 != 0) ? parseFloat(vm.discountValue.toFixed(2)) : parseInt(vm.discountValue); - } else if (vm.discountValue != '') { - vm.discountPercentage = 100 * parseFloat(vm.discountValue) / totalCost; - vm.discountPercentage = (vm.discountPercentage % 1 != 0) ? parseFloat(vm.discountPercentage.toFixed(1)) : parseInt(vm.discountPercentage); + var treatmentLength = (vm.selectedProblems.length ? vm.selectedProblems.length : 0) + ((parseFloat(vm.problem.amount) > 0) ? 1 : 0); + var partLength = (vm.selectedInventories.length ? vm.selectedInventories.length : 0) + ((parseFloat(vm.inventory.amount) > 0) ? 1 : 0); + if (partLength > 0) { + var dv2 = vm.discount.total * 0.5; + var partValue = (dv2 > inventoryTotal) ? inventoryTotal : dv2; + vm.discount.part = (treatmentLength > 0) ? partValue : vm.discount.total; + } else + vm.discount.part = 0; + if (treatmentLength > 0) { + var treatmentValue = vm.discount.total - vm.discount.part; + if (treatmentValue > treatmentTotal) { + treatmentValue = treatmentTotal; + vm.discount.part = vm.discount.total - treatmentValue; + } + vm.discount.treatment = (partLength > 0) ? treatmentValue : vm.discount.total; + } else + vm.discount.treatment = 0; + calculate(); + } + + function calculateTotalDiscount() { + if (!vm.isDiscountApplied) + return; + var isTreatmentTaxed = false, isInventoryTaxed = false, treatmentTaxPercent = 0, inventoryTaxPercent = 0; + dTreatment = treatmentTotal - vm.discount.treatment; + dInventory = inventoryTotal - vm.discount.part; + + vm.taxSettings.forEach(iterateTaxes); + + dTreatmentTax = (isTreatmentTaxed) ? (dTreatment * treatmentTaxPercent / 100) : 0; + dInventoryTax = (isInventoryTaxed) ? (dInventory * inventoryTaxPercent / 100) : 0; + dTreatmentTax = (dTreatmentTax % 1 != 0) ? parseFloat(dTreatmentTax.toFixed(2)) : dTreatmentTax; + dInventoryTax = (dInventoryTax % 1 != 0) ? parseFloat(dInventoryTax.toFixed(2)) : dInventoryTax; + + function iterateTaxes(tax) { + if (tax.isTaxApplied && tax.isForTreatments) { + isTreatmentTaxed = true; + treatmentTaxPercent += tax.percent; + } + if (tax.isTaxApplied && tax.isForInventory) { + isInventoryTaxed = true; + inventoryTaxPercent += tax.percent; + } } - calculateCost(); } function changeForceStopCalCost(bool) { @@ -1582,18 +2042,11 @@ function calculateCost(isDbp) { if (forceStopCalCost) return; - var totalCost = 0; - vm.service.problems.forEach(iterateProblem); - iterateProblem(vm.problem); - vm.selectedInventories.forEach(iterateInventories); - iterateInventories(vm.inventory); - if (vm.serviceType == vm.serviceTypeList[1]) { - vm.packages.forEach(iteratePackages); - } + var totalCost = 0, taxes = 0; + var discountedSubtotal = parseFloat(dTreatment + dTreatmentTax) + parseFloat(dInventory + dInventoryTax); + vm.taxSettings.forEach(iterateTaxes); + totalCost = (vm.isDiscountApplied && (vm.discount.total > 0)) ? Math.round(discountedSubtotal) : (parseFloat(vm.service.subtotal) + parseFloat(taxes)); serviceTcDc = totalCost; - if (vm.isDiscountApplied) { - totalCost = vm.isDiscountApplied && !isNaN(vm.discountValue) ? totalCost - vm.discountValue : totalCost; - } serviceTcRo = totalCost; if (vm.isRoundOffVal) { totalCost += parseFloat(vm.roundedOffVal); @@ -1601,85 +2054,52 @@ } totalCost = (totalCost % 1 != 0) ? parseFloat(totalCost.toFixed(2)) : totalCost; totalCost = (totalCost % 1).toFixed(2) == 0.00 ? Math.round(totalCost) : totalCost; + totalCost = (totalCost % 1).toFixed(2) == 0.99 ? Math.round(totalCost) : totalCost; vm.service.cost = parseFloat(totalCost); - function iterateProblem(element) { - totalCost += parseFloat(element.amount ? (element.amount * (element.checked ? 1 : 0)) : 0); - } - - function iterateInventories(element) { - totalCost += parseFloat(element.total ? (element.total * (element.checked ? 1 : 0)) : 0); - } - - function iteratePackages(package) { - if (!package.checked) - return; - package.selectedTreatments.forEach(ipt); - } - - function ipt(treatment) { - totalCost += treatment.amount[vm.vehicle.type.toLowerCase().replace(' ', '-')]; - } - } - - function calculateTax() { - var totalTax = 0.0; - vm.service.problems.forEach(iterateProblems); - iterateProblems(vm.problem); - if (vm.serviceType == vm.serviceTypeList[1]) - vm.packages.forEach(iteratePackages); - totalTax = (totalTax % 1 != 0) ? totalTax.toFixed(2) : parseInt(totalTax); - return totalTax; - - function iterateProblems(problem) { - if ((vm.sTaxSettings && !vm.sTaxSettings.applyTax) || !problem.tax || !problem.checked) - return; - totalTax += parseFloat(problem.tax); - } - - function iteratePackages(package) { - if (!package.checked) - return; - package.selectedTreatments.forEach(ipt); - } - - function ipt(treatment) { - if ((vm.sTaxSettings && !vm.sTaxSettings.applyTax) || !treatment.tax) - return; - totalTax += parseFloat(treatment.tax[vm.vehicle.type.toLowerCase().replace(' ', '-')]); + function iterateTaxes(tax) { + taxes += tax.tax; } } function finalizeNewProblem(isFromAutocomplete) { vm.problem.details = vm.problem.details.trim(); + vm.problemFocusIndex = -1; if (vm.problem.details != '') { if (isFromAutocomplete) updateTreatmentDetails(); var found = $filter('filter')(vm.service.problems, { details: vm.problem.details }, true); + var foundExisting = $filter('filter')(vm.selectedProblems, { + details: vm.problem.details + }, true); if (found.length == 1) { found[0].checked = true; - found[0].rate = (vm.sTaxSettings && vm.sTaxSettings.applyTax) ? vm.problem.rate : vm.problem.amount; + found[0].rate = vm.problem.rate; found[0].tax = vm.problem.tax; found[0].amount = vm.problem.amount; - vm.selectedProblems.push(found[0]); + if (foundExisting.length == 0) + vm.selectedProblems.push(found[0]); + else + foundExisting[0] = found[0]; } else { vm.service.problems.push({ details: vm.problem.details, - rate: (vm.sTaxSettings && vm.sTaxSettings.applyTax) ? vm.problem.rate : vm.problem.amount, + rate: vm.problem.rate, tax: vm.problem.tax, amount: vm.problem.amount, checked: true }); vm.selectedProblems.push(vm.service.problems[vm.service.problems.length - 1]); } - calculateCost(); vm.problem.details = ''; - vm.problem.amount = ''; - vm.problem.rate = ''; - if (isFromAutocomplete) - vm.problemFocusIndex = vm.selectedProblems.length - 1; + vm.problem.amount = 0; + vm.problem.rate = 0; + vm.problem.tax = {}; + calculate(); + if (isFromAutocomplete || foundExisting.length != 0) + vm.problemFocusIndex = (foundExisting.length == 0) ? vm.selectedProblems.length - 1 : vm.selectedProblems.indexOf(foundExisting[0]); else setTimeout(focusNewProblemDetails, 300); } @@ -1697,46 +2117,53 @@ if (found.length == 1) { var rate = found[0].rate[angular.lowercase(vm.vehicle.type).replace(/\s/g, '-')]; vm.problem.amount = (rate == '' || rate == undefined ? vm.problem.amount : rate); - if (vm.sTaxSettings.applyTax) { - if (vm.sTaxSettings.inclusive) { - vm.problem.rate = (vm.problem.amount * 100) / (vm.sTaxSettings.tax + 100); - vm.problem.tax = (vm.problem.rate * vm.sTaxSettings.tax / 100); - } else { - vm.problem.rate = (rate == '' || rate == undefined ? vm.problem.rate : rate); - vm.problem.tax = (vm.problem.rate * vm.sTaxSettings.tax / 100); - vm.problem.amount = vm.problem.rate + vm.problem.tax; + var taxable = vm.problem.amount; + vm.problem.tax = {}; + vm.taxSettings.forEach(iterateTaxes); + vm.problem.rate = taxable; + vm.problem.checked = true; + calculate(); + + function iterateTaxes(tax) { + if (!tax.isForTreatments) + return; + if (tax.isTaxApplied) { + if (tax.inclusive) { + var temptax = 0; + vm.problem.rate = (taxable * 100) / (tax.percent + 100); + temptax = (vm.problem.rate * tax.percent / 100); + vm.problem.tax[tax.name] = temptax; + taxable = vm.problem.rate; + } else { + var temptax = 0; + temptax = (taxable * tax.percent / 100); + vm.problem.tax[tax.name] = temptax; + } } - } else { - if (vm.sTaxSettings.inclusive) - vm.problem.rate = (rate == '' || rate == undefined ? vm.problem.rate : rate); - else - vm.problem.amount = (rate == '' || rate == undefined ? vm.problem.amount : rate); } - vm.problem.checked = true; - calculateCost(); } } else { vm.problem.rate = ''; - vm.problem.tax = 0; + vm.problem.tax = {}; vm.problem.amount = ''; vm.problem.checked = false; } } function validate() { + if (vm.user.name == '') { + vm.user.name = 'Anonymous'; + } var isVehicleBlank = (vm.vehicle.manuf == undefined || vm.vehicle.manuf == '') && (vm.vehicle.model == undefined || vm.vehicle.model == '') && (vm.vehicle.reg == undefined || vm.vehicle.reg == ''); if (isVehicleBlank) { - changeVehicleInfoState(true); - utils.showSimpleToast('Please Enter At Least One Vehicle Detail'); - return false; + vm.vehicle.reg = 'Vehicle'; } - return true; } // save to database function save(redirect) { - if (!validate()) return; + validate(); switch (vm.serviceType) { case vm.serviceTypeList[0]: if (checkBasic() == false) { @@ -1759,14 +2186,10 @@ } vm.service.problems = vm.selectedProblems; vm.user.memberships = vm.membershipChips; - switch (vm.serviceType) { - case vm.serviceTypeList[1]: - vm.packages.forEach(addPkToService); - break; - case vm.serviceTypeList[2]: - vm.membershipChips.forEach(addMsToService); - break; - } + if (vm.packages) + vm.packages.forEach(addPkToService); + if (vm.membershipChips) + vm.membershipChips.forEach(addMsToService); vm.service.status = vm.servicestatus ? 'paid' : 'due'; vm.service.date = moment(vm.service.date).format(); if (vm.isNextDueService) @@ -1776,29 +2199,13 @@ if (vm.problem.details) vm.service.problems.push(vm.problem); vm.service.problems.forEach(iterateProblems); - if (vm.isDiscountApplied) { - vm.service['discount'] = { - percent: parseFloat(vm.discountPercentage), - amount: parseFloat(vm.discountValue) - } - } + if (vm.isDiscountApplied) + vm.service.discount = vm.discount; if (vm.isRoundOffVal) { vm.service['roundoff'] = vm.roundedOffVal; } - if (vm.sTaxSettings != undefined) { - vm.service.serviceTax = { - applyTax: vm.sTaxSettings.applyTax, - taxIncType: (vm.sTaxSettings.inclusive) ? 'inclusive' : 'exclusive', - tax: vm.sTaxSettings.tax - }; - } - if (vm.vatSettings != undefined) { - vm.service.vat = { - applyTax: vm.vatSettings.applyTax, - taxIncType: (vm.vatSettings.inclusive) ? 'inclusive' : 'exclusive', - tax: vm.vatSettings.tax - } - } + vm.service.taxes = {}; + vm.taxSettings.forEach(iterateTaxes); if (vm.inventory.name) vm.selectedInventories.push(vm.inventory); vm.selectedInventories.forEach(iterateInventories); @@ -1830,6 +2237,17 @@ } amServices.saveService(vm.user, vm.vehicle, vm.service, options).then(success).catch(failure); + function iterateTaxes(tax) { + vm.service.taxes[tax.name] = { + tax: tax.tax, + type: (tax.inclusive) ? "inclusive" : "exclusive", + isTaxApplied: tax.isTaxApplied, + isForTreatments: tax.isForTreatments, + isForInventory: tax.isForInventory, + percent: tax.percent + } + } + function addMsToService(membership) { if (!membership.checked) return; @@ -1855,19 +2273,13 @@ } function iterateProblems(problem) { - if (!vm.sTaxSettings || (vm.sTaxSettings && !vm.sTaxSettings.applyTax && vm.sTaxSettings.inclusive)) - problem.rate = problem.amount; delete problem.checked; - delete problem['amount']; delete problem['$$hashKey']; } function iterateInventories(inventory) { - if (!vm.vatSettings || (vm.vatSettings && vm.vatSettings.applyTax && vm.vatSettings.inclusive)) - inventory.rate = inventory.amount; delete inventory.checked; delete inventory['total']; - delete inventory['amount']; delete inventory['$$hashKey']; } @@ -1928,145 +2340,8 @@ // !(save successfull) function failure(err) { - console.info(err); utils.showSimpleToast('Failed to update. Please Try Again!'); } } } - - function MembershipEditDialogController($mdDialog, $filter, membership, treatments) { - var editMsVm = this; - - editMsVm.treatment = { - details: '', - rate: '' - }; - editMsVm.membership = { - name: membership.name, - occurences: membership.occurences, - duration: membership.duration - }; - editMsVm.selectedTreatments = []; - editMsVm.treatments = treatments; - editMsVm.confirmDialog = confirmDialog; - editMsVm.treatmentQuerySearch = treatmentQuerySearch; - editMsVm.finalizeNewTreatment = finalizeNewTreatment; - editMsVm.updateTreatmentDetails = updateTreatmentDetails; - - loadDefaultOccDur(); - loadMemberships(); - - function loadMemberships() { - membership.treatments.forEach(iterateTreatments); - - function iterateTreatments(treatment) { - var found = $filter('filter')(editMsVm.treatments, { - name: treatment.name - }, true); - - if (found.length == 1) { - found[0].given.occurences = treatment.given.occurences; - found[0].given.duration = treatment.given.duration; - found[0].used.occurences = treatment.used.occurences; - found[0].used.duration = treatment.used.duration; - editMsVm.selectedTreatments.push(found[0]); - } else { - editMsVm.treatments.push(treatment); - editMsVm.selectedTreatments.push(editMsVm.treatments[editMsVm.treatments.length - 1]); - } - } - } - - function updateTreatmentDetails() { - var found = $filter('filter')(editMsVm.treatments, { - name: editMsVm.treatment.details - }); - if (found.length == 1 && found[0].name == editMsVm.treatment.details) { - editMsVm.treatment.occurences = found[0].given.occurences; - editMsVm.treatment.duration = found[0].given.duration; - } else { - editMsVm.treatment.occurences = editMsVm.membership.occurences - editMsVm.treatment.duration = editMsVm.membership.duration; - } - } - - // query search for treatments [autocomplete] - function treatmentQuerySearch() { - var tracker = $q.defer(); - var results = (editMsVm.treatment.details ? editMsVm.treatments.filter(createFilterForTreatments(editMsVm.treatment.details)) : editMsVm.treatments); - - return results; - } - - // create filter for users' query list - function createFilterForTreatments(query) { - var lcQuery = angular.lowercase(query); - return function filterFn(item) { - return (angular.lowercase(item.name).indexOf(lcQuery) === 0); - } - } - - function finalizeNewTreatment(btnClicked) { - editMsVm.treatment.details = editMsVm.treatment.details.trim(); - if (editMsVm.treatment.details != '') { - var found = $filter('filter')(editMsVm.treatments, { - name: editMsVm.treatment.details - }, true); - if (found.length == 1 && found[0].name == editMsVm.treatment.details) { - found[0].checked = true; - found[0].rate = editMsVm.treatment.rate; - found[0].duration = editMsVm.treatment.duration; - found[0].occurences = editMsVm.treatment.occurences; - editMsVm.selectedTreatments.push(found[0]); - } else { - editMsVm.treatments.push({ - name: editMsVm.treatment.details, - duration: editMsVm.treatment.duration, - occurences: editMsVm.treatment.occurences, - checked: true - }); - editMsVm.selectedTreatments.push(editMsVm.treatments[editMsVm.treatments.length - 1]); - } - editMsVm.treatment.details = ''; - editMsVm.treatment.occurences = editMsVm.membership.occurences; - editMsVm.treatment.duration = editMsVm.membership.duration; - angular.element('#new-treatment-details').find('input')[0].focus(); - } - if (btnClicked) - angular.element('#new-treatment-details').find('input')[0].focus(); - } - - function loadDefaultOccDur() { - editMsVm.treatments.forEach(iterateTreatments); - - function iterateTreatments(treatment) { - if (!treatment.given) { - treatment.given = { - occurences: membership.occurences, - duration: membership.duration - } - } - if (!treatment.used) { - treatment.used = { - occurences: 0, - duration: 0 - } - } - } - } - - function confirmDialog() { - membership.treatments = editMsVm.selectedTreatments; - membership.selectedTreatments = []; - membership.treatments.forEach(makeSelectedTreatments); - $mdDialog.hide(); - - function makeSelectedTreatments(treatment) { - if (membership.calculateTOccurenceLeft(treatment) != 0 && membership.calculateTDurationLeft(treatment) != 0) { - treatment.checked = true; - membership.selectedTreatments.push(treatment); - } - } - } - } })(); \ No newline at end of file diff --git a/src/app/components/services/services-viewall.controller.js b/src/app/components/services/services-viewall.controller.js index 2d8ac03c..0ca56d91 100644 --- a/src/app/components/services/services-viewall.controller.js +++ b/src/app/components/services/services-viewall.controller.js @@ -2,7 +2,7 @@ * Controller for View Services module * @author ndkcha * @since 0.4.1 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -12,9 +12,9 @@ angular.module('automintApp').controller('amCtrlSeRA', ServiceViewAllController); - ServiceViewAllController.$inject = ['$scope', '$state', '$filter', '$timeout', '$mdDialog', 'utils', 'amServices']; + ServiceViewAllController.$inject = ['$rootScope', '$scope', '$state', '$filter', '$timeout', '$mdDialog', 'utils', 'amServices']; - function ServiceViewAllController($scope, $state, $filter, $timeout, $mdDialog, utils, amServices) { + function ServiceViewAllController($rootScope, $scope, $state, $filter, $timeout, $mdDialog, utils, amServices) { // initialize view model var vm = this, queryChangedPromise, cacheLoadTimeout = false, isDataLoaded = false, isPreferencesLoaded = false, filterRange, isFirstTimeWsq = true; @@ -32,6 +32,7 @@ vm.serviceStateList = ['Job Card', 'Estimate', 'Bill']; vm.currentTimeSet = []; vm.ddTimeSet = ''; + vm.currencySymbol = "Rs."; // function maps vm.addService = addService; @@ -47,14 +48,39 @@ vm.IsServiceStateEs = IsServiceStateEs; vm.IsServiceStateIv = IsServiceStateIv; vm.openTimeFilter = openTimeFilter; + vm.IsCustomerAnonymous = IsCustomerAnonymous; + vm.IsVehicleAnonymous = IsVehicleAnonymous; // default execution steps $scope.$watch('vm.serviceQuery', watchServiceQuery); + + getCurrencySymbol(); getFilterMonths(processPreferences); initCurrentTimeSet(); + getServices(); // function definitions + function IsVehicleAnonymous(reg) { + return (reg == 'Vehicle'); + } + + function IsCustomerAnonymous(name) { + return (name == 'Anonymous'); + } + + function getCurrencySymbol() { + amServices.getCurrencySymbol().then(success).catch(failure); + + function success(res) { + vm.currencySymbol = res; + } + + function failure(err) { + vm.currencySymbol = "Rs."; + } + } + function openTimeFilter(event) { $mdDialog.show({ controller: 'amCtrlSeTmFl', @@ -92,7 +118,6 @@ function failure(err) { callback.apply(callingFunction, Array.prototype.slice.call(callbackArgs, 1)); - console.info('failed to get filter months'); } } @@ -264,7 +289,6 @@ function failure(err) { isPreferencesLoaded = true; getServices(); - console.warn(err.message); } } @@ -350,7 +374,7 @@ } function ignoreDelete() { - console.info('nope'); + // do nothing } @@ -363,7 +387,6 @@ } function failure(err) { - console.info(err); utils.showSimpleToast('Service can not be deleted at moment. Please Try Again!'); } } diff --git a/src/app/components/services/services.factory.js b/src/app/components/services/services.factory.js index 6beae693..ee6dc7b0 100644 --- a/src/app/components/services/services.factory.js +++ b/src/app/components/services/services.factory.js @@ -2,7 +2,7 @@ * Factory that handles database interactions between services database and controller * @author ndkcha * @since 0.4.1 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -11,9 +11,9 @@ angular.module('automintApp') .factory('amServices', ServicesFactory); - ServicesFactory.$inject = ['$http', '$timeout', '$q', '$log', '$filter', 'utils', '$amRoot', 'constants', 'pdbCustomers', 'pdbCommon', 'pdbConfig', 'pdbCache']; + ServicesFactory.$inject = ['$http', '$timeout', '$q', '$log', '$filter', 'utils', '$rootScope', 'constants', 'pdbMain', 'pdbCache']; - function ServicesFactory($http, $timeout, $q, $log, $filter, utils, $amRoot, constants, pdbCustomers, pdbCommon, pdbConfig, pdbCache) { + function ServicesFactory($http, $timeout, $q, $log, $filter, utils, $rootScope, constants, pdbMain, pdbCache) { // initialize factory variable and function maps var factory = { getManufacturers: getManufacturers, @@ -30,21 +30,101 @@ getLastInvoiceNo: getLastInvoiceNo, getPackages: getPackages, getMemberships: getMemberships, - getServiceTaxSettings: getServiceTaxSettings, getServices: getServices, getInventories: getInventories, - getVatSettings: getVatSettings, getInventoriesSettings: getInventoriesSettings, getLastEstimateNo : getLastEstimateNo, getLastJobCardNo: getLastJobCardNo, getDefaultServiceType: getDefaultServiceType, - getFilterMonths: getFilterMonths + getFilterMonths: getFilterMonths, + getTreatmentsTax: getTreatmentsTax, + getInventoryTax: getInventoryTax, + getCurrencySymbol: getCurrencySymbol } return factory; // function definitions + function getCurrencySymbol() { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); + return tracker.promise; + + function getSettingsObject(res) { + if (res.currency) + tracker.resolve(res.currency); + else + failure('No Currency Symbol Found!'); + } + + function failure(err) { + tracker.reject(err); + } + } + + function getTreatmentsTax() { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObj).catch(failure); + return tracker.promise; + + function getSettingsObj(res) { + var result = []; + if (res.settings && res.settings.tax) + Object.keys(res.settings.tax).forEach(iterateTaxes); + tracker.resolve(result); + + function iterateTaxes(tax) { + var t = res.settings.tax[tax]; + if (t.isForTreatments) { + result.push({ + inclusive: (t.type == "inclusive"), + isTaxApplied: t.isTaxApplied, + isForTreatments: t.isForTreatments, + isForInventory: t.isForInventory, + percent: t.percent, + name: tax + }); + } + } + } + + function failure(err) { + tracker.reject(err); + } + } + + function getInventoryTax() { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObj).catch(failure); + return tracker.promise; + + function getSettingsObj(res) { + var result = []; + if (res.settings && res.settings.tax) + Object.keys(res.settings.tax).forEach(iterateTaxes); + tracker.resolve(result); + + function iterateTaxes(tax) { + var t = res.settings.tax[tax]; + if (t.isForInventory) { + result.push({ + inclusive: (t.type == "inclusive"), + isTaxApplied: t.isTaxApplied, + isForTreatments: t.isForTreatments, + isForInventory: t.isForInventory, + percent: t.percent, + name: tax + }); + } + } + } + + function failure(err) { + tracker.reject(err); + } + } + function getFilterMonths() { var tracker = $q.defer(); pdbCache.get(constants.pdb_cache_views.view_services).then(generateMonthsUsed).catch(failure); @@ -73,13 +153,9 @@ function getDefaultServiceType() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(failure); - } - function getSettingsObject(res) { if (res.settings && res.settings.servicestate) tracker.resolve(res.settings.servicestate); @@ -100,13 +176,9 @@ function getInventoriesSettings() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(configFound).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(configDocFound).catch(failure); return tracker.promise; - function configFound(res) { - pdbConfig.get($amRoot.docIds.settings).then(configDocFound).catch(failure); - } - function configDocFound(res) { if (res.settings && res.settings.inventory) tracker.resolve(res.settings.inventory.displayAsList); @@ -125,53 +197,18 @@ } } - function getVatSettings() { - var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); - return tracker.promise; - - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObj).catch(failure); - } - - function getSettingsObj(res) { - if (res.settings && res.settings.vat) { - tracker.resolve({ - applyTax: res.settings.vat.applyTax, - inclusive: (res.settings.vat.taxIncType == 'inclusive') ? true : false, - tax: res.settings.vat.tax - }); - } else - failure(); - } - - function failure(err) { - if (!err) { - err = { - success: false, - message: 'VAT Settings Not Found!' - } - } - tracker.reject(err); - } - } - function getInventories() { var tracker = $q.defer(); var response = []; - $amRoot.isInventoryId().then(getInventoryDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.inventory).then(getInventoryObj).catch(failure); return tracker.promise; - function getInventoryDoc(res) { - pdbConfig.get($amRoot.docIds.inventory).then(getInventoryObj).catch(failure); - } - function getInventoryObj(res) { Object.keys(res).forEach(iterateInventories); tracker.resolve(response); function iterateInventories(name) { - if (name.match(/\b_id|\b_rev|\bcreator/i) || res[name]._deleted == true) + if (name.match(/\b_id|\b_rev|\bcreator|\bchannel/i) || res[name]._deleted == true) return; var temp = res[name]; temp.name = name; @@ -188,49 +225,13 @@ tracker.reject(err); } } - - function getServiceTaxSettings() { - var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); - return tracker.promise; - - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObj).catch(failure); - } - - function getSettingsObj(res) { - if (res.settings && res.settings.servicetax) { - tracker.resolve({ - applyTax: res.settings.servicetax.applyTax, - inclusive: (res.settings.servicetax.taxIncType == 'inclusive') ? true : false, - tax: res.settings.servicetax.tax - }); - } else - failure(); - } - - function failure(err) { - if (!err) { - err = { - success: false, - message: 'Service Tax Settings Not Found!' - } - } - tracker.reject(err); - } - } // retrieve current treatment settings function getTreatmentSettings() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); return tracker.promise; - // if settings configuration is tracked, fetch corrosponding document - function getSettingsDoc(response) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(failure); - } - // if document call is successfull, return treatment settings if available function getSettingsObject(response) { if (response.settings.treatments) @@ -251,13 +252,9 @@ // retrieve vehicle types from config database function getVehicleTypes() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(failure); - } - function getSettingsObject(res) { if (res.vehicletypes) tracker.resolve(res.vehicletypes); @@ -273,7 +270,7 @@ // return service tree function serviceTree(userId, vehicleId, serviceId) { var tracker = $q.defer(); - pdbCustomers.get(userId).then(getUserObject).catch(failure); + pdbMain.get(userId).then(getUserObject).catch(failure); return tracker.promise; function getUserObject(response) { @@ -334,12 +331,12 @@ // delete service from UI function deleteService(userId, vehicleId, serviceId) { var tracker = $q.defer(); - pdbCustomers.get(userId).then(getUserObject).catch(failure); + pdbMain.get(userId).then(getUserObject).catch(failure); return tracker.promise; function getUserObject(res) { res.user.vehicles[vehicleId].services[serviceId]._deleted = true; - pdbCustomers.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } function success(res) { @@ -394,7 +391,6 @@ } } function failure(err) { - console.log(err); tracker.reject(err); } } @@ -406,13 +402,9 @@ memberships: [], total: 0 } - $amRoot.isTreatmentId().then(getTreatmentsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(getTreatmentObject).catch(failure); return tracker.promise; - function getTreatmentsDoc(res) { - pdbConfig.get($amRoot.docIds.treatment).then(getTreatmentObject).catch(failure); - } - function getTreatmentObject(res) { if (res.memberships) Object.keys(res.memberships).forEach(iterateMemberships); @@ -450,13 +442,9 @@ function getPackages() { var tracker = $q.defer(); var packages = []; - $amRoot.isTreatmentId().then(getConfigDocument).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(getConfigObject).catch(failure); return tracker.promise; - function getConfigDocument(res) { - pdbConfig.get($amRoot.docIds.treatment).then(getConfigObject).catch(failure); - } - function getConfigObject(res) { if (res.packages) Object.keys(res.packages).forEach(iteratePackages); @@ -481,13 +469,9 @@ function getRegularTreatments() { var tracker = $q.defer(); var treatments = []; - $amRoot.isTreatmentId().then(getConfigDocument).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(getConfigObject).catch(failure); return tracker.promise; - function getConfigDocument(res) { - pdbConfig.get($amRoot.docIds.treatment).then(getConfigObject).catch(failure); - } - function getConfigObject(res) { if (res.regular) Object.keys(res.regular).forEach(iterateTreatments); @@ -495,10 +479,13 @@ function iterateTreatments(name) { if (!res.regular[name]._deleted) { - treatments.push({ + var t = { name: name, rate: res.regular[name].rate - }) + }; + if (res.regular[name].orgcost) + t.orgcost = res.regular[name].orgcost; + treatments.push(t); } } } @@ -515,7 +502,7 @@ include_docs: false } var customers = []; - pdbCustomers.getAll(dbOptions).then(success).catch(failure); + pdbMain.getAll(dbOptions).then(success).catch(failure); return tracker.promise; function success(res) { @@ -523,12 +510,16 @@ tracker.resolve(customers); function iterateRows(row) { + if ($rootScope.amGlobals.IsConfigDoc(row.id)) + return; var splitname = row.id.split('-'); var name = splitname[1]; for (var i = 2; i < (splitname.length - 5); i++) { name += ' ' + splitname[i]; } name = utils.convertToTitleCase(name); + if (name == 'Anonymous') + return; customers.push({ id: row.id, name: name @@ -544,7 +535,7 @@ // return customer information and their vehicles function getCustomerChain(uId) { var tracker = $q.defer(); - pdbCustomers.get(uId).then(success).catch(failure); + pdbMain.get(uId).then(success).catch(failure); return tracker.promise; function success(res) { @@ -583,7 +574,7 @@ // return customer information based on their mobile number function getCustomerByMobile(mobile) { var tracker = $q.defer(); - pdbCustomers.query(mapView, { + pdbMain.query(mapView, { include_docs: true, key: mobile }).then(success).catch(failure); @@ -632,7 +623,7 @@ // save a service to database function saveService(newUser, newVehicle, newService, options) { var tracker = $q.defer(); - var prefixVehicle = 'vhcl' + ((newVehicle.manuf && newVehicle.model) ? '-' + angular.lowercase(newVehicle.manuf).replace(' ', '-') + '-' + angular.lowercase(newVehicle.model).replace(' ', '-') : ''); + var prefixVehicle = 'vhcl'; var prefixUser = 'usr-' + angular.lowercase(newUser.name).replace(' ', '-'); var newServiceId = ((newService.id == undefined || newService.id == '') ? utils.generateUUID('srvc') : newService.id); var newVehicleId = ((newVehicle.id == undefined || newVehicle.id == '') ? utils.generateUUID(prefixVehicle) : newVehicle.id); @@ -681,13 +672,28 @@ saveLastJobCardNo(newService.jobcardno); } - pdbCustomers.get(newUserId).then(foundExistingUser).catch(noUserFound); + pdbMain.get(newUserId).then(foundExistingUser).catch(noUserFound); return tracker.promise; function foundExistingUser(res) { + var splitname = res._id.split('-'); + var name = splitname[1]; + for (var i = 2; i < (splitname.length - 5); i++) { + name += ' ' + splitname[i]; + } + name = utils.convertToTitleCase(name); + if (name != newUser.name) { + res._deleted = true; + pdbMain.save(res).then(doNothing).catch(doNothing); + res._id = utils.generateUUID(prefixUser); + delete res._deleted; + delete res._rev; + } if (!res.user) res.user = {}; Object.keys(newUser).forEach(iterateUserFields); + if (res.user.type && (res.user.type == 'Lead')) + res.user.type = 'Customer'; if (!isVehicleBlank) { if (!res.user.vehicles) res.user.vehicles = {}; @@ -698,7 +704,7 @@ res.user.vehicles[newVehicleId].services = {}; res.user.vehicles[newVehicleId].services[newServiceId] = newService; } - pdbCustomers.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); function iterateUserFields(ufn) { res.user[ufn] = newUser[ufn]; @@ -711,6 +717,10 @@ } } + function doNothing(res) { + // do nothing + } + function noUserFound(err) { if (!isVehicleBlank) { newVehicle.services = {}; @@ -720,10 +730,11 @@ } var doc = { _id: newUserId, - creator: $amRoot.username, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, user: newUser } - pdbCustomers.save(doc).then(success).catch(failure); + pdbMain.save(doc).then(success).catch(failure); } function success(res) { @@ -772,7 +783,6 @@ treatment.rate = treatment.rate[newVehicle.type.toLowerCase().replace(' ', '-')]; treatment.tax = treatment.tax[newVehicle.type.toLowerCase().replace(' ', '-')]; finalPackage.treatments[treatment.name] = treatment; - delete treatment.amount; delete treatment.name; delete treatment.checked; delete treatment['$$hashKey']; @@ -830,7 +840,7 @@ function getManufacturers() { var tracker = $q.defer(); var manufacturers = []; - pdbCommon.get('manuf-models').then(success).catch(missDb); + $http.get('data/manuf_model.json').success(success).catch(failure); return tracker.promise; // success ? add manufacturers to an array and return it via promise @@ -839,11 +849,6 @@ tracker.resolve(manufacturers); } - // !success ? get manufacturer list from raw json file, then execute success sequence again - function missDb(error) { - $http.get('data/manuf_model.json').success(success).catch(failure); - } - // iterate through manufacturer list and get individual manufacturer function manufIterator(manuf) { if (!manuf.match(/\b_id|\b_rev/i)) @@ -860,7 +865,7 @@ function getModels(manufacturer) { var tracker = $q.defer(); var models = []; - pdbCommon.get('manuf-models').then(success).catch(missDb); + $http.get('data/manuf_model.json').success(success).catch(failure); return tracker.promise; // success ? add models to an array and return it via promise @@ -870,11 +875,6 @@ tracker.resolve(models); } - // !success ? get manufacturer list from raw json file, then execute success sequence again - function missDb(error) { - $http.get('data/manuf_model.json').success(success).catch(failure); - } - // throw an error via promise function failure(error) { tracker.reject(error); @@ -883,13 +883,9 @@ function getLastJobCardNo() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(failure); - } - function getSettingsObject(res) { if (res.settings && res.settings.invoices && res.settings.invoices.lastJobCardNo) tracker.resolve(res.settings.invoices.lastJobCardNo); @@ -910,13 +906,9 @@ function getLastEstimateNo() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(failure); - } - function getSettingsObject(res) { if (res.settings && res.settings.invoices && res.settings.invoices.lastEstimateNo) tracker.resolve(res.settings.invoices.lastEstimateNo); @@ -938,13 +930,9 @@ // get last invoice number function getLastInvoiceNo() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(failure); - } - function getSettingsObject(res) { if (res.settings && res.settings.invoices && res.settings.invoices.lastInvoiceNumber) tracker.resolve(res.settings.invoices.lastInvoiceNumber); @@ -965,11 +953,7 @@ // save last invoice number function saveLastInvoiceNo(lino) { - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); - - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(writeSettingsObject); - } + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(writeSettingsObject); function getSettingsObject(res) { if (!res.settings) @@ -977,20 +961,21 @@ if (!res.settings.invoices) res.settings.invoices = {}; res.settings.invoices.lastInvoiceNumber = lino; - pdbConfig.save(res); + pdbMain.save(res); } function writeSettingsObject(err) { var doc = { - _id: utils.generateUUID('sttngs'), - creator: $amRoot.username, + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, settings: { invoices: { lastInvoiceNumber: 1 } } } - pdbConfig.save(doc); + pdbMain.save(doc); } function failure(err) { @@ -999,11 +984,7 @@ } function saveLastEstimateNo(leno) { - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); - - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(writeSettingsObject); - } + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(writeSettingsObject); function getSettingsObject(res) { if (!res.settings) @@ -1011,20 +992,21 @@ if (!res.settings.invoices) res.settings.invoices = {}; res.settings.invoices.lastEstimateNo = leno; - pdbConfig.save(res); + pdbMain.save(res); } function writeSettingsObject(err) { var doc = { - _id: utils.generateUUID('sttngs'), - creator: $amRoot.username, + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, settings: { invoices: { lastEstimateNo: 1 } } } - pdbConfig.save(doc); + pdbMain.save(doc); } function failure(err) { @@ -1033,11 +1015,7 @@ } function saveLastJobCardNo(ljbno) { - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); - - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(writeSettingsObject); - } + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(writeSettingsObject); function getSettingsObject(res) { if (!res.settings) @@ -1045,20 +1023,21 @@ if (!res.settings.invoices) res.settings.invoices = {}; res.settings.invoices.lastJobCardNo = ljbno; - pdbConfig.save(res); + pdbMain.save(res); } function writeSettingsObject(err) { var doc = { - _id: utils.generateUUID('sttngs'), - creator: $amRoot.username, + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, settings: { invoices: { lastJobCardNo: 1 } } } - pdbConfig.save(doc); + pdbMain.save(doc); } function failure(err) { diff --git a/src/app/components/services/services_add.html b/src/app/components/services/services_add.html index 767667b1..3fe3d06a 100644 --- a/src/app/components/services/services_add.html +++ b/src/app/components/services/services_add.html @@ -1,4 +1,29 @@ arrow_back - Back {{vm.label_titleCustomerMoreInfo()}} Information -
+
-
+
- +
-
+
@@ -165,46 +193,43 @@ Continue Continue to Add Service + + View Customer Profile + View {{vm.user.name}}'s Profile - +
-
+
-
+
-
+
-
+
-
- - - {{type}} - -
-
+
-
+
{{type}}
-
- Next Service Reminder: +
+ Next Service Reminder:
{{vm.getDate(vm.nextDueDate)}} @@ -218,24 +243,25 @@
- Customer: - {{vm.user.name}}(M) {{vm.user.mobile}} + Customer: + {{vm.user.name}}(M) {{vm.user.mobile}}
-
+
- + {{user.name}} +
-
+
-
+
More Details more @@ -243,7 +269,7 @@
-
+
Please wait
@@ -259,7 +285,7 @@
-
+
@@ -267,7 +293,7 @@
-
+
@@ -275,29 +301,27 @@
-
-
- - - - - directions_car - Change Vehicle - - - - - {{vehicle.name}} - - - - - New Vehicle - - - - -
+
+ + + + + Change Vehicle + Change Vehicle + + + + + {{vehicle.name}} + + + + + New Vehicle + + + +
@@ -325,21 +349,20 @@ >>
-
+
-
+
- Actions
-
+
Membership
-
+
add_circle_outline @@ -377,83 +400,6 @@ {{vm.user.name || 'Customer'}} has not subscribed to any memberships. Click here to subscribe to one
- -
-
-
-
-
- - Actions -
-
- Package -
-
- Rate -
-
- Amount -
-
- -
-
-
- - - add_circle_outline - remove_circle_outline - CollapseExpand Package - -
-
- {{package.name}} -
-
- {{package.calculatePackageTotal()}} -
-
- {{(package.total ? package.total * (package.checked ? 1 : 0) : 0)}} -
-
-
- - - - - - - - - - - - - - - - - - -
TreatmentsRateTaxAmount
{{treatment.name}} - {{treatment.rate[vm.convertVehicleTypeToAF()] | number: 2}} - - - {{treatment.tax[vm.convertVehicleTypeToAF()] | number: 2}} - - - {{treatment.amount[vm.convertVehicleTypeToAF()]}} -
-
-
- -
-
- No Packages Found! -
-
-
@@ -463,29 +409,25 @@ Treatments - ( - Show AllShow All Treatments - ) + ( + Show AllShow All Treatments + ) - Rate - Tax Amount +   - - {{vm.doRoundOff(problem.rate)}} - - - - {{vm.doRoundOff(problem.tax)}} - - - {{vm.doRoundOff(problem.amount)}} + + + + + more + @@ -496,17 +438,10 @@ - - {{vm.doRoundOff(vm.problem.rate)}} - - - - {{vm.doRoundOff(vm.problem.tax)}} - - - {{vm.doRoundOff(vm.problem.amount)}} + +   @@ -524,24 +459,20 @@ ) - Rate - Tax Amount +   - - {{vm.doRoundOff(problem.rate)}} - - - - {{vm.doRoundOff(problem.tax)}} - - - {{vm.doRoundOff(problem.amount)}} + + + + + more + @@ -552,17 +483,10 @@ - - {{vm.doRoundOff(vm.problem.rate)}} - - - - {{vm.doRoundOff(vm.problem.tax)}} - - - {{vm.doRoundOff(vm.problem.amount)}} + +   @@ -581,29 +505,26 @@ Rate Qty - VAT Amount +   - - - - - - + + - - {{vm.doRoundOff(inventory.tax * inventory.qty)}} - - - {{vm.doRoundOff(inventory.total)}} + + + + + more + @@ -614,23 +535,16 @@ - - - - - - + + - - {{vm.doRoundOff(vm.inventory.tax * vm.inventory.qty)}} - - - {{vm.doRoundOff(vm.inventory.total)}} + +   @@ -649,29 +563,26 @@ Rate Qty - VAT Amount +   - - - - - - + + - - {{vm.doRoundOff(inventory.tax * inventory.qty)}} - - - {{vm.doRoundOff(inventory.total)}} + + + + + more + @@ -682,28 +593,86 @@ - - - - - - + + - - {{vm.doRoundOff(vm.inventory.tax * vm.inventory.qty)}} - - - {{vm.doRoundOff(vm.inventory.total)}} + +  
+
+
+
+
+ + Actions +
+
+ Package +
+
+ Rate +
+
+ Amount +
+
+ +
+
+
+ + + add_circle_outline + remove_circle_outline + CollapseExpand Package + +
+
+ {{package.name}} +
+
+ {{package.calculatePackageTotal()}} +
+
+ {{(package.total ? package.total * (package.checked ? 1 : 0) : 0)}} +
+
+
+ + + + + + + + + + + + + + +
TreatmentsAmount
{{treatment.name}} + +
+
+
+ +
+
+ No Packages Found! +
+
+
@@ -713,36 +682,52 @@ {{vm.getDate(vm.service.date)}}
- Payment - - Service Tax -  % + + Payment + + + history + Manage Payments + - VAT -  % + + + {{tax.name}} + +  % Round Off - - Discount -  % + + Discount + + + more + Manage Discounts +
- Subtotal: Rs. {{vm.calculateSubtotal()}} + Subtotal: {{vm.currencySymbol}} {{vm.service.subtotal}}   - Service Tax: Rs. {{vm.calculateTax()}} -   - VAT: Rs. {{vm.calculateVat()}} -   - Discount: Rs. + Discount: {{vm.currencySymbol}}   - Round Off: Rs. + Round Off: {{vm.currencySymbol}}   - Total Cost: Rs. {{vm.service.cost}} + + {{tax.name}}: {{vm.currencySymbol}} {{tax.tax}} + +   + Total Cost: {{vm.currencySymbol}} {{vm.service.cost}}
+
+   + Received: {{vm.currencySymbol}} {{vm.service.partialpayment.total}} +   + Due: {{vm.currencySymbol}} {{vm.calculateDue()}} +
done diff --git a/src/app/components/services/services_viewAll.html b/src/app/components/services/services_viewAll.html index dbc69aae..c068a289 100644 --- a/src/app/components/services/services_viewAll.html +++ b/src/app/components/services/services_viewAll.html @@ -35,14 +35,14 @@ Customer Vehicle Date - Amount
(Rs.) + Amount
({{vm.currencySymbol}}) Payment - {{service.cstmr_name}} - {{service.vhcl_manuf + ' ' + service.vhcl_model}} ({{service.vhcl_reg}}) + {{service.cstmr_name}} + {{service.vhcl_manuf + ' ' + service.vhcl_model}} ({{service.vhcl_reg}}) {{vm.getServiceDate(service.srvc_date)}} {{service.srvc_cost}} {{service.srvc_status}} diff --git a/src/app/components/services/tmpl/dialog_discount.controller.js b/src/app/components/services/tmpl/dialog_discount.controller.js new file mode 100644 index 00000000..18f92afa --- /dev/null +++ b/src/app/components/services/tmpl/dialog_discount.controller.js @@ -0,0 +1,81 @@ +/** + * Controller for discount control dialogbox + * @author ndkcha + * @since 0.7.0 + * @version 0.7.0 + */ + +/// + +(function() { + angular.module('automintApp').controller('amCtrlSeDc', DiscountController); + + DiscountController.$inject = ['$mdDialog', 'treatmentLength', 'partLength', 'treatmentTotal', 'partTotal', 'discountObj', 'currencySymbol']; + + function DiscountController($mdDialog, treatmentLength, partLength, treatmentTotal, partTotal, discountObj, currencySymbol) { + // initiailize view model + var vm = this; + + // named assignments for view model + vm.treatmentDiscount = 0; + vm.partDiscount = 0; + vm.totalDiscount = 0; + vm.isTreatment = (treatmentLength > 0); + vm.isPart = (partLength > 0); + vm.isTreatmentSelected = false; + vm.isPartSelected = false; + vm.currencySymbol = currencySymbol; + + // function maps to view model + vm.cancel = cancel; + vm.calculateTotal = calculateTotal; + vm.checkTreatmentDiscount = checkTreatmentDiscount; + vm.checkPartDiscount = checkPartDiscount; + vm.save = save; + + // default execution steps + initialize(); + + // function definitions + + function checkTreatmentDiscount() { + vm.isTreatmentSelected = (vm.treatmentDiscount > 0); + calculateTotal(); + } + + function checkPartDiscount() { + vm.isPartSelected = (vm.partDiscount > 0); + calculateTotal(); + } + + function initialize() { + if (discountObj != undefined) { + vm.treatmentDiscount = parseFloat(discountObj.treatment); + vm.partDiscount = parseFloat(discountObj.part); + vm.treatmentDiscount = (vm.treatmentDiscount % 1 != 0) ? parseFloat(vm.treatmentDiscount.toFixed(2)) : parseInt(vm.treatmentDiscount); + vm.partDiscount = (vm.partDiscount % 1 != 0) ? parseFloat(vm.partDiscount.toFixed(2)) : parseInt(vm.partDiscount); + vm.isTreatmentSelected = (vm.treatmentDiscount > 0); + vm.isPartSelected = (vm.partDiscount > 0); + calculateTotal(); + } + } + + function calculateTotal() { + vm.totalDiscount = (vm.isTreatmentSelected ? parseFloat(vm.treatmentDiscount) : 0) + (vm.isPartSelected ? parseFloat(vm.partDiscount) : 0); + vm.totalDiscount = (vm.totalDiscount % 1 != 0) ? parseFloat(vm.totalDiscount.toFixed(2)) : parseInt(vm.totalDiscount); + } + + function save() { + var discount = { + treatment: (vm.isTreatmentSelected ? vm.treatmentDiscount : 0), + part: (vm.isPartSelected ? vm.partDiscount : 0), + total: vm.totalDiscount + } + $mdDialog.hide(discount); + } + + function cancel() { + $mdDialog.cancel(); + } + } +})(); \ No newline at end of file diff --git a/src/app/components/services/tmpl/dialog_discount.html b/src/app/components/services/tmpl/dialog_discount.html new file mode 100644 index 00000000..232eab01 --- /dev/null +++ b/src/app/components/services/tmpl/dialog_discount.html @@ -0,0 +1,45 @@ + + + + Discount For: +
+
+ Treatments: + + {{vm.currencySymbol}} +
+
+ Parts: + + {{vm.currencySymbol}} +
+
+ Total: + {{vm.totalDiscount}} + {{vm.currencySymbol}} +
+
+ + done + Done + + + close + Cancel + +
+
+
+
\ No newline at end of file diff --git a/src/app/components/services/service_membership.edit-template.html b/src/app/components/services/tmpl/dialog_membership.edit-template.html similarity index 100% rename from src/app/components/services/service_membership.edit-template.html rename to src/app/components/services/tmpl/dialog_membership.edit-template.html diff --git a/src/app/components/services/tmpl/dialog_membership.edit.controller.js b/src/app/components/services/tmpl/dialog_membership.edit.controller.js new file mode 100644 index 00000000..43436628 --- /dev/null +++ b/src/app/components/services/tmpl/dialog_membership.edit.controller.js @@ -0,0 +1,159 @@ +/** + * Controller for Edit Membership Dialogbox + * @author ndkcha + * @since 0.7.0 + * @version 0.7.0 + */ + +/// + +(function() { + angular.module('automintApp').controller('amCtrlMeD', MembershipEditDialogController); + + MembershipEditDialogController.$inject = ['$mdDialog', '$filter', 'membership', 'treatments']; + + function MembershipEditDialogController($mdDialog, $filter, membership, treatments) { + var editMsVm = this; + editMsVm.treatment = { + details: '' + }; + editMsVm.membership = { + name: membership.name, + occurences: membership.occurences, + duration: membership.duration + }; + editMsVm.selectedTreatments = []; + editMsVm.treatments = treatments; + editMsVm.confirmDialog = confirmDialog; + editMsVm.treatmentQuerySearch = treatmentQuerySearch; + editMsVm.finalizeNewTreatment = finalizeNewTreatment; + editMsVm.updateTreatmentDetails = updateTreatmentDetails; + + loadDefaultOccDur(); + loadMemberships(); + + function loadMemberships() { + membership.treatments.forEach(iterateTreatments); + + function iterateTreatments(treatment) { + var found = $filter('filter')(editMsVm.treatments, { + name: treatment.name + }, true); + + if (found.length == 1) { + found[0].given.occurences = treatment.given.occurences; + found[0].given.duration = treatment.given.duration; + found[0].used.occurences = treatment.used.occurences; + found[0].used.duration = treatment.used.duration; + editMsVm.selectedTreatments.push(found[0]); + } else { + editMsVm.treatments.push(treatment); + editMsVm.selectedTreatments.push(editMsVm.treatments[editMsVm.treatments.length - 1]); + } + } + } + + function updateTreatmentDetails() { + var found = $filter('filter')(editMsVm.treatments, { + name: editMsVm.treatment.details + }); + if (found.length == 1 && found[0].name == editMsVm.treatment.details) { + editMsVm.treatment.occurences = found[0].given.occurences; + editMsVm.treatment.duration = found[0].given.duration; + } else { + editMsVm.treatment.occurences = editMsVm.membership.occurences + editMsVm.treatment.duration = editMsVm.membership.duration; + } + } + + // query search for treatments [autocomplete] + function treatmentQuerySearch() { + var tracker = $q.defer(); + var results = (editMsVm.treatment.details ? editMsVm.treatments.filter(createFilterForTreatments(editMsVm.treatment.details)) : editMsVm.treatments); + + return results; + } + + // create filter for users' query list + function createFilterForTreatments(query) { + var lcQuery = angular.lowercase(query); + return function filterFn(item) { + return (angular.lowercase(item.name).indexOf(lcQuery) === 0); + } + } + + function finalizeNewTreatment(btnClicked) { + editMsVm.treatment.details = editMsVm.treatment.details.trim(); + if (editMsVm.treatment.details != '') { + var found = $filter('filter')(editMsVm.treatments, { + name: editMsVm.treatment.details + }, true); + if (found.length == 1 && found[0].name == editMsVm.treatment.details) { + found[0].checked = true; + found[0].rate = editMsVm.treatment.rate; + found[0].given.duration = editMsVm.treatment.duration; + found[0].given.occurences = editMsVm.treatment.occurences; + found[0].used.duration = 0; + found[0].used.occurences = 0; + editMsVm.selectedTreatments.push(found[0]); + } else { + editMsVm.treatments.push({ + name: editMsVm.treatment.details, + rate: editMsVm.treatment.rate, + given: { + duration: editMsVm.treatment.duration, + occurences: editMsVm.treatment.occurences, + }, + used: { + duration: 0, + occurences: 0 + }, + checked: true + }); + editMsVm.selectedTreatments.push(editMsVm.treatments[editMsVm.treatments.length - 1]); + } + editMsVm.treatment.details = ''; + editMsVm.treatment.rate = {}; + editMsVm.treatment.occurences = editMsVm.membership.occurences; + editMsVm.treatment.duration = editMsVm.membership.duration; + angular.element('#new-treatment-details').find('input')[0].focus(); + } + if (btnClicked) + angular.element('#new-treatment-details').find('input')[0].focus(); + } + + function loadDefaultOccDur() { + editMsVm.treatments.forEach(iterateTreatments); + + function iterateTreatments(treatment) { + if (!treatment.given) { + treatment.given = { + occurences: membership.occurences, + duration: membership.duration + } + } + if (!treatment.used) { + treatment.used = { + occurences: 0, + duration: 0 + } + } + } + } + + function confirmDialog() { + membership.treatments = editMsVm.selectedTreatments; + membership.selectedTreatments = []; + membership.treatments.forEach(makeSelectedTreatments); + $mdDialog.hide(); + + function makeSelectedTreatments(treatment) { + if (membership.calculateTOccurenceLeft(treatment) != 0 && membership.calculateTDurationLeft(treatment) != 0) { + treatment.checked = true; + membership.selectedTreatments.push(treatment); + } else + treatment.checked = false; + } + } + } +})(); \ No newline at end of file diff --git a/src/app/components/services/tmpl/dialog_partialpayment.controller.js b/src/app/components/services/tmpl/dialog_partialpayment.controller.js new file mode 100644 index 00000000..34e61f1b --- /dev/null +++ b/src/app/components/services/tmpl/dialog_partialpayment.controller.js @@ -0,0 +1,162 @@ +/** + * Controller for Partial Payment Dialogbox + * @author ndkcha + * @since 0.7.0 + * @version 0.7.0 + */ + +/// + +(function() { + angular.module('automintApp').controller('amCtrlSePp', PartialPaymentController); + + PartialPaymentController.$inject = ['$mdDialog', '$filter', 'totalCost', 'partialPayments', 'currencySymbol']; + + function PartialPaymentController($mdDialog, $filter, totalCost, partialPayments, currencySymbol) { + // initialize view model + var vm = this; + + // named assignments for view model + vm.partialPayments = []; + vm.tc = totalCost; + vm.paymentFocusIndex = -1; + vm.currencySymbol = currencySymbol; + + // function mappings to view model + vm.getDate = getDate; + vm.addPayment = addPayment; + vm.save = save; + vm.cancel = cancel; + vm.calculateRemaining = calculateRemaining; + vm.calculateReceived = calculateReceived; + vm.IsPaymentFocusIndex = IsPaymentFocusIndex; + vm.deleteAllEntries = deleteAllEntries; + vm.deleteEntry = deleteEntry; + + // default execution steps + setTimeout(setViewportHeight, 400); + feedExistingPayments(); + + $(window).on('resize', OnWindowResize); + + // function definitions + + function deleteAllEntries() { + vm.partialPayments = []; + calculateRemaining(); + addPayment(); + } + + function deleteEntry(index) { + vm.partialPayments.splice(index, 1); + calculateRemaining(); + if (vm.partialPayments.length == 0) + addPayment(); + } + + function feedExistingPayments() { + var keys = (partialPayments) ? Object.keys(partialPayments) : undefined; + if (partialPayments && keys && (keys.length > 1)) { + keys.forEach(iteratePp); + calculateRemaining(); + } else + addPayment(); + + function iteratePp(pp) { + if (pp == "total") + return; + vm.partialPayments.push({ + amount: partialPayments[pp], + date: new Date(pp), + adjust: false + }); + } + } + + function IsPaymentFocusIndex(index) { + return (vm.paymentFocusIndex == index); + } + + function calculateTotalReceived() { + var temptr = 0; + vm.partialPayments.forEach(iteratePp); + return temptr; + + function iteratePp(pp) { + if (!pp.amount || pp.amount == '' || (pp.adjust == true)) + return; + temptr += parseFloat(pp.amount); + } + } + + function calculateReceived() { + var x = totalCost - (vm.tc + calculateTotalReceived()); + var found = $filter('filter')(vm.partialPayments, { + adjust: true + }, true); + + if (found.length > 0) + found[0].amount = x; + else { + vm.partialPayments.push({ + amount: x, + date: new Date(), + adjust: true + }); + } + } + + function adjustPaymentCalc() { + vm.partialPayments.forEach(iteratePp); + + function iteratePp(pp) { + pp.adjust = (!pp.amount || pp.amount == ''); + } + } + + function calculateRemaining(payment) { + adjustPaymentCalc(); + vm.tc = totalCost - calculateTotalReceived(); + } + + function OnWindowResize() { + setViewportHeight(); + } + + function setViewportHeight() { + $('#am-dpp').css('max-height', $(window).height() - ($('#am-dpp').offset().top + 15)); + } + + function addPayment() { + vm.paymentFocusIndex = -1; + vm.partialPayments.push({ + amount: '', + date: new Date(), + adjust: true + }); + vm.paymentFocusIndex = vm.partialPayments.length - 1; + } + + function getDate(date) { + return moment(date).format('DD MMM YYYY'); + } + + function save() { + var temp = {}, total = 0; + vm.partialPayments.forEach(iteratePp); + temp.total = parseFloat(total); + $mdDialog.hide(temp); + + function iteratePp(pp) { + if (pp.amount == '') + return; + temp[moment(pp.date).format()] = pp.amount; + total += pp.amount; + } + } + + function cancel() { + $mdDialog.cancel(); + } + } +})(); \ No newline at end of file diff --git a/src/app/components/services/tmpl/dialog_partialpayment.html b/src/app/components/services/tmpl/dialog_partialpayment.html new file mode 100644 index 00000000..12d4b642 --- /dev/null +++ b/src/app/components/services/tmpl/dialog_partialpayment.html @@ -0,0 +1,89 @@ + + + +
+
+ {{$index+1}}. Received:   + +  {{vm.currencySymbol}} + + delete + Delete this entry! + +
+
+ + {{vm.getDate(payment.date)}} +
+
+
+ + add + Add More + +
+
+ Remaining:   + +  {{vm.currencySymbol}} + + delete_sweep + Delete all entries! + +
+
+ + done + Done + + + close + Cancel + +
+
+
\ No newline at end of file diff --git a/src/app/components/services/tmpl/dialog_timefilter.html b/src/app/components/services/tmpl/dialog_timefilter.html index 90cae099..29da0b7b 100644 --- a/src/app/components/services/tmpl/dialog_timefilter.html +++ b/src/app/components/services/tmpl/dialog_timefilter.html @@ -98,7 +98,7 @@ - + done Done diff --git a/src/app/components/services/tmpl2/dialog-id.controller.js b/src/app/components/services/tmpl2/dialog-id.controller.js new file mode 100644 index 00000000..94f3baec --- /dev/null +++ b/src/app/components/services/tmpl2/dialog-id.controller.js @@ -0,0 +1,61 @@ +/** + * Controller to handle Inventory Details (td) dialog box + * @author ndkcha + * @since 0.7.0 + * @version 0.7.0 + */ + +/// + +(function() { + angular.module('automintApp').controller('amCtrlSeId', IdController); + + IdController.$inject = ['$mdDialog', 'inventory']; + + function IdController($mdDialog, inventory) { + // intialize view model + var vm = this; + + // temporary assignments for controller instance + // no such assignments + + // named assignments for view model + vm.inventory = inventory; + + // function mappings to view model + vm.OnKeyDown = OnKeyDown; + vm.submit = submit; + vm.getDate = getDate; + vm.clearall = clearall; + + // default execution steps + setTimeout(focusOriginalCost, 800); + if (vm.inventory.purchasedate) + vm.inventory.purchasedate = new Date(vm.inventory.purchasedate); + + // function definitions + + function clearall() { + delete vm.inventory.orgcost; + delete vm.inventory.vendor; + } + + function getDate(date) { + return moment(date).format('DD MMM YYYY'); + } + + function focusOriginalCost() { + $('#ami-did-orgcost').focus(); + } + + function OnKeyDown(event) { + if (event.keyCode == 13) + submit(); + } + + function submit() { + vm.inventory.purchasedate = moment(vm.inventory.purchasedate).format(); + $mdDialog.hide(vm.inventory); + } + } +})(); \ No newline at end of file diff --git a/src/app/components/services/tmpl2/dialog-id.html b/src/app/components/services/tmpl2/dialog-id.html new file mode 100644 index 00000000..655e239f --- /dev/null +++ b/src/app/components/services/tmpl2/dialog-id.html @@ -0,0 +1,62 @@ + + + +
+ {{vm.inventory.name}} +
+
+ + +
+
+ + +
+
+ + + {{vm.getDate(vm.inventory.purchasedate)}} +
+
+ + + close + Clear All + + + done + Done + + +
\ No newline at end of file diff --git a/src/app/components/services/tmpl2/dialog-td.controller.js b/src/app/components/services/tmpl2/dialog-td.controller.js new file mode 100644 index 00000000..869ad4bf --- /dev/null +++ b/src/app/components/services/tmpl2/dialog-td.controller.js @@ -0,0 +1,47 @@ +/** + * Controller to handle Treatment Details (td) dialog box + * @author ndkcha + * @since 0.7.0 + * @version 0.7.0 + */ + +/// + +(function() { + angular.module('automintApp').controller('amCtrlSeTd', TdController); + + TdController.$inject = ['$mdDialog', 'problem']; + + function TdController($mdDialog, problem) { + // intialize view model + var vm = this; + + // temporary assignments for controller instance + // no such assignments + + // named assignments for view model + vm.problem = problem; + + // function mappings to view model + vm.OnKeyDown = OnKeyDown; + vm.submit = submit; + + // default execution steps + setTimeout(focusOriginalCost, 800); + + // function definitions + + function focusOriginalCost() { + $('#ami-dtd-orgcost').focus(); + } + + function OnKeyDown(event) { + if (event.keyCode == 13) + submit(); + } + + function submit() { + $mdDialog.hide(vm.problem); + } + } +})(); \ No newline at end of file diff --git a/src/app/components/services/tmpl2/dialog-td.html b/src/app/components/services/tmpl2/dialog-td.html new file mode 100644 index 00000000..813dfe3d --- /dev/null +++ b/src/app/components/services/tmpl2/dialog-td.html @@ -0,0 +1,37 @@ + + + +
+ {{vm.problem.details}} +
+
+ + +
+
+ + + done + Done + + +
\ No newline at end of file diff --git a/src/app/components/settings/settings-backup.factory.js b/src/app/components/settings/settings-backup.factory.js index 5ca2ac6a..d6ebb8c4 100644 --- a/src/app/components/settings/settings-backup.factory.js +++ b/src/app/components/settings/settings-backup.factory.js @@ -2,18 +2,20 @@ * Factory to backup pouchDb dump to local storage * @author ndkcha * @since 0.4.1 - * @version 0.4.1 + * @version 0.7.0 */ /// (function() { - angular.module('automintApp') - .factory('amBackup', BackupFactory); + const electron = require('electron').remote; + const amApp = electron.app; - BackupFactory.$inject = ['$q', 'pdbCustomers', 'pdbConfig', 'constants']; + angular.module('automintApp').factory('amBackup', BackupFactory); - function BackupFactory($q, pdbCustomers, pdbConfig, constants) { + BackupFactory.$inject = ['$q', 'pdbMain', 'pdbLocal']; + + function BackupFactory($q, pdbMain, pdbLocal) { // temporary named assignments var backupDocument = {}; var tracker; @@ -32,20 +34,21 @@ tracker = $q.defer(); $q.all([ - pdbCustomers.getAll(), - pdbConfig.getAll() + pdbMain.getAll(), + pdbLocal.getAll() ]).then(foundDocsToBackup).catch(noDocsToBackup); return tracker.promise; } function foundDocsToBackup(data) { - backupDocument.backupTime = Date.now(); - backupDocument.customers = {} - backupDocument.customers.doc = []; - backupDocument.config = {}; - backupDocument.config.doc = []; - data[0].rows.forEach(iterateCustomers); - data[1].rows.forEach(iterateConfigs); + backupDocument.backupTime = moment().format(); + backupDocument.automintVersion = amApp.getVersion(); + backupDocument.main = {} + backupDocument.main.doc = []; + backupDocument.local = {}; + backupDocument.local.doc = []; + data[0].rows.forEach(iterateMain); + data[1].rows.forEach(iterateLocal); // content dispostion var docText = JSON.stringify(backupDocument); var date = new Date(); @@ -63,14 +66,14 @@ }); } - // iterate through customers to add into backup document - function iterateCustomers(intr_customer) { - backupDocument.customers.doc.push(intr_customer.doc); + // iterate through main docs to add into backup document + function iterateMain(intr_customer) { + backupDocument.main.doc.push(intr_customer.doc); } - // iterate through configs to add into backup document - function iterateConfigs(intr_config) { - backupDocument.config.doc.push(intr_config.doc); + // iterate through local docs to add into backup document + function iterateLocal(intr_config) { + backupDocument.local.doc.push(intr_config.doc); } // error fetching from database diff --git a/src/app/components/settings/settings-importdata.service.js b/src/app/components/settings/settings-importdata.service.js index 9b289bb9..7d96b07c 100644 --- a/src/app/components/settings/settings-importdata.service.js +++ b/src/app/components/settings/settings-importdata.service.js @@ -2,7 +2,7 @@ * Service for Importing data to Automint * @author ndkcha * @since 0.4.1 - * @version 0.4.1 + * @version 0.7.0 */ /// @@ -11,155 +11,413 @@ angular.module('automintApp') .service('amImportdata', ImportDataService); - ImportDataService.$inject = ['pdbCustomers', '$filter', '$q', 'utils', '$amRoot', '$log']; + ImportDataService.$inject = ['pdbMain', '$filter', '$q', 'utils', '$rootScope', '$log', '$amRoot']; - function ImportDataService(pdbCustomers, $filter, $q, utils, $amRoot, $log) { + function ImportDataService(pdbMain, $filter, $q, utils, $rootScope, $log, $amRoot) { var sVm = this; // temporary named mappings var tracker; // function mappings - sVm.compileCSVFile = compileCSVFile; + sVm.checkTypeofFile = checkTypeofFile; sVm.cleanUp = cleanUp; - // function declarations and definations - function compileCSVFile(files) { + function checkTypeofFile(files) { tracker = $q.defer(); - readFile(files[0], readerCallback); + checkFile(files[0]); return tracker.promise; - // declarations and definations - - // initiate reading of CSV file - function readFile(f, callback) { + function checkFile(file) { var reader = new FileReader(); - reader.readAsText(f); - reader.onload = onReaderLoad; + reader.readAsText(file); + reader.onload = onRLoad; - function onReaderLoad(event) { - var csvArray = $.csv2Array(event.target.result); - callback(csvArray); + function onRLoad(event) { + var isCsvFile, isJsonFile; + try { + var csvArray = $.csv2Array(event.target.result); + isCsvFile = true; + csvCallback(csvArray); + } catch(exception) { + isCsvFile = false; + } + if (isCsvFile) + return; + try { + var jsonObj = JSON.parse(event.target.result); + isJsonFile = true; + jsonCallback(jsonObj); + } catch(exception) { + isJsonFile = false; + } + if (isJsonFile) + return; + tracker.reject({ + success: false, + message: 'Invalid File!' + }); } } + } - // parse CSV file - function readerCallback(csvArray) { - var customers = []; - var csvMap = {}; - var csvFields = csvArray[0]; - tracker.notify({ - current: 0, - total: csvFields.length - }); - for (var j = 0; j < csvFields.length; j++) { - var fieldName = csvFields[j].toLowerCase(); - switch (fieldName) { - case 'mobile': - case 'mo': - case 'mobile number': - csvMap.mobile = j; - break; - case 'name': - csvMap.name = j; - break; - case 'reg': - case 'registration': - case 'registration number': - case 'vehicle number': - case 'registration no': - case 'vehicle no': - csvMap.reg = j; - break; - case 'model': - case 'car': - csvMap.model = j; - break; - case 'manufacturer': - case 'company': - csvMap.manuf = j; - break; + function jsonCallback(restore) { + $rootScope.isOnChangeMainDbBlocked = true; + $q.all([ + pdbMain.getAll(), + pdbMain.get($rootScope.amGlobals.configDocIds.settings) + ]).then(getAllDocs).catch(getAllDocs); + + function getAllDocs(combores) { + var docsToSave = []; + var res = combores[0]; + var setconfig = combores[1]; + + if (restore.customers && restore.customers.doc) + restore.customers.doc.forEach(iterateCustomers); + + if (restore.config && restore.config.doc) + restore.config.doc.forEach(iterateConfig); + + pdbMain.saveAll(docsToSave).then(success).catch(failure); + + function success(res) { + setTimeout(setIsImportingDb, 1000); + + function setIsImportingDb() { + $rootScope.isOnChangeMainDbBlocked = false; + $amRoot.generateCacheDocs(true).then(respond).catch(respond); + + function respond() { + tracker.resolve({ + success: true, + message: 'Backup has been restored! You may now delete the file.' + }); + } } } - for (var row = 1; row < csvArray.length; row++) { - // hold different values coming from csv file - var mobile = csvArray[row][csvMap.mobile]; - var name = csvArray[row][csvMap.name]; - var reg = csvArray[row][csvMap.reg]; - var manuf = csvArray[row][csvMap.manuf]; - var model = csvArray[row][csvMap.model]; - - // check if at least one entry has been found, skip otherwise - if (!(mobile || name || reg || manuf || model)) - continue; - // encode objects from derived data - var user = { - mobile: mobile ? mobile : '', - name: name ? utils.convertToTitleCase(name) : '' + function failure(err) { + console.error(err); + tracker.reject({ + success: false, + message: 'Could not restore backup at moment! Please Try Again Later!' + }) + } + + function iterateConfig(config) { + var doc = $.extend({}, config); + doc.creator = $rootScope.amGlobals.creator; + doc.channel = $rootScope.amGlobals.channel; + if (config._id.match(/\btrtmnt-/i)) + doc._id = $rootScope.amGlobals.configDocIds.treatment; + else if (config._id.match(/\bwrkshp-/i)) + doc._id = $rootScope.amGlobals.configDocIds.workshop; + else if (config._id.match(/\bsttngs-/i)) + doc._id = $rootScope.amGlobals.configDocIds.settings; + else if (config._id.match(/\binvntry-/i)) + doc._id = $rootScope.amGlobals.configDocIds.inventory; + + delete doc._rev; + + if (doc._id == $rootScope.amGlobals.configDocIds.settings) { + if (doc.dbversion) + delete doc.dbversion; + if (doc.settings && doc.settings.serviceTax) { + if (!doc.settings.tax) + doc.settings.tax = {}; + doc.settings.tax['Service Tax'] = { + type: doc.settings.serviceTax.taxIncType, + isTaxApplied: doc.settings.serviceTax.applyTax, + isForTreatments: true, + isForInventory: false, + percent: doc.settings.serviceTax.tax + } + delete doc.settings['serviceTax']; + } + if (doc.settings && doc.settings.servicetax) { + if (!doc.settings.tax) + doc.settings.tax = {}; + doc.settings.tax['Service Tax'] = { + type: doc.settings.servicetax.taxIncType, + isTaxApplied: doc.settings.servicetax.applyTax, + isForTreatments: true, + isForInventory: false, + percent: doc.settings.servicetax.tax + } + delete doc.settings['servicetax']; + } + if (doc.settings && doc.settings.vat) { + if (!doc.settings.tax) + doc.settings.tax = {}; + doc.settings.tax['VAT'] = { + type: doc.settings.vat.taxIncType, + isTaxApplied: doc.settings.vat.applyTax, + isForTreatments: false, + isForInventory: true, + percent: doc.settings.vat.tax + } + delete doc.settings['vat']; + } } - var vehicle = { - reg: reg ? reg.toUpperCase() : '', - manuf: manuf ? manuf : '', - model: model ? model : '' + + if (res) { + var confound = $filter('filter')(res.rows, comparator, true); + + if (confound.length == 1) { + doc._rev = confound[0].doc._rev; + doc.currency = confound[0].doc.currency; + } + + function comparator(value, index) { + if (value.doc && (value.doc._id == doc._id)) + return true; + } } - // reduce duplicates in imported file - var found = $filter('filter')(customers, { - name: name, - mobile: mobile - }, true); - if (found.length > 0) { - var vfound = $filter('filter')(found[0].vehicles, { - reg: reg - }, true); - if (vfound.length > 0) - continue; - else { - if ((reg || manuf || model) && (reg != '' || manuf != '' || model != '')) - found[0].vehicles.push(vehicle); + docsToSave.push(doc); + } + + function iterateCustomers(customer) { + if ($rootScope.amGlobals.IsConfigDoc(customer._id)) + return; + var doc, custfound; + if (res.error) { + custfound = { + length: 0 } - } else { - user.vehicles = []; - if ((reg || manuf || model) && (reg != '' || manuf != '' || model != '')) - user.vehicles.push(vehicle); - customers.push(user); + } else + custfound = $filter('filter')(res.rows, comparator, true); + + if (custfound.length == 1) { + // doc = already existing user + // customer = imported user + doc = custfound[0].doc; + if (doc.user && customer.user) + Object.keys(customer.user).forEach(changeNewFieldsInUser); + + if (customer.user.vehicles) + Object.keys(customer.user.vehicles).forEach(iterateVehicles); + } else if (customer.user) { + // doc = user to be inserted + // customer = imported + var prefixUser = 'usr-' + angular.lowercase(customer.user.name).replace(' ', '-'); + doc = { + _id: utils.generateUUID(prefixUser), + channel: $rootScope.amGlobals.channel, + creator: $rootScope.amGlobals.creator, + user: {} + }; + + if (customer.user) + Object.keys(customer.user).forEach(changeNewFieldsInUser); + + if (customer.user.vehicles) + Object.keys(customer.user.vehicles).forEach(iterateVehicles); + } + docsToSave.push(doc); + + function iterateVehicles(vId) { + var tempv = customer.user.vehicles[vId], isDuplicateVehicle = false; + var newVehicleId; + if (!doc.user.vehicles) { + doc.user.vehicles = {}; + if (newVehicleId == undefined) + newVehicleId = utils.generateUUID('vhcl') + doc.user.vehicles[newVehicleId] = tempv; + } else { + Object.keys(doc.user.vehicles).forEach(iterateExstVehicle); + if (!isDuplicateVehicle) { + if (newVehicleId == undefined) + newVehicleId = utils.generateUUID('vhcl') + doc.user.vehicles[newVehicleId] = tempv; + } + } + + if (doc.user.vehicles[newVehicleId].services) + Object.keys(doc.user.vehicles[newVehicleId].services).forEach(iterateServices); + + function iterateServices(sId) { + var temps = doc.user.vehicles[newVehicleId].services[sId]; + var service = $.extend({}, temps); + if (temps.serviceTax) { + delete service['serviceTax']; + if (!service.taxes) + service.taxes = {}; + service.taxes['Service Tax'] = { + type: temps.serviceTax.taxIncType, + percent: temps.serviceTax.tax, + isTaxApplied: temps.serviceTax.applyTax, + isForTreatments: true, + isForInventory: false + } + } + if (temps.vat) { + delete service['vat']; + if (!service.taxes) + service.taxes = {}; + service.taxes['VAT'] = { + type: temps.vat.taxIncType, + percent: temps.vat.tax, + isTaxApplied: temps.vat.applyTax, + isForTreatments: false, + isForInventory: true + } + } + + if (service.problems) + Object.keys(service.problems).forEach(iterateProblems); + if (service.inventories) + Object.keys(service.inventories).forEach(iterateInventory); + + doc.user.vehicles[newVehicleId].services[sId] = service; + + function iterateInventory(inventory) { + var tempi = service.inventories[inventory]; + if (temps.vat && temps.vat.applyTax) { + if (temps.vat.taxIncType == 'inclusive') { + tempi.amount = parseFloat(tempi.rate) + parseFloat(tempi.tax); + tempi.amount = parseFloat(tempi.amount); + tempi.amount = (tempi.amount % 1 != 0) ? tempi.amount.toFixed(2) : parseInt(tempi.amount); + } else + tempi.amount = parseFloat(tempi.rate); + } else + tempi.amount = parseFloat(tempi.rate); + delete tempi.tax; + service.inventories[inventory] = tempi; + } + + function iterateProblems(problem) { + var tempp = service.problems[problem]; + if (temps.serviceTax && temps.serviceTax.applyTax) { + if (temps.serviceTax.taxIncType == 'inclusive') { + tempp.amount = parseFloat(tempp.rate) + parseFloat(tempp.tax); + tempp.amount = parseFloat(tempp.amount); + tempp.amount = (tempp.amount % 1 != 0) ? tempp.amount.toFixed(2) : parseInt(tempp.amount); + } else + tempp.amount = parseFloat(tempp.rate); + } else + tempp.amount = parseFloat(tempp.rate); + delete tempp.tax; + service.problems[problem] = tempp; + } + } + + function iterateExstVehicle(evId) { + var extv = doc.user.vehicles[evId]; + if ((tempv.reg == extv.reg) || (vId == evId)) { + newVehicleId = evId; + extv.reg = tempv.reg; + extv.manuf = (tempv.manuf ? tempv.manuf : extv.manuf); + extv.model = (tempv.model ? tempv.model : extv.model); + extv.type = (tempv.type ? tempv.type : extv.type); + isDuplicateVehicle = true; + } + } + } + + function changeNewFieldsInUser(key) { + if ((key == 'vehicles') || (customer.user[key] == '') || (angular.isObject(customer.user[key]) && (Object.keys(customer.user[key]).length == 0))) + return; + doc.user[key] = customer.user[key]; + } + + function comparator(value, index, array) { + if (value.doc && value.doc.user && value.doc.user.mobile && customer.user && customer.user.mobile && (value.doc.user.mobile != '') && (customer.user.mobile != '') && (value.doc.user.mobile == customer.user.mobile)) + return true; } } + } + } - updateDatabase(customers); + // parse CSV file + function csvCallback(csvArray) { + var customers = []; + var csvMap = {}; + var csvFields = csvArray[0]; + for (var j = 0; j < csvFields.length; j++) { + var fieldName = csvFields[j].toLowerCase(); + switch (fieldName) { + case 'mobile': + case 'mo': + case 'mobile number': + csvMap.mobile = j; + break; + case 'name': + csvMap.name = j; + break; + case 'reg': + case 'registration': + case 'registration number': + case 'vehicle number': + case 'registration no': + case 'vehicle no': + csvMap.reg = j; + break; + case 'model': + case 'car': + csvMap.model = j; + break; + case 'manufacturer': + case 'company': + csvMap.manuf = j; + break; + } } + for (var row = 1; row < csvArray.length; row++) { + // hold different values coming from csv file + var mobile = csvArray[row][csvMap.mobile]; + var name = csvArray[row][csvMap.name]; + var reg = csvArray[row][csvMap.reg]; + var manuf = csvArray[row][csvMap.manuf]; + var model = csvArray[row][csvMap.model]; - function getDocuments() { - var tracker = $q.defer(); - var documents = []; - pdbCustomers.getAll().then(docFound).catch(failure); - return tracker.promise; + // check if at least one entry has been found, skip otherwise + if (!(mobile || name || reg || manuf || model)) + continue; - function docFound(res) { - res.rows.forEach(iterateDocuments); - tracker.resolve(documents); + // encode objects from derived data + var user = { + mobile: mobile ? mobile : '', + name: name ? utils.convertToTitleCase(name) : '' } - - function failure(err) { - tracker.reject(documents); + var vehicle = { + reg: reg ? reg.toUpperCase() : '', + manuf: manuf ? manuf : '', + model: model ? model : '' } - function iterateDocuments(element) { - documents.push(element.doc); + // reduce duplicates in imported file + var found = $filter('filter')(customers, { + name: name, + mobile: mobile + }, true); + if (found.length > 0) { + var vfound = $filter('filter')(found[0].vehicles, { + reg: reg + }, true); + if (vfound.length > 0) + continue; + else { + if ((reg || manuf || model) && (reg != '' || manuf != '' || model != '')) + found[0].vehicles.push(vehicle); + } + } else { + user.vehicles = []; + if ((reg || manuf || model) && (reg != '' || manuf != '' || model != '')) + user.vehicles.push(vehicle); + customers.push(user); } } + updateDatabase(customers); + function updateDatabase(customers) { + var addedCustomerCount = 0; getDocuments().then(matchAndUpdate).catch(failure); function matchAndUpdate(res) { - var addedCustomerCount = 0; var customersToSave = []; - tracker.notify({ - current: 0, - total: customers.length - }); customers.forEach(iterateCustomers); function iterateCustomers(customer) { @@ -186,7 +444,7 @@ existingVehicleInDb = true; } if (!existingVehicleInDb) { - var prefixVehicle = 'vhcl' + ((vehicle.manuf && vehicle.model) ? '-' + angular.lowercase(vehicle.manuf).replace(' ', '-') + '-' + angular.lowercase(vehicle.model).replace(' ', '-') : ''); + var prefixVehicle = 'vhcl'; dbUser.user.vehicles[utils.generateUUID('vhcl')] = vehicle; } } @@ -196,7 +454,8 @@ var prefixUser = 'usr-' + angular.lowercase(customer.name).replace(' ', '-'); targetUser = { _id: utils.generateUUID(prefixUser), - creator: $amRoot.username + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel }; targetUser.user = $.extend({}, customer); if (customer.vehicles && customer.vehicles.length > 0) { @@ -204,28 +463,23 @@ customer.vehicles.forEach(iterateVehicles); function iterateVehicles(vehicle) { - var prefixVehicle = 'vhcl' + ((vehicle.manuf && vehicle.model) ? '-' + angular.lowercase(vehicle.manuf).replace(' ', '-') + '-' + angular.lowercase(vehicle.model).replace(' ', '-') : ''); + var prefixVehicle = 'vhcl'; targetUser.user.vehicles[utils.generateUUID(prefixVehicle)] = vehicle; } } else delete targetUser.user.vehicles; addedCustomerCount++; } - tracker.notify({ - current: addedCustomerCount, - total: customers.length - }); customersToSave.push(targetUser); } - pdbCustomers.saveAll(customersToSave).then(saveSuccess).catch(failure); - tracker.resolve({ - success: true, - message: addedCustomerCount + " customer(s) added!" - }); + pdbMain.saveAll(customersToSave).then(saveSuccess).catch(failure); } function saveSuccess(res) { - $log.info('Import Successfull!'); + tracker.resolve({ + success: true, + message: addedCustomerCount + ' customers have been imported!' + }) } function failure(error) { @@ -235,6 +489,28 @@ }); } } + + function getDocuments() { + var tracker = $q.defer(); + var documents = []; + pdbMain.getAll().then(docFound).catch(failure); + return tracker.promise; + + function docFound(res) { + res.rows.forEach(iterateDocuments); + tracker.resolve(documents); + } + + function failure(err) { + tracker.reject(documents); + } + + function iterateDocuments(element) { + if ($rootScope.amGlobals.IsConfigDoc(element.id)) + return; + documents.push(element.doc); + } + } } function cleanUp() { diff --git a/src/app/components/settings/settings-invoices.factory.js b/src/app/components/settings/settings-invoices.factory.js index eddbc959..4658fc73 100644 --- a/src/app/components/settings/settings-invoices.factory.js +++ b/src/app/components/settings/settings-invoices.factory.js @@ -2,7 +2,7 @@ * Factory to fetch and retrieve invoice settings from database * @author ndkcha * @since 0.5.0 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -11,9 +11,9 @@ angular.module('automintApp') .factory('amIvSettings', IvSettingsFactory); - IvSettingsFactory.$inject = ['$q', '$amRoot', 'utils', 'pdbConfig']; + IvSettingsFactory.$inject = ['$q', '$rootScope', 'pdbMain']; - function IvSettingsFactory($q, $amRoot, utils, pdbConfig) { + function IvSettingsFactory($q, $rootScope, pdbMain) { // initialize factory and function mappings var factory = { getWorkshopDetails: getWorkshopDetails, @@ -25,23 +25,75 @@ saveIvAlignMargins : saveIvAlignMargins, getIvAlignMargins: getIvAlignMargins, changeLastJobCardNo: changeLastJobCardNo, - changeLastEstimateNo: changeLastEstimateNo + changeLastEstimateNo: changeLastEstimateNo, + saveInvoicePageSize: saveInvoicePageSize, + getInvoicePageSize: getInvoicePageSize } return factory; // function definitions + + function saveInvoicePageSize(pageSize) { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(writeSettingsDoc); + return tracker.promise; + + function getSettingsObject(res) { + if (!res.settings) + res.settings = {}; + if (!res.settings.invoices) + res.settings.invoices = {}; + res.settings.invoices.pageSize = pageSize; + pdbMain.save(res).then(success).catch(failure); + } + + function writeSettingsDoc(err) { + var doc = { + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, + settings: { + invoices: { + pageSize: pageSize + } + } + } + pdbMain.save(doc).then(success).catch(failure); + } + + function success(res) { + tracker.resolve(res); + } + + function failure(err) { + tracker.reject(err); + } + } + + function getInvoicePageSize() { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); + return tracker.promise; + + function getSettingsObject(res) { + if (res.settings && res.settings.invoices && res.settings.invoices.pageSize) + tracker.resolve(res.settings.invoices.pageSize); + else + failure('No PageSize Found!'); + } + + function failure(err) { + tracker.reject(err); + } + } // get workshop details from config database function getWorkshopDetails() { var tracker = $q.defer(); - $amRoot.isWorkshopId().then(getWorkshopDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.workshop).then(getWorkshopObject).catch(failure); return tracker.promise; - function getWorkshopDoc(res) { - pdbConfig.get($amRoot.docIds.workshop).then(getWorkshopObject).catch(failure); - } - function getWorkshopObject(res) { if (res.workshop) tracker.resolve(res.workshop); @@ -63,25 +115,22 @@ // save workshop details to config database function saveWorkshopDetails(workshop) { var tracker = $q.defer(); - $amRoot.isWorkshopId().then(getWorkshopDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.workshop).then(updateWorkshopDoc).catch(createWorkshopDoc); return tracker.promise; - function getWorkshopDoc(res) { - pdbConfig.get($amRoot.docIds.workshop).then(updateWorkshopDoc).catch(createWorkshopDoc); - } - function updateWorkshopDoc(res) { res.workshop = workshop; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } function createWorkshopDoc(err) { var doc = { - _id: utils.generateUUID('wrkshp'), - creator: $amRoot.username, + _id: $rootScope.amGlobals.configDocIds.workshop, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, workshop: workshop } - pdbConfig.save(doc).then(success).catch(failure); + pdbMain.save(doc).then(success).catch(failure); } function success(res) { @@ -96,13 +145,9 @@ // get invoice settings function getInvoiceSettings() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(failure); - } - function getSettingsObject(res) { if (res.settings && res.settings.invoices) tracker.resolve(res.settings.invoices); @@ -124,33 +169,30 @@ // save invoice display settings function saveIvDisplaySettings(display) { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(writeSettingsDoc); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(writeSettingsDoc); - } - function getSettingsObject(res) { if (!res.settings) res.settings = {}; if (!res.settings.invoices) res.settings.invoices = {}; res.settings.invoices.display = display; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } function writeSettingsDoc(err) { var doc = { - _id: utils.generateUUID('sttngs'), - creator: $amRoot.username, + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, settings: { invoices: { display: display } } } - pdbConfig.save(doc).then(success).catch(failure); + pdbMain.save(doc).then(success).catch(failure); } function success(res) { @@ -163,33 +205,30 @@ function changeLastJobCardNo(jobcardno) { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(writeSettingsDoc); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(writeSettingsObject); - } - function getSettingsObject(res) { if (!res.settings) res.settings = {}; if (!res.settings.invoices) res.settings.invoices = {}; res.settings.invoices.lastJobCardNo = jobcardno; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } - function writeSettingsObject(err) { + function writeSettingsDoc(err) { var doc = { - _id: utils.generateUUID('sttngs'), - creator: $amRoot.username, + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, settings: { invoices: { lastJobCardNo: jobcardno } } } - pdbConfig.save(doc).then(success).catch(failure); + pdbMain.save(doc).then(success).catch(failure); } function success(res) { @@ -203,33 +242,30 @@ function changeLastEstimateNo(estimateno) { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(writeSettingsDoc); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(writeSettingsObject); - } - function getSettingsObject(res) { if (!res.settings) res.settings = {}; if (!res.settings.invoices) res.settings.invoices = {}; res.settings.invoices.lastEstimateNo = estimateno; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } - function writeSettingsObject(err) { + function writeSettingsDoc(err) { var doc = { - _id: utils.generateUUID('sttngs'), - creator: $amRoot.username, + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, settings: { invoices: { lastEstimateNo: estimateno } } } - pdbConfig.save(doc).then(success).catch(failure); + pdbMain.save(doc).then(success).catch(failure); } function success(res) { @@ -244,33 +280,30 @@ // change last invoice number in database function changeLastInvoiceNo(invoiceno) { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(writeSettingsDoc); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(writeSettingsObject); - } - function getSettingsObject(res) { if (!res.settings) res.settings = {}; if (!res.settings.invoices) res.settings.invoices = {}; res.settings.invoices.lastInvoiceNumber = invoiceno; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } - function writeSettingsObject(err) { + function writeSettingsDoc(err) { var doc = { - _id: utils.generateUUID('sttngs'), - creator: $amRoot.username, + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, settings: { invoices: { lastInvoiceNumber: invoiceno } } } - pdbConfig.save(doc).then(success).catch(failure); + pdbMain.save(doc).then(success).catch(failure); } function success(res) { @@ -284,33 +317,30 @@ function saveIvEmailSubject(emailsubject) { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(writeSettingsDoc); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(writeSettingsObject); - } - function getSettingsObject(res) { if (!res.settings) res.settings = {}; if (!res.settings.invoices) res.settings.invoices = {}; res.settings.invoices.emailsubject = emailsubject; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } - function writeSettingsObject(err) { + function writeSettingsDoc(err) { var doc = { - _id: utils.generateUUID('sttngs'), - creator: $amRoot.username, + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, settings: { invoices: { emailsubject: emailsubject } } } - pdbConfig.save(doc).then(success).catch(failure); + pdbMain.save(doc).then(success).catch(failure); } function success(res) { @@ -324,33 +354,30 @@ function saveIvAlignMargins(margin) { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(writeSettingsDoc); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(writeSettingsDoc); - } - function getSettingsObject(res) { if (!res.settings) res.settings = {}; if (!res.settings.invoices) res.settings.invoices = {}; res.settings.invoices.margin = margin; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } function writeSettingsDoc(err) { var doc = { - _id: utils.generateUUID('sttngs'), - creator: $amRoot.username, + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, settings: { invoices: { margin: margin } } } - pdbConfig.save(doc).then(success).catch(failure); + pdbMain.save(doc).then(success).catch(failure); } function success(res) { @@ -364,13 +391,9 @@ function getIvAlignMargins() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(failure); - } - function getSettingsObject(res) { if (res.settings && res.settings.invoices && res.settings.invoices.margin) tracker.resolve(res.settings.invoices.margin); diff --git a/src/app/components/settings/settings-login.factory.js b/src/app/components/settings/settings-login.factory.js index f9bf978e..43de6712 100644 --- a/src/app/components/settings/settings-login.factory.js +++ b/src/app/components/settings/settings-login.factory.js @@ -2,22 +2,20 @@ * Factory to handle login events * @author ndkcha * @since 0.4.1 - * @version 0.6.1 + * @version 0.7.0 */ /// (function() { angular.module('automintApp') - .factory('amLogin', LoginFactory); + .factory('amLoginSettings', LoginFactory); - LoginFactory.$inject = ['$q', '$amRoot', 'utils', 'pdbConfig', 'pdbCustomers']; + LoginFactory.$inject = ['$q', '$rootScope', 'pdbMain']; - function LoginFactory($q, $amRoot, utils, pdbConfig, pdbCustomers) { + function LoginFactory($q, $rootScope, pdbMain) { // initialize factory variable and funtion maps var factory = { - login: login, - loginDetails: loginDetails, getPasscode: getPasscode, savePasscode: savePasscode } @@ -28,13 +26,9 @@ function getPasscode() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObj).catch(failure); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObj).catch(failure); - } - function getSettingsObj(res) { tracker.resolve(res.passcode); } @@ -46,31 +40,28 @@ function savePasscode(passcode, enabled) { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObj).catch(writeSettingsObj); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObj).catch(writeSettingsObj); - } - function getSettingsObj(res) { res.passcode = { enabled: enabled, code: passcode }; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } function writeSettingsObj(err) { var doc = { - _id: utils.generateUUID('sttngs'), - creator: $amRoot.username, + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, passcode: { enabled: enabled, code: passcode } } - pdbConfig.save(doc).then(success).catch(failure); + pdbMain.save(doc).then(success).catch(failure); } function success(res) { @@ -81,100 +72,5 @@ tracker.reject(err); } } - - // get login details from database - function loginDetails() { - var tracker = $q.defer(); - $amRoot.isWorkshopId().then(workshopConfigFound).catch(failure); - return tracker.promise; - - function workshopConfigFound(res) { - pdbConfig.get($amRoot.docIds.workshop).then(configExists).catch(failure); - } - - function configExists(res) { - if (res.user && res.user.username && res.user.password) { - tracker.resolve({ - username: res.user.username - }); - } else - failure(); - } - - function failure(err) { - tracker.reject({ - success: false - }) - } - } - - // store login information into database - function login(username, password) { - var tracker = $q.defer(); - $amRoot.isWorkshopId().then(workshopConfigFound).catch(failure); - return tracker.promise; - - function workshopConfigFound(res) { - pdbConfig.get($amRoot.docIds.workshop).then(configExists).catch(noDocFound); - - function configExists(res) { - if (!res.user) - res.user = {}; - res.creator = $amRoot.username; - res.user['username'] = username; - res.user['password'] = password; - updateCreatorToDocs(username); - pdbConfig.save(res).then(success).catch(failure); - } - - function noDocFound(err) { - var doc = {}; - doc['_id'] = utils.generateUUID('wrkshp'); - doc.creator = $amRoot.username; - doc.user = { - username: username, - password: password - }; - updateCreatorToDocs(username); - pdbConfig.save(doc).then(success).catch(failure); - } - - function success(res) { - tracker.resolve(res); - } - } - - function failure(err) { - tracker.reject(err); - } - } - - // manually update creator to all (unsynced) documents - function updateCreatorToDocs(creator) { - pdbConfig.getAll().then(configFound).catch(failure); - pdbCustomers.getAll().then(customersFound).catch(failure); - - function configFound(res) { - res.rows.forEach(iterateConfigDoc); - - function iterateConfigDoc(element) { - element.doc['creator'] = creator; - pdbConfig.save(element.doc); - } - } - - function customersFound(res) { - res.rows.forEach(iterateCustomerDoc); - - function iterateCustomerDoc(element) { - element.doc['creator'] = creator; - pdbCustomers.save(element.doc); - } - } - - function failure(err) { - $log.warn('Cannot sync data'); - } - } } })(); \ No newline at end of file diff --git a/src/app/components/settings/settings-servicetax.factory.js b/src/app/components/settings/settings-servicetax.factory.js deleted file mode 100644 index 9f4a016d..00000000 --- a/src/app/components/settings/settings-servicetax.factory.js +++ /dev/null @@ -1,188 +0,0 @@ -/** - * Factory to fetch and retrieve service tax settings from database - * @author ndkcha - * @since 0.5.0 - * @version 0.6.1 - */ - -/// - -(function() { - angular.module('automintApp').factory('amSeTaxSettings', ServiceTaxSettings); - - ServiceTaxSettings.$inject = ['$q', '$amRoot', 'utils', 'pdbConfig']; - - function ServiceTaxSettings($q, $amRoot, utils, pdbConfig) { - // intialize factory variable and function maps - var factory = { - getServiceTaxSettings: getServiceTaxSettings, - saveServiceTaxSettings: saveServiceTaxSettings, - getVatSettings: getVatSettings, - saveVatSettings: saveVatSettings - } - - return factory; - - // function definitions - - function getServiceTaxSettings() { - var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); - return tracker.promise; - - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObj).catch(failure); - } - - function getSettingsObj(res) { - if (res.settings && res.settings.servicetax) { - tracker.resolve({ - applyTax: res.settings.servicetax.applyTax, - inclusive: (res.settings.servicetax.taxIncType == 'inclusive') ? true : false, - tax: res.settings.servicetax.tax - }); - } else - failure(); - } - - function failure(err) { - if (!err) { - err = { - success: false, - message: 'Service Tax Settings Not Found!' - } - } - tracker.reject(err); - } - } - - function saveServiceTaxSettings(taxObject) { - var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); - return tracker.promise; - - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObj).catch(writeSettingsDoc); - } - - function getSettingsObj(res) { - if (!res.settings) - res.settings = {}; - if (!res.settings.servicetax) - res.settings.servicetax = {}; - if (taxObject.applyTax != undefined) - res.settings.servicetax.applyTax = taxObject.applyTax; - if (taxObject.inclusive != undefined) - res.settings.servicetax.taxIncType = (taxObject.inclusive) ? 'inclusive' : 'exclusive'; - if (taxObject.tax != undefined) - res.settings.servicetax.tax = taxObject.tax; - pdbConfig.save(res).then(success).catch(failure); - } - - function writeSettingsDoc(err) { - var doc = { - _id: utils.generateUUID('sttngs'), - creator: $amRoot.username, - settings: { - servicetax: {} - } - } - if (taxObject.applyTax) - doc.settings.servicetax.applyTax = taxObject.applyTax; - if (taxObject.inclusive) - doc.settings.servicetax.taxIncType = (taxObject.inclusive) ? 'inclusive' : 'exclusive'; - if (taxObject.tax) - doc.settings.servicetax.tax = taxObject.tax; - pdbConfig.save(doc).then(success).catch(failure); - } - - function success(res) { - tracker.resolve(res); - } - - function failure(err) { - tracker.reject(err); - } - } - - function getVatSettings() { - var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); - return tracker.promise; - - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObj).catch(failure); - } - - function getSettingsObj(res) { - if (res.settings && res.settings.vat) { - tracker.resolve({ - applyTax: res.settings.vat.applyTax, - inclusive: (res.settings.vat.taxIncType == 'inclusive') ? true : false, - tax: res.settings.vat.tax - }); - } else - failure(); - } - - function failure(err) { - if (!err) { - err = { - success: false, - message: 'VAT Settings Not Found!' - } - } - tracker.reject(err); - } - } - - function saveVatSettings(taxObject) { - var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); - return tracker.promise; - - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObj).catch(writeSettingsDoc); - } - - function getSettingsObj(res) { - if (!res.settings) - res.settings = {}; - if (!res.settings.vat) - res.settings.vat = {}; - if (taxObject.applyTax != undefined) - res.settings.vat.applyTax = taxObject.applyTax; - if (taxObject.inclusive != undefined) - res.settings.vat.taxIncType = (taxObject.inclusive) ? 'inclusive' : 'exclusive'; - if (taxObject.tax != undefined) - res.settings.vat.tax = taxObject.tax; - pdbConfig.save(res).then(success).catch(failure); - } - - function writeSettingsDoc(err) { - var doc = { - _id: utils.generateUUID('sttngs'), - creator: $amRoot.username, - settings: { - vat: {} - } - } - if (taxObject.applyTax) - doc.settings.vat.applyTax = taxObject.applyTax; - if (taxObject.inclusive) - doc.settings.vat.taxIncType = (taxObject.inclusive) ? 'inclusive' : 'exclusive'; - if (taxObject.tax) - doc.settings.vat.tax = taxObject.tax; - pdbConfig.save(doc).then(success).catch(failure); - } - - function success(res) { - tracker.resolve(res); - } - - function failure(err) { - tracker.reject(err); - } - } - } -})(); \ No newline at end of file diff --git a/src/app/components/settings/settings-tax.factory.js b/src/app/components/settings/settings-tax.factory.js new file mode 100644 index 00000000..1387e52c --- /dev/null +++ b/src/app/components/settings/settings-tax.factory.js @@ -0,0 +1,126 @@ +/** + * Factory to fetch and retrieve service tax settings from database + * @author ndkcha + * @since 0.5.0 + * @version 0.7.0 + */ + +/// + +(function() { + angular.module('automintApp').factory('amTaxSettings', TaxSettings); + + TaxSettings.$inject = ['$q', '$rootScope', 'pdbMain']; + + function TaxSettings($q, $rootScope, pdbMain) { + // intialize factory variable and function maps + var factory = { + getAllTaxSettings: getAllTaxSettings, + saveTaxSettings: saveTaxSettings, + deleteTaxSettings: deleteTaxSettings + } + + return factory; + + // function definitions + + function deleteTaxSettings(tax) { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObj).catch(failure); + return tracker.promise; + + function getSettingsObj(res) { + if (res.settings && res.settings.tax && res.settings.tax[tax.name]) { + delete res.settings.tax[tax.name]; + pdbMain.save(res).then(success).catch(failure); + } + } + + function success(res) { + tracker.resolve(res); + } + + function failure(err) { + tracker.reject(err); + } + } + + function saveTaxSettings(tax) { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObj).catch(writeSettingsDoc); + return tracker.promise; + + function getSettingsObj(res) { + if (!res.settings) + res.settings = {}; + if (res.settings && !res.settings.tax) + res.settings.tax = {}; + res.settings.tax[tax.name] = { + type: (tax.inclusive) ? "inclusive" : "exclusive", + isTaxApplied: tax.isTaxApplied, + isForTreatments: tax.isForTreatments, + isForInventory: tax.isForInventory, + percent: tax.percent + }; + pdbMain.save(res).then(success).catch(failure); + } + + function writeSettingsDoc(err) { + var doc = { + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, + settings: { + tax: {} + } + } + doc.settings.tax[tax.name] = { + type: (tax.inclusive) ? "inclusive" : "exclusive", + isTaxApplied: tax.isTaxApplied, + isForTreatments: tax.isForTreatments, + isForInventory: tax.isForInventory, + percent: tax.percent + } + pdbMain.save(doc).then(success).catch(failure); + } + + function success(res) { + tracker.resolve(res); + } + + function failure(err) { + tracker.reject(err); + } + } + + function getAllTaxSettings() { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObj).catch(failure); + return tracker.promise; + + function getSettingsObj(res) { + var result = []; + if (res.settings && res.settings.tax) { + Object.keys(res.settings.tax).forEach(iterateTax); + + function iterateTax(tax) { + var t = res.settings.tax[tax]; + result.push({ + inclusive: (t.type == "inclusive"), + isTaxApplied: t.isTaxApplied, + isForTreatments: t.isForTreatments, + isForInventory: t.isForInventory, + percent: t.percent, + name: tax + }); + } + } + tracker.resolve(result); + } + + function failure(err) { + tracker.reject(err); + } + } + } +})(); \ No newline at end of file diff --git a/src/app/components/settings/settings.controller.js b/src/app/components/settings/settings.controller.js index 0377f9f3..618eea02 100644 --- a/src/app/components/settings/settings.controller.js +++ b/src/app/components/settings/settings.controller.js @@ -2,33 +2,41 @@ * Controller for Settings component * @author ndkcha * @since 0.4.1 - * @version 0.6.4 + * @version 0.7.0 */ /// (function() { - angular.module('automintApp') - .controller('amCtrlSettings', SettingsController); + const ipcRenderer = require('electron').ipcRenderer; + const electron = require('electron').remote; + const fse = require('fs-extra'); + const amApp = electron.app; + const dialog = electron.dialog; + const ammPreferences = require('./automint_modules/am-preferences.js'); - SettingsController.$inject = ['$rootScope', '$scope', '$state', '$log', 'utils', 'amBackup', 'amLogin', 'amImportdata', 'amIvSettings', 'amSeTaxSettings', 'amSettings']; + angular.module('automintApp').controller('amCtrlSettings', SettingsController); - function SettingsController($rootScope, $scope, $state, $log, utils, amBackup, amLogin, amImportdata, amIvSettings, amSeTaxSettings, amSettings) { + SettingsController.$inject = ['$rootScope', '$scope', '$state', '$log', '$mdDialog', '$amLicense', '$amRoot', 'utils', 'amBackup', 'amLoginSettings', 'amImportdata', 'amIvSettings', 'amTaxSettings', 'amSettings', 'amLogin']; + + function SettingsController($rootScope, $scope, $state, $log, $mdDialog, $amLicense, $amRoot, utils, amBackup, amLoginSettings, amImportdata, amIvSettings, amTaxSettings, amSettings, amLogin) { // initialize view model var vm = this; - + // temporary named assignments - var olino = 0, - oljbno = 0, - oleno = 0, - oPasscode = '1234', - oPasscodeEnabled, - oIvAlignTop = '', - oIvAlignBottom = '', - ivEmailSubject, oIvFacebookLink, oIvInstagramLink, oIvTwitterLink, oIvWorkshopName, oIvWorkshopPhone, oIvWorkshopAddress1, oIvWorkshopAddress2, oIvWorkshopCity, oDefaultServiceType; + var olino = 0, + oljbno = 0, + oleno = 0; + var oPasscode = '1234', + oPasscodeEnabled; + var oIvAlignTop = '', + oIvAlignBottom = ''; + var ivEmailSubject, oIvFacebookLink, oIvInstagramLink, oIvTwitterLink, oIvWorkshopName, oIvWorkshopPhone, oIvWorkshopAddress1, oIvWorkshopAddress2, oIvWorkshopCity, oDefaultServiceType; + var currentTaxFocusIndex = -1; + var csMessage, + isAutomintLoggedIn; // named assignments to keep track of UI [BEGIN] - // general settings vm.user = { username: '', password: '' @@ -37,7 +45,7 @@ vm.label_password = 'Enter Password:'; vm.serviceStateList = ['Job Card', 'Estimate', 'Bill']; vm.serviceState = vm.serviceStateList[2]; - // invoice settings + vm.amAppPath = 'Default'; vm.workshop = { name: '', phone: '', @@ -62,22 +70,34 @@ }; vm.label_ivAlignTopAlignment = 'Enter Top Margin:'; vm.label_ivAlignBottomAlignment = 'Enter Bottom Margin:'; + vm.taxSettings = []; + vm.currencySymbol = "Rs."; + vm.invoicePageSizeList = ['Single Page', 'A4']; + vm.invoicePageSize = vm.invoicePageSizeList[1]; + vm.cloudSettings = { + username: '', + password: '', + message: undefined, + enable: false, + isLicensed: false, + cloudenddate: undefined, + isCloudEnabled: false + }; + vm.isLoginBoxOpen = false; // named assignments to keep track of UI [END] - + // function maps [BEGIN] vm.changeInvoiceTab = changeInvoiceTab; - // general settings vm.changeUsernameLabel = changeUsernameLabel; vm.changePasswordLabel = changePasswordLabel; vm.doBackup = doBackup; - vm.doLogin = doLogin; vm.uploadCSV = uploadCSV; vm.uploadCover = uploadCover; vm.handleUploadedFile = handleUploadedFile; vm.handleUploadedCoverPic = handleUploadedCoverPic; vm.handlePasscodeVisibility = handlePasscodeVisibility; vm.saveDefaultServiceType = saveDefaultServiceType; - // invoice settings + vm.setAmAppDataPath = setAmAppDataPath; vm.changeWorkshopNameLabel = changeWorkshopNameLabel; vm.changeWorkshopPhoneLabel = changeWorkshopPhoneLabel; vm.changeWorkshopAddress1Label = changeWorkshopAddress1Label; @@ -93,8 +113,6 @@ vm.saveFacebookLink = saveFacebookLink; vm.saveInstagramLink = saveInstagramLink; vm.saveTwitterLink = saveTwitterLink; - vm.saveServiceTaxSettings = saveServiceTaxSettings; - vm.saveVatSettings = saveVatSettings; vm.savePasscode = savePasscode; vm.changeTopAlignLabel = changeTopAlignLabel; vm.changeBottomAlignLabel = changeBottomAlignLabel; @@ -113,6 +131,23 @@ vm.autoCapitalizeAddressLine2 = autoCapitalizeAddressLine2; vm.autoCapitalizeWorkshopName = autoCapitalizeWorkshopName; vm.autoCapitalizeEmailSubject = autoCapitalizeEmailSubject; + vm.addNewTax = addNewTax; + vm.deleteTax = deleteTax; + vm.saveTax = saveTax; + vm.autoCapitalizeName = autoCapitalizeName; + vm.IsTaxFocused = IsTaxFocused; + vm.saveCurrencySymbol = saveCurrencySymbol; + vm.saveInvoicePageSize = saveInvoicePageSize; + vm.changeInvoiceFLogo = changeInvoiceFLogo; + vm.uploadInvoiceFLogo = uploadInvoiceFLogo; + vm.changeCloudTab = changeCloudTab; + vm.cloudSettings.OnKeyDown = csOnKeyDown; + vm.cloudSettings.changeUserDetails = csChangeuserDetails; + vm.cloudSettings.submit = csSubmit; + vm.cloudSettings.changeAvailability = csChangeAvailability; + vm.cloudSettings.changePassword = csChangePassword; + + $rootScope.loadSettingsBlock = loadBlock; // function maps [END] // default execution steps [BEGIN] @@ -123,23 +158,367 @@ default: break; } - // general settings - checkLogin(); - getPasscode(); - getDefaultServiceType(); - // invoice settings - getWorkshopDetails(); - getInvoiceSettings(); - loadInvoiceWLogo(); - getIvAlignMargins(); - // service tax settings - getServiceTaxSettings(); - getVatSettings(); - // changeInvoiceTab(true) // testing purposes amTODO: remove it + loadBlock(); // default execution steps [END] // function definitions + function loadBlock() { + if ($rootScope.busyApp.show == true) + $rootScope.busyApp.message = 'Loading Data'; + getPasscode(); + getDefaultServiceType(); + getAmAppDataPath(); + getWorkshopDetails(); + getInvoiceSettings(); + loadInvoiceWLogo(); + loadInvoiceFLogo(); + getIvAlignMargins(); + getAllTaxSettings(); + getCurrencySymbol(); + getInvoicePageSize(); + // changeCloudTab(true) // testing purposes amTODO: remove it + getLoginState(); + // changeInvoiceTab(true) // testing purposes amTODO: remove it + // changeTaxTab(true); // testing purposes amTODO: remove it + } + + function csChangePassword(event) { + $mdDialog.show({ + controller: 'amCtrlSeChPwd', + controllerAs: 'vm', + templateUrl: 'app/components/settings/tmpl/changepassword.html', + parent: angular.element(document.body), + targetEvent: event, + clickOutsideToClose: true + }).then(success).catch(success); + + function success(res) { + if (res == true) { + if ($rootScope.amDbSync) + $rootScope.amDbSync.cancel(); + $amRoot.syncDb(); + getLoginState(); + } + } + } + + function csChangeAvailability() { + vm.isLoginBoxOpen = vm.cloudSettings.enable; + if (vm.cloudSettings.isLicensed && vm.cloudSettings.isCloudEnabled) + amLogin.cloudForceEnabled(vm.cloudSettings.enable).then(success).catch(failure); + + function success(res) { + if (vm.cloudSettings.enable == true) { + if ($rootScope.amDbSync) + $rootScope.amDbSync.cancel(); + $amRoot.syncDb(); + } else if ($rootScope.amDbSync) + $rootScope.amDbSync.cancel(); + vm.cloudSettings.isCloudForceEnabled = vm.cloudSettings.enable; + + utils.showSimpleToast('Automint Cloud Services has been ' + (vm.cloudSettings.enable ? 'enabled' : 'disabled') + ' successfully'); + } + + function failure(failure) { + utils.showSimpleToast('Could not ' + (vm.cloudSettings.enable ? 'enable' : 'disable') +' Audomint Cloud Service at moment! Please Try Again!'); + vm.cloudSettings.enable = vm.cloudSettings.isCloudForceEnabled; + } + } + + function getLoginState() { + $amLicense.checkLogin(false).then(success).catch(failure); + + function success(res) { + vm.cloudSettings.enable = ((res.isCloudEnabled != undefined) ? res.isCloudEnabled : false); + if (vm.cloudSettings.enable == true) + vm.cloudSettings.isCloudForceEnabled = ((res.isCloudForceEnabled != undefined) ? res.isCloudForceEnabled : vm.cloudSettings.enable); + vm.cloudSettings.enable = vm.cloudSettings.isCloudForceEnabled; + vm.cloudSettings.isCloudEnabled = res.isCloudEnabled; + vm.cloudSettings.isLicensed = ((res.isLoggedIn == true) && (res.type == 'license')); + vm.cloudSettings.cloudenddate = ((res.cloudenddate != undefined) ? res.cloudenddate : undefined); + if (res.type != 'license') + csMessage = 'You need to login to enable Automint Cloud Services'; + else { + vm.cloudSettings.username = $rootScope.amGlobals.credentials.username; + if (res.cloudenddate) { + var ced = moment(res.cloudenddate, 'YYYY-MM-DD').format('D MMMM YYYY'); + csMessage = (res.isCloudEnabled == true) ? ('Your license expires on ' + ced) : ('Your license has expired on ' + ced + '. Please contact Automint Care to extend it'); + } + } + vm.cloudSettings.message = csMessage; + vm.isLoginBoxOpen = vm.cloudSettings.enable; + } + + function failure(err) { + $rootScope.busyApp.show = true; + $rootScope.busyApp.message = err; + $rootScope.busyApp.isRaEnabled = true; + setTimeout(restartApp, 1000); + + function restartApp(res) { + ipcRenderer.send('am-do-restart', true); + } + console.error(err); + } + } + + function csSubmit() { + if ((vm.cloudSettings.username == '') && (vm.cloudSettings.password == '')) { + vm.cloudSettings.message = 'Please Enter Username and Password!'; + return; + } + if ((vm.cloudSettings.username != '') && (vm.cloudSettings.password == '')) { + vm.cloudSettings.message = 'Please Enter Password!'; + return; + } + if ((vm.cloudSettings.password != '') && (vm.cloudSettings.username == '')) { + vm.cloudSettings.message = 'Please Enter Username!'; + return; + } + + $rootScope.busyApp.show = true; + $rootScope.busyApp.message = 'Loging In'; + $amLicense.loadCredentials(vm.cloudSettings.username, vm.cloudSettings.password); + $amLicense.login(false).then(success).catch(failure); + + function success(res) { + if (res.isLoggedIn) { + vm.cloudSettings.isLicensed = (res.isLoggedIn == true); + if (res.isSyncableDb) { + $rootScope.isSyncCalledFromSettings = true; + $amRoot.syncDb(); + $rootScope.busyApp.message = 'Syncing'; + } else + $rootScope.busyApp.show = false; + } else + getLoginState(); + } + + function failure(err) { + $rootScope.busyApp.show = false; + vm.cloudSettings.message = err.message; + } + } + + function csChangeuserDetails() { + vm.cloudSettings.message = csMessage; + } + + function csOnKeyDown(event) { + if (event.keyCode == 13) + csSubmit(); + } + + function changeCloudTab(bool) { + vm.cloudTab = true; + } + + function uploadInvoiceFLogo() { + angular.element(document.querySelector('#am-upload-invoice-f-logo')).click(); + } + + function changeInvoiceFLogo(e) { + var files = e.target.files; + if (!files[0].type.match(/image/g)) { + utils.showSimpleToast('Please upload photo'); + return; + } + if (files && files[0]) { + var reader = new FileReader(); + + reader.onload = loadReader; + reader.readAsDataURL(files[0]); + } + + function loadReader(e) { + $('#am-invoice-f-logo').attr('src', e.target.result); + var footerPic = document.getElementById('am-invoice-f-logo'); + var ic = document.createElement('canvas'), + icontext = ic.getContext('2d'); + ic.width = footerPic.width; + ic.height = footerPic.height; + icontext.drawImage(footerPic, 0, 0, footerPic.width, footerPic.height); + localStorage.setItem('invoice-f-pic', ic.toDataURL(files[0].type)); + loadInvoiceFLogo(); + } + } + + // load workshop logo in invoice settings + function loadInvoiceFLogo() { + var source = localStorage.getItem('invoice-f-pic'); + vm.invoiceFLogo = source; + } + + function getInvoicePageSize() { + amIvSettings.getInvoicePageSize().then(success).catch(failure); + + function success(res) { + vm.invoicePageSize = res; + } + + function failure(err) { + vm.invoicePageSize = vm.invoicePageSizeList[0]; + } + } + + function saveInvoicePageSize() { + amIvSettings.saveInvoicePageSize(vm.invoicePageSize).then(success).catch(failure); + + function success(res) { + if (res.ok) + utils.showSimpleToast('Invoice settings saved successfully'); + else + failure(); + } + + function failure(err) { + utils.showSimpleToast('Could not save invoice settings! Please try again!'); + } + } + + function getCurrencySymbol() { + amSettings.getCurrencySymbol().then(success).catch(failure); + + function success(res) { + vm.currencySymbol = res; + } + + function failure(err) { + vm.currencySymbol = "Rs."; + } + } + + function saveCurrencySymbol() { + if ((vm.currencySymbol == '') || (vm.currencySymbol == undefined)) + vm.currencySymbol = "Rs."; + amSettings.saveCurrencySymbol(vm.currencySymbol).then(success).catch(failure); + + function success(res) { + if (res.ok) + utils.showSimpleToast('Currency saved successfully!'); + else + failure(); + } + + function failure(err) { + utils.showSimpleToast('Could not save Currency at moment! Try Again Later!'); + } + } + + function IsTaxFocused(index) { + return (currentTaxFocusIndex == index); + } + + function autoCapitalizeName(tax) { + tax.name = utils.autoCapitalizeWord(tax.name); + } + + function getAllTaxSettings() { + amTaxSettings.getAllTaxSettings().then(success).catch(failure); + + function success(res) { + if (angular.isArray(res)) + vm.taxSettings = res; + else + failure('No Taxes Found!'); + } + + function failure(err) { + // do nothing + } + } + + function saveTax(tax) { + if ((tax.name == '') || (tax.name == undefined)) { + utils.showSimpleToast('Please enter name of tax in order to save it!'); + return; + } + amTaxSettings.saveTaxSettings(tax).then(success).catch(failure); + + function success(res) { + if (res.ok) + utils.showSimpleToast(tax.name + ' settings saved successfully!'); + else + failure(); + } + + function failure(err) { + utils.showSimpleToast('Could not save ' + tax.name + ' settings. Try Again Later!'); + } + } + + function deleteTax(tax) { + if (tax.name == '') { + var index = vm.taxSettings.indexOf(tax); + vm.taxSettings.splice(index, 1); + return; + } + amTaxSettings.deleteTaxSettings(tax).then(success).catch(failure); + + function success(res) { + if (res.ok) { + utils.showSimpleToast(tax.name + ' deleted successfully!'); + getAllTaxSettings(); + } else + failure(); + } + + function failure(err) { + utils.showSimpleToast('Could not delete ' + tax.name + ' settings. Try Again Later!'); + } + } + + function addNewTax() { + vm.taxSettings.push({ + name: '', + isTaxApplied: false, + inclusive: false, + percent: 0, + isForTreatments: false, + isForInventory: false + }); + currentTaxFocusIndex = vm.taxSettings.length - 1; + } + + function changeTaxTab(bool) { + vm.taxTab = bool; + } + + function setAmAppDataPath(move) { + var newPath = dialog.showOpenDialog({ + properties: ['openDirectory'] + }); + if (newPath) { + $rootScope.busyApp.show = true; + $rootScope.busyApp.message = 'Restarting App. Please Wait..'; + ammPreferences.storePreference('automint.userDataPath', newPath[0]); + if (move) { + fse.copy(amApp.getPath('userData'), newPath[0], { + clobber: true + }, success); + } else + removeSuccess(); + } + + function success(res) { + if (res) + console.error(res); + fse.remove(amApp.getPath('userData'), removeSuccess); + } + + function removeSuccess(err) { + if (err) + console.error(err); + ipcRenderer.send('am-do-restart', true); + } + // /Users/ndkcha/Library/Application Support/Automint + } + + function getAmAppDataPath() { + vm.amAppPath = amApp.getPath('userData'); + } + function getDefaultServiceType() { amSettings.getDefaultServiceType().then(success).catch(failure); @@ -221,7 +600,7 @@ function resetLastEstimateNo(estimateno, reset) { amIvSettings.changeLastEstimateNo((estimateno == undefined) ? 0 : estimateno).then(respond).catch(respond); - + function respond(res) { getInvoiceSettings(); if (reset != true) @@ -266,7 +645,6 @@ } function failure(err) { - console.warn(err); utils.showSimpleToast('Could not save margin! Please Try Again!'); } } @@ -286,7 +664,7 @@ } function getPasscode() { - amLogin.getPasscode().then(success).catch(failure); + amLoginSettings.getPasscode().then(success).catch(failure); function success(res) { if (!res) { @@ -315,7 +693,7 @@ } if (vm.passcode == oPasscode && vm.isPasscodeEnabled == oPasscodeEnabled) return; - amLogin.savePasscode(vm.passcode, vm.isPasscodeEnabled).then(success).catch(failure); + amLoginSettings.savePasscode(vm.passcode, vm.isPasscodeEnabled).then(success).catch(failure); function success(res) { if (res.ok) { @@ -349,12 +727,12 @@ return; saveWorkshopDetails(); } - + // default tab settings function changeInvoiceTab(bool) { vm.invoiceTab = bool; } - + function OnBlurLastInvoiceNumber(ar, arg) { if (vm.ivSettings.lastInvoiceNumber == '' || vm.ivSettings.lastInvoiceNumber == null || vm.ivSettings.lastInvoiceNumber == undefined) vm.ivSettings.lastInvoiceNumber = 0; @@ -362,13 +740,14 @@ return; resetLastInvoiceNo(vm.ivSettings.lastInvoiceNumber); } - + // listen to changes in input fields [BEGIN] // general settings function changeUsernameLabel(force) { vm.isUsername = (force != undefined || vm.user.username != ''); vm.label_username = vm.isUsername ? 'Username:' : 'Enter Username:'; } + function changePasswordLabel(force) { vm.isPassword = (force != undefined || vm.user.password != ''); vm.label_password = vm.isPassword ? 'Password:' : 'Enter Password:'; @@ -378,18 +757,22 @@ vm.isWorkshopName = (force != undefined || vm.workshop.name != ''); vm.label_workshopName = vm.isWorkshopName ? 'Workshop Name:' : 'Enter Workshop Name:'; } + function changeWorkshopPhoneLabel(force) { vm.isWorkshopPhone = (force != undefined || vm.workshop.phone != ''); vm.label_workshopPhone = vm.isWorkshopPhone ? 'Phone Number:' : 'Enter Phone Number:'; } + function changeWorkshopAddress1Label(force) { vm.isWorkshopAddress1 = (force != undefined || vm.workshop.address1 != ''); vm.label_workshopAddress1 = vm.isWorkshopAddress1 ? 'Address Line 1:' : 'Enter Address Line 1:'; } + function changeWorkshopAddress2Label(force) { vm.isWorkshopAddress2 = (force != undefined || vm.workshop.address2 != ''); vm.label_workshopAddress2 = vm.isWorkshopAddress2 ? 'Address Line 2:' : 'Enter Address Line 2:'; } + function changeWorkshopCityLabel(force) { vm.isWorkshopCity = (force != undefined || vm.workshop.city != ''); vm.label_workshopCity = vm.isWorkshopCity ? 'City:' : 'Enter City:'; @@ -401,6 +784,7 @@ function uploadCSV() { angular.element(document.querySelector('#csv-file-select')).click(); } + function uploadCover() { angular.element(document.querySelector('#am-upload-cover-pic')).click(); } @@ -440,23 +824,18 @@ // callback function to import csv files function handleUploadedFile(e) { - vm.currentCsvProgress = 0; + vm.isCsvProcessed = true; var files = e.target.files || e.originalEvent.dataTransfer.files; - amImportdata.compileCSVFile(files).then(displayToastMessage).catch(displayToastMessage).finally(cleanUp, updates); + amImportdata.checkTypeofFile(files).then(displayToastMessage).catch(displayToastMessage).finally(cleanUp); function displayToastMessage(res) { utils.showSimpleToast(res.message); - vm.currentCsvProgress = 100; - vm.isCsvProcessed = (vm.currentCsvProgress < 100); + vm.isCsvProcessed = false; } function cleanUp(res) { amImportdata.cleanUp(); - } - - function updates(res) { - vm.currentCsvProgress = (res.total == 0) ? 0 : ((res.current * 100) / res.total); - vm.isCsvProcessed = (vm.currentCsvProgress < 100); + loadBlock(); } } @@ -470,44 +849,11 @@ } } - // check if user is signed in or not - function checkLogin() { - amLogin.loginDetails().then(success).catch(failure); - - function success(res) { - if (res.username) { - vm.isLoggedIn = true; - vm.label_login = 'You are signed in'; - vm.user.username = res.username; - changeUsernameLabel(); - } else - failure(); - } - - function failure() { - vm.isLoggedIn = false; - vm.label_login = 'Sign In'; - } - } - - // store user's login information in database - function doLogin() { - amLogin.login(vm.user.username, vm.user.password).then(success); - - function success(res) { - if (res.ok) { - vm.isLoggedIn = true; - vm.label_login = 'You are signed in'; - utils.showSimpleToast('You have successfully logged in!'); - } - } - } - // functions defined for invoice settings // get workshop details from database function getWorkshopDetails() { amIvSettings.getWorkshopDetails().then(getWorkshopObject).catch(failure); - + function getWorkshopObject(res) { vm.workshop = res; oIvWorkshopName = res.name; @@ -524,9 +870,9 @@ changeWorkshopAddress2Label(); changeWorkshopCityLabel(); } - + function failure(err) { - $log.info('No workshop details found!'); + // do nothing } } @@ -559,11 +905,11 @@ return; saveWorkshopDetails(); } - + // save workshop details to database function saveWorkshopDetails() { amIvSettings.saveWorkshopDetails(vm.workshop).then(success).catch(failure); - + function success(res) { oIvWorkshopName = vm.workshop.name; oIvWorkshopPhone = vm.workshop.phone; @@ -575,16 +921,16 @@ oIvInstagramLink = vm.workshop.social.instagram; utils.showSimpleToast('Workshop details updated successfully!'); } - + function failure(err) { utils.showSimpleToast('Failied to update workshop details! Please Try Again!'); } } - + // get invoice settings function getInvoiceSettings() { amIvSettings.getInvoiceSettings().then(success).catch(failure); - + function success(res) { vm.ivSettings = res; if (!vm.ivSettings.lastJobCardNo) @@ -593,18 +939,18 @@ vm.ivSettings.lastEstimateNo = 0; if (!vm.ivSettings.lastInvoiceNumber) vm.ivSettings.lastInvoiceNumber = 0; - + olino = res.lastInvoiceNumber; oljbno = res.lastJobCardNo; oleno = res.lastEstimateNo; ivEmailSubject = res.emailsubject; } - + function failure(err) { - $log.info('Cannot find invoice settings!'); + // do nothing } } - + // change workshop logo in invoice settings function changeInvoiceWLogo(e) { var files = e.target.files; @@ -631,95 +977,42 @@ loadInvoiceWLogo(); } } - + // load workshop logo in invoice settings function loadInvoiceWLogo() { var source = localStorage.getItem('invoice-w-pic'); vm.invoiceWLogo = source; } - + // reset invoice number sequence function resetLastInvoiceNo(invoiceno, reset) { amIvSettings.changeLastInvoiceNo((invoiceno == undefined) ? 0 : invoiceno).then(respond).catch(respond); - + function respond(res) { getInvoiceSettings(); if (reset != true) utils.showActionToast('Invoice number has been ' + ((invoiceno == undefined) ? 'reset' : 'changed'), 'Undo', resetLastInvoiceNo, olino, true); } } - + // change display settings function saveIvDisplaySettings() { amIvSettings.saveIvDisplaySettings(vm.ivSettings.display).then(success).catch(failure); - - function success(res) { - utils.showSimpleToast('Settings saved successfully!'); - } - function failure(err) { - utils.showSimpleToast('Could not save settings at moment. Please try again!'); - } - } - - function getServiceTaxSettings() { - amSeTaxSettings.getServiceTaxSettings().then(success).catch(failure); - - function success(res) { - vm.sTaxSettings = res; - } - - function failure(err) { - vm.sTaxSettings = {}; - } - } - - function saveServiceTaxSettings() { - amSeTaxSettings.saveServiceTaxSettings(vm.sTaxSettings).then(success).catch(failure); - - function success(res) { - if (res.ok) - utils.showSimpleToast('Service Tax Settings Saved Successfully!'); - else - failure(); - } - - function failure(err) { - utils.showSimpleToast('Failed to save Service Tax Settings. Please Try Again!'); - } - } - - function getVatSettings() { - amSeTaxSettings.getVatSettings().then(success).catch(failure); function success(res) { - vm.vatSettings = res; + utils.showSimpleToast('Settings saved successfully!'); } function failure(err) { - vm.vatSettings = {}; + utils.showSimpleToast('Could not save settings at moment. Please try again!'); } } - function saveVatSettings() { - amSeTaxSettings.saveVatSettings(vm.vatSettings).then(success).catch(failure); - - function success(res) { - if (res.ok) - utils.showSimpleToast('VAT Settings Saved Successfully!'); - else - failure(); - } - - function failure(err) { - utils.showSimpleToast('Failed to save VAT Settings. Please Try Again!'); - } - } - function saveIvEmailSubject(es, reset) { if (vm.ivSettings.emailsubject == undefined || ((ivEmailSubject == vm.ivSettings.emailsubject) && !es)) return; amIvSettings.saveIvEmailSubject((es == undefined) ? vm.ivSettings.emailsubject : es).then(respond).catch(respond); - + function respond(res) { getInvoiceSettings(); if (ivEmailSubject != undefined) { diff --git a/src/app/components/settings/settings.factory.js b/src/app/components/settings/settings.factory.js index 7f4a0843..4ef4c175 100644 --- a/src/app/components/settings/settings.factory.js +++ b/src/app/components/settings/settings.factory.js @@ -2,7 +2,7 @@ * Factory to fetch and retrieve service tax settings from database * @author ndkcha * @since 0.6.4 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -10,27 +10,71 @@ (function() { angular.module('automintApp').factory('amSettings', SettingsFactory); - SettingsFactory.$inject = ['$q', '$amRoot', 'utils', 'pdbConfig']; + SettingsFactory.$inject = ['$q', '$rootScope', 'pdbMain']; - function SettingsFactory($q, $amRoot, utils, pdbConfig) { + function SettingsFactory($q, $rootScope, pdbMain) { var factory = { getDefaultServiceType: getDefaultServiceType, - saveDefaultServiceType: saveDefaultServiceType + saveDefaultServiceType: saveDefaultServiceType, + getCurrencySymbol: getCurrencySymbol, + saveCurrencySymbol: saveCurrencySymbol } return factory; // function definitions - function getDefaultServiceType() { + function getCurrencySymbol() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(failure); + function getSettingsObject(res) { + if (res.currency) + tracker.resolve(res.currency); + else + failure('No Currency Symbol Found!'); } + function failure(err) { + tracker.reject(err); + } + } + + function saveCurrencySymbol(currency) { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(writeSettingsObject); + return tracker.promise; + + function getSettingsObject(res) { + res.currency = currency; + pdbMain.save(res).then(success).catch(failure); + } + + function writeSettingsObject(err) { + var doc = { + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, + currency: currency + } + pdbMain.save(doc).then(success).catch(failure); + } + + function success(res) { + tracker.resolve(res); + } + + function failure(err) { + tracker.reject(err); + } + } + + function getDefaultServiceType() { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); + return tracker.promise; + function getSettingsObject(res) { if (res.settings && res.settings.servicestate) tracker.resolve(res.settings.servicestate); @@ -51,29 +95,26 @@ function saveDefaultServiceType(servicestate) { var tracker = $q.defer(); - $amRoot.isSettingsId().then(getSettingsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(writeSettingsObject); return tracker.promise; - function getSettingsDoc(res) { - pdbConfig.get($amRoot.docIds.settings).then(getSettingsObject).catch(writeSettingsObject); - } - function getSettingsObject(res) { if (!res.settings) res.settings = {}; res.settings.servicestate = servicestate; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } function writeSettingsObject(err) { var doc = { - _id: utils.generateUUID('sttngs'), - creator: $amRoot.username, + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel, settings: { servicestate: servicestate } } - pdbConfig.save(doc).then(success).catch(failure); + pdbMain.save(doc).then(success).catch(failure); } function success(res) { diff --git a/src/app/components/settings/settings.html b/src/app/components/settings/settings.html index 07cc8577..7d8c268c 100644 --- a/src/app/components/settings/settings.html +++ b/src/app/components/settings/settings.html @@ -11,29 +11,22 @@ .am-tax-inline-input { border: 0; - border-bottom: 1px solid black; - width: 97%; + border-bottom: 1px solid #BDBDBD; + min-width: 40px; font-weight: 400; - padding: 0.7rem; + padding: 6px; outline: none; background: transparent; - color: rgba(30, 30, 30, 0.7); - -webkit-transition: background 1s ease 0s, box-shadow 1s ease 0s, border-bottom 1s ease 0s; - -moz-transition: background 1s ease 0s, box-shadow 1s ease 0s, border-bottom 1s ease 0s; - transition: background 1s ease 0s, box-shadow 1s ease 0s, border-bottom 1s ease 0s; - box-shadow: 0px 1px 3px 1px rgba(30, 30, 30, 0); + color: #000; + transition: border-bottom 1s ease 0s; } .am-tax-inline-input:focus { - border-bottom: 0; - background: white; - box-shadow: 0px 1px 3px 1px rgba(30, 30, 30, 0.3); + border-bottom: 1px solid #424242; } .am-tax-inline-input:hover { - border-bottom: 0; - background: white; - box-shadow: 0px 1px 3px 1px rgba(30, 30, 30, 0.2); + border-bottom: 1px solid #9E9E9E; } .am-tax-adjust md-switch .md-bar { @@ -103,7 +96,7 @@ - +
@@ -116,18 +109,18 @@ Click to upload - or + or
Drop CSV File
- +
First row of the CSV file must be the header row, divided into fields like this;
name, mobile, registration, manufacturer, model.
- - + + lock_openSee Passcode @@ -139,19 +132,15 @@ - -
- Default Service Type -
- - {{state}} - + + Currency: +
- + Backup Your Data
@@ -160,33 +149,6 @@
- - - - {{vm.label_login}} as {{vm.user.username}} - - - -
- - person_pin - - - - - vpn_key - - - -
-
- - send - Login - -
-
-
@@ -204,60 +166,43 @@ -
- Service Tax -
- - Apply Service Tax - +
+ App Data Location
-
-
- Exclusive - - Inclusive -
-
-
- Service Tax (%): - -
+
+ {{vm.amAppPath}} +
+
+ + create_new_folder + Change and Move + + + Select Existing + folder_open +
- +
- VAT -
- - Apply VAT - -
-
-
- Exclusive - - Inclusive -
-
-
- VAT (%): - -
+ Default Service Type
+ + {{state}} +
- - +
- - Workshop Details + + Workshop Details
domain @@ -286,18 +231,18 @@
- - + + Display in Invoice
-
+
Social Links
- + Show Links
@@ -318,13 +263,33 @@
+ + + + Footer Logo + + + + + + + + + Display in Invoice + + + collections + Change + + +
- +
- Last Invoice Number: + Last Invoice Number:
@@ -334,7 +299,7 @@
- Last Estimate Number: + Last Estimate Number:
@@ -344,7 +309,7 @@
- Last Job Card Number: + Last Job Card Number:
@@ -355,17 +320,17 @@ - + Workshop Logo - + - + Display in Invoice @@ -388,24 +353,171 @@
Printing Margin (in cm)
- + Enable Margins
- + vertical_align_top - + vertical_align_bottom
+ + +
+ Print Settings + + Page Size:  + + {{page}} + +
+
+
+ + + + + +
+ add + Add New +
+ +
+
+ + Apply Tax + +
+
+ +
+ Tax: + + % +
+
+ Exclusive + + Inclusive +
+
+
+

Applicable On:

+ Treatments + Parts +
+ + delete + Delete Tax + +
+ +
+
+
+
+ + + + + +
+ Automint Cloud + + Enable Cloud Services +
+ +
+
+
+
\ No newline at end of file diff --git a/src/app/components/settings/tmpl/changepassword.controller.js b/src/app/components/settings/tmpl/changepassword.controller.js new file mode 100644 index 00000000..f6f655ad --- /dev/null +++ b/src/app/components/settings/tmpl/changepassword.controller.js @@ -0,0 +1,112 @@ +/** + * Controller for Change Password Dialog box + * @author ndkcha + * @since 0.7.0 + * @version 0.7.0 + */ + +/// + +(function() { + const ipcRenderer = require('electron').ipcRenderer; + + angular.module('automintApp').controller('amCtrlSeChPwd', ChangePasswordController); + + ChangePasswordController.$inject = ['$rootScope', '$amLicense', '$mdDialog', '$amRoot']; + + function ChangePasswordController($rootScope, $amLicense, $mdDialog, $amRoot) { + // initialize view model + var vm = this; + + // temporary assignments for the instance + // no such assignments for now + + // named assignments to view model + vm.oldPassword = ''; + vm.newPassword = ''; + + // function mappings to view model + vm.OnKeyDown = OnKeyDown; + vm.submit = submit; + vm.OnChangePasswords = OnChangePasswords; + + // default execution steps + setTimeout(focusCurrentPassword, 300); + + // function definitions + + function OnChangePasswords() { + vm.message = undefined; + } + + function OnKeyDown(event) { + if (event.keyCode == 13) + submit(); + } + + function focusCurrentPassword() { + $('#ami-cur-password').focus(); + } + + function focusNewPassword() { + $('#ami-new-password').focus(); + } + + function submit() { + if (vm.oldPassword == '') { + vm.message = 'Please enter current password'; + setTimeout(focusCurrentPassword, 300); + return; + } + if (vm.newPassword == '') { + vm.message = 'Please enter new password'; + setTimeout(focusNewPassword, 300); + return; + } + if (vm.oldPassword != $rootScope.amGlobals.credentials.password) { + vm.message = 'Incorrect current password'; + setTimeout(focusCurrentPassword, 300); + return; + } + $rootScope.busyApp.show = true; + $rootScope.busyApp.message = 'Changing Password. Please Wait..'; + if ($rootScope.amDbSync) + $rootScope.amDbSync.cancel(); + $amLicense.changePassword($rootScope.amGlobals.credentials.username, vm.newPassword).then(success).catch(failure); + + function success(res) { + $amRoot.syncDb(); + $rootScope.busyApp.show = false; + $mdDialog.hide(true); + } + + function failure(err) { + $rootScope.busyApp.show = false; + $amRoot.syncDb(); + if (err.error_code == 1) { + doLogin(err.error_message); + return; + } + vm.message = err.error_message; + } + + function doLogin(message) { + $mdDialog.show( + $mdDialog.alert() + .parent(document.body) + .clickOutsideToClose(false) + .title('License Error!') + .textContent(message) + .ariaLabel('License Error') + .ok('Got it!') + ).then(restartApp).catch(restartApp); + + function restartApp(res) { + $rootScope.busyApp.show = true; + $rootScope.busyApp.message = 'Restarting App due to License Error. Please Wait..'; + ipcRenderer.send('am-do-restart', true); + } + } + } + } +})(); \ No newline at end of file diff --git a/src/app/components/settings/tmpl/changepassword.html b/src/app/components/settings/tmpl/changepassword.html new file mode 100644 index 00000000..e0d70bbb --- /dev/null +++ b/src/app/components/settings/tmpl/changepassword.html @@ -0,0 +1,29 @@ + + + + +
+ + {{$root.amGlobals.credentials.username}} +
+
+ + +
+
+ + +
+
+ {{vm.message}} + + Submit + send + +
+
+
\ No newline at end of file diff --git a/src/app/components/treatments/memberships/memberships-add.controller.js b/src/app/components/treatments/memberships/memberships-add.controller.js index 6b0e4bcf..6522d91c 100644 --- a/src/app/components/treatments/memberships/memberships-add.controller.js +++ b/src/app/components/treatments/memberships/memberships-add.controller.js @@ -2,7 +2,7 @@ * Controller for Add Membership component * @author ndkcha * @since 0.5.0 - * @version 0.6.1 + * @version 0.7.0 */ /// @@ -10,9 +10,9 @@ (function() { angular.module('automintApp').controller('amCtrlMsCI', MembershipAddController); - MembershipAddController.$inject = ['$q', '$filter', '$state', 'utils', 'amTreatments']; + MembershipAddController.$inject = ['$rootScope', '$q', '$filter', '$state', 'utils', 'amTreatments']; - function MembershipAddController($q, $filter, $state, utils, amTreatments) { + function MembershipAddController($rootScope, $q, $filter, $state, utils, amTreatments) { // initialize view model var vm = this; diff --git a/src/app/components/treatments/memberships/memberships-edit.controller.js b/src/app/components/treatments/memberships/memberships-edit.controller.js index e6cff398..b34bf435 100644 --- a/src/app/components/treatments/memberships/memberships-edit.controller.js +++ b/src/app/components/treatments/memberships/memberships-edit.controller.js @@ -2,7 +2,7 @@ * Controller for Edit Membership component * @author ndkcha * @since 0.5.0 - * @version 0.6.1 + * @version 0.7.0 */ /// @@ -10,9 +10,9 @@ (function() { angular.module('automintApp').controller('amCtrlMsUI', MembershipEditController); - MembershipEditController.$inject = ['$q', '$filter', '$state', 'utils', 'amTreatments']; + MembershipEditController.$inject = ['$rootScope', '$q', '$filter', '$state', 'utils', 'amTreatments']; - function MembershipEditController($q, $filter, $state, utils, amTreatments) { + function MembershipEditController($rootScope, $q, $filter, $state, utils, amTreatments) { // initialize view model var vm = this, oMembershipName; @@ -176,7 +176,6 @@ } } function failure(err) { - console.info(err); errorAndExit(); } } diff --git a/src/app/components/treatments/memberships/memberships-viewall.controller.js b/src/app/components/treatments/memberships/memberships-viewall.controller.js index 371eff8c..518ad2d9 100644 --- a/src/app/components/treatments/memberships/memberships-viewall.controller.js +++ b/src/app/components/treatments/memberships/memberships-viewall.controller.js @@ -2,7 +2,7 @@ * Conroller for View All Memberships component * @author ndkcha * @since 0.5.0 - * @version 0.6.0 + * @version 0.7.0 */ /// @@ -10,9 +10,9 @@ (function() { angular.module('automintApp').controller('amCtrlMsRA', MembershipsViewAll); - MembershipsViewAll.$inject = ['$state', '$filter', 'utils', 'amTreatments']; + MembershipsViewAll.$inject = ['$rootScope', '$state', '$filter', 'utils', 'amTreatments']; - function MembershipsViewAll($state, $filter, utils, amTreatments) { + function MembershipsViewAll($rootScope, $state, $filter, utils, amTreatments) { // initialize view model var vm = this; @@ -24,6 +24,7 @@ }; vm.selectedMembership = undefined; vm.isExpandAll = false; + vm.currencySymbol = "Rs."; // function maps vm.changeExpandValues = changeExpandValues; @@ -34,9 +35,22 @@ vm.IsMembershipVisible = IsMembershipVisible; // default execution steps + getCurrencySymbol(); getMemberships(changeExpandValues); // function definitions + + function getCurrencySymbol() { + amTreatments.getCurrencySymbol().then(success).catch(failure); + + function success(res) { + vm.currencySymbol = res; + } + + function failure(err) { + vm.currencySymbol = "Rs."; + } + } function changeExpandValues() { vm.isExpandAll = !vm.isExpandAll; diff --git a/src/app/components/treatments/memberships/memberships_add.html b/src/app/components/treatments/memberships/memberships_add.html index 9a2a6097..f241adfc 100644 --- a/src/app/components/treatments/memberships/memberships_add.html +++ b/src/app/components/treatments/memberships/memberships_add.html @@ -1,6 +1,5 @@ arrow_back - Back
diff --git a/src/app/components/treatments/packages/packages-add.controller.js b/src/app/components/treatments/packages/packages-add.controller.js index 0f352ed6..744aa9e3 100644 --- a/src/app/components/treatments/packages/packages-add.controller.js +++ b/src/app/components/treatments/packages/packages-add.controller.js @@ -2,7 +2,7 @@ * Controller for Add Package component * @author ndkcha * @since 0.5.0 - * @version 0.6.1 + * @version 0.7.0 */ /// @@ -10,9 +10,9 @@ (function() { angular.module('automintApp').controller('amCtrlPkCI', PackageAddController); - PackageAddController.$inject = ['$q', '$filter', '$state', 'utils', 'amTreatments']; + PackageAddController.$inject = ['$rootScope', '$q', '$filter', '$state', 'utils', 'amTreatments']; - function PackageAddController($q, $filter, $state, utils, amTreatments) { + function PackageAddController($rootScope, $q, $filter, $state, utils, amTreatments) { // initialize view model var vm = this; diff --git a/src/app/components/treatments/packages/packages-edit.controller.js b/src/app/components/treatments/packages/packages-edit.controller.js index 1950a6fb..65b07dd9 100644 --- a/src/app/components/treatments/packages/packages-edit.controller.js +++ b/src/app/components/treatments/packages/packages-edit.controller.js @@ -2,7 +2,7 @@ * Controller for Edit Package component * @author ndkcha * @since 0.5.0 - * @version 0.6.1 + * @version 0.7.0 */ /// @@ -10,9 +10,9 @@ (function() { angular.module('automintApp').controller('amCtrlPkUI', PackageAddController); - PackageAddController.$inject = ['$q', '$filter', '$state', 'utils', 'amTreatments']; + PackageAddController.$inject = ['$rootScope', '$q', '$filter', '$state', 'utils', 'amTreatments']; - function PackageAddController($q, $filter, $state, utils, amTreatments) { + function PackageAddController($rootScope, $q, $filter, $state, utils, amTreatments) { // initialize view model var vm = this, oPackageName; @@ -35,7 +35,7 @@ return; } getVehicleTypes(getTreatments, getPackageInfo); - + // function maps vm.goBack = goBack; vm.changeNameLabel = changeNameLabel; diff --git a/src/app/components/treatments/packages/packages-viewall.controller.js b/src/app/components/treatments/packages/packages-viewall.controller.js index 3c3223ea..c6b24a16 100644 --- a/src/app/components/treatments/packages/packages-viewall.controller.js +++ b/src/app/components/treatments/packages/packages-viewall.controller.js @@ -2,7 +2,7 @@ * Controller for View All Packages compoenent * @author ndkcha * @since 0.5.0 - * @version 0.6.0 + * @version 0.7.0 */ /// @@ -10,9 +10,9 @@ (function() { angular.module('automintApp').controller('amCtrlPkRA', PackagesViewAllController); - PackagesViewAllController.$inject = ['$state', '$filter', 'utils', 'amTreatments']; + PackagesViewAllController.$inject = ['$rootScope', '$state', '$filter', 'utils', 'amTreatments']; - function PackagesViewAllController($state, $filter, utils, amTreatments) { + function PackagesViewAllController($rootScope, $state, $filter, utils, amTreatments) { // initialize view model var vm = this; diff --git a/src/app/components/treatments/packages/packages_add.html b/src/app/components/treatments/packages/packages_add.html index daec1b9e..6a249173 100644 --- a/src/app/components/treatments/packages/packages_add.html +++ b/src/app/components/treatments/packages/packages_add.html @@ -1,6 +1,5 @@ arrow_back - Back
diff --git a/src/app/components/treatments/regular/treatments-add.controller.js b/src/app/components/treatments/regular/treatments-add.controller.js index f45e4ee6..1d129c28 100644 --- a/src/app/components/treatments/regular/treatments-add.controller.js +++ b/src/app/components/treatments/regular/treatments-add.controller.js @@ -2,7 +2,7 @@ * Controller for Add Treatments component * @author ndkcha * @since 0.4.1 - * @version 0.6.1 + * @version 0.7.0 */ /// @@ -11,9 +11,9 @@ angular.module('automintApp') .controller('amCtrlTrCI', TreatmentAddController); - TreatmentAddController.$inject = ['$state', 'utils', 'amTreatments']; + TreatmentAddController.$inject = ['$rootScope', '$state', 'utils', 'amTreatments']; - function TreatmentAddController($state, utils, amTreatments) { + function TreatmentAddController($rootScope, $state, utils, amTreatments) { // initialize view model object var vm = this; @@ -63,6 +63,7 @@ vm.rates.push({ type: utils.convertToTitleCase(type.replace(/-/g, ' ')), value: '', + orgcost: '', fromDb: true, focusIndex: vm.rates.length }); @@ -80,6 +81,7 @@ vm.rates.push({ type: '', value: '', + orgcost: '', fromDb: false, focusIndex: fIndex }); @@ -113,9 +115,23 @@ } return result; } + + function generateOrgCost() { + var result = {}; + vm.rates.forEach(iterateRate); + + function iterateRate(rate) { + rate.type = rate.type.trim(); + if (rate.type && rate.orgcost != '') + result[angular.lowercase(rate.type.replace(/\s/g, '-'))] = rate.orgcost; + } + return result; + } function save() { vm.treatment.rate = generateRate(); + if (vm.isOrgCostEnabled) + vm.treatment.orgcost = generateOrgCost(); amTreatments.saveVehicleTypes(Object.keys(vm.treatment.rate)); amTreatments.saveTreatment(vm.treatment, vm.operationMode).then(success).catch(failure); diff --git a/src/app/components/treatments/regular/treatments-edit.controller.js b/src/app/components/treatments/regular/treatments-edit.controller.js index 6eca8376..f750c7d9 100644 --- a/src/app/components/treatments/regular/treatments-edit.controller.js +++ b/src/app/components/treatments/regular/treatments-edit.controller.js @@ -2,7 +2,7 @@ * Controller for Edit Treatments component * @author ndkcha * @since 0.4.1 - * @version 0.6.1 + * @version 0.7.0 */ /// @@ -11,9 +11,9 @@ angular.module('automintApp') .controller('amCtrlTrUI', TreatmentsEditController); - TreatmentsEditController.$inject = ['$state', '$filter', 'utils', 'amTreatments']; + TreatmentsEditController.$inject = ['$rootScope', '$state', '$filter', 'utils', 'amTreatments']; - function TreatmentsEditController($state, $filter, utils, amTreatments) { + function TreatmentsEditController($rootScope, $state, $filter, utils, amTreatments) { // initialize view model object var vm = this; @@ -71,6 +71,18 @@ vm.treatment.name = res.name; changeNameLabel(); Object.keys(res.rate).forEach(iterateRate); + if (res.orgcost) { + vm.isOrgCostEnabled = true; + Object.keys(res.orgcost).forEach(iterateOrgCost); + } + + function iterateOrgCost(rk) { + var found = $filter('filter')(vm.rates, { + type: utils.convertToTitleCase(rk.replace(/-/g, ' ')) + }, true); + if (found.length == 1) + found[0].orgcost = res.orgcost[rk]; + } function iterateRate(rk) { var found = $filter('filter')(vm.rates, { @@ -97,6 +109,7 @@ vm.rates.push({ type: utils.convertToTitleCase(type.replace(/-/g, ' ')), value: '', + orgcost: '', fromDb: true, focusIndex: vm.rates.length }); @@ -116,6 +129,7 @@ type: '', value: '', fromDb: false, + orgcost: '', focusIndex: fIndex }); if (focus) { @@ -144,9 +158,23 @@ } return result; } + + function generateOrgCost() { + var result = {}; + vm.rates.forEach(iterateRate); + + function iterateRate(rate) { + rate.type = rate.type.trim(); + if (rate.type && rate.orgcost != '') + result[angular.lowercase(rate.type.replace(/\s/g, '-'))] = rate.orgcost; + } + return result; + } function save() { vm.treatment.rate = generateRate(); + if (vm.isOrgCostEnabled) + vm.treatment.orgcost = generateOrgCost(); amTreatments.saveVehicleTypes(Object.keys(vm.treatment.rate)); amTreatments.saveTreatment(vm.treatment, vm.operationMode).then(success).catch(failure); diff --git a/src/app/components/treatments/regular/treatments-viewall.controller.js b/src/app/components/treatments/regular/treatments-viewall.controller.js index 68bbe759..5013c2cc 100644 --- a/src/app/components/treatments/regular/treatments-viewall.controller.js +++ b/src/app/components/treatments/regular/treatments-viewall.controller.js @@ -2,7 +2,7 @@ * Controller for View All Treatments component * @author ndkcha * @since 0.4.1 - * @version 0.5.0 + * @version 0.7.0 */ /// @@ -11,9 +11,9 @@ angular.module('automintApp') .controller('amCtrlTrRA', TreatmentsViewAll); - TreatmentsViewAll.$inject = ['$scope', '$state', 'utils', 'amTreatments']; + TreatmentsViewAll.$inject = ['$rootScope', '$scope', '$state', 'utils', 'amTreatments']; - function TreatmentsViewAll($scope, $state, utils, amTreatments) { + function TreatmentsViewAll($rootScope, $scope, $state, utils, amTreatments) { // initialize view model var vm = this; diff --git a/src/app/components/treatments/regular/treatments_add.html b/src/app/components/treatments/regular/treatments_add.html index f9f5dbc1..5f6e4896 100644 --- a/src/app/components/treatments/regular/treatments_add.html +++ b/src/app/components/treatments/regular/treatments_add.html @@ -1,23 +1,28 @@ arrow_back - Back
- + spa
+
+ + Original Cost to Center + +
+ @@ -28,6 +33,9 @@ +
Vehicle Type RateOriginal Cost to Center
+ +
diff --git a/src/app/components/treatments/treatments.factory.js b/src/app/components/treatments/treatments.factory.js index b7b0eeeb..dfeca7e5 100644 --- a/src/app/components/treatments/treatments.factory.js +++ b/src/app/components/treatments/treatments.factory.js @@ -2,7 +2,7 @@ * Factory that handles database interactions between treatments database and controller * @author ndkcha * @since 0.4.1 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -11,9 +11,9 @@ angular.module('automintApp') .factory('amTreatments', TreatmentsFactory); - TreatmentsFactory.$inject = ['$q', '$filter', '$amRoot', 'utils', 'pdbConfig']; + TreatmentsFactory.$inject = ['$q', '$filter', '$rootScope', 'pdbMain']; - function TreatmentsFactory($q, $filter, $amRoot, utils, pdbConfig) { + function TreatmentsFactory($q, $filter, $rootScope, pdbMain) { // initialized factory and function maps var factory = { saveTreatment: saveTreatment, @@ -31,21 +31,35 @@ getMemberships: getMemberships, getMembershipInfo: getMembershipInfo, deleteMembership: deleteMembership, - saveMembership: saveMembership + saveMembership: saveMembership, + getCurrencySymbol: getCurrencySymbol } return factory; + + function getCurrencySymbol() { + var tracker = $q.defer(); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(getSettingsObject).catch(failure); + return tracker.promise; + + function getSettingsObject(res) { + if (res.currency) + tracker.resolve(res.currency); + else + failure('No Currency Symbol Found!'); + } + + function failure(err) { + tracker.reject(err); + } + } // retrieve vehicle types from config database function getVehicleTypes() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(configFound).catch(noConfigFound); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(settingsDocFound).catch(noConfigFound); return tracker.promise; - function configFound(res) { - pdbConfig.get($amRoot.docIds.settings).then(settingsDocFound).catch(noConfigFound); - } - function settingsDocFound(res) { if (res.vehicletypes) tracker.resolve(res.vehicletypes); @@ -61,13 +75,9 @@ // store vehicle types to config database function saveVehicleTypes(vehicleTypes) { var tracker = $q.defer(); - $amRoot.isSettingsId().then(configFound).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(settingsDocFound).catch(writeNewConfig); return tracker.promise; - function configFound(res) { - pdbConfig.get($amRoot.docIds.settings).then(settingsDocFound).catch(writeNewConfig); - } - function settingsDocFound(res) { var totalMatch = 0; if (!res.vehicletypes) @@ -84,15 +94,17 @@ if (totalMatch == vehicleTypes.length) tracker.resolve('Duplicate Entries'); else - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } function writeNewConfig(err) { - var doc = {}; - doc['_id'] = utils.generateUUID('sttngs'); - doc['creator'] = $amRoot.username; + var doc = { + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel + }; doc.vehicletypes = vehicleTypes; - pdbConfig.save(doc).then(success).catch(failure); + pdbMain.save(doc).then(success).catch(failure); } function success(res) { @@ -107,19 +119,19 @@ // return particular treatment function treatmentDetails(treatmentName) { var tracker = $q.defer(); - $amRoot.isTreatmentId().then(treatmentConfigFound).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(treatmentDocFound).catch(failure); return tracker.promise; - - function treatmentConfigFound(response) { - pdbConfig.get($amRoot.docIds.treatment).then(treatmentDocFound).catch(failure); - } + function treatmentDocFound(res) { var treatment = { name: treatmentName, rate: res.regular[treatmentName].rate } + if (res.regular[treatmentName].orgcost) + treatment.orgcost = res.regular[treatmentName].orgcost; tracker.resolve(treatment); } + function failure(error) { tracker.reject(error); } @@ -132,13 +144,9 @@ treatments: [], total: 0 }; - $amRoot.isTreatmentId().then(treatmentConfigFound).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(treatmentDocFound).catch(failure); return tracker.promise; - function treatmentConfigFound(res) { - pdbConfig.get($amRoot.docIds.treatment).then(treatmentDocFound).catch(failure); - } - function treatmentDocFound(res) { if (res.regular) Object.keys(res.regular).forEach(iterateRegularTreatments); @@ -162,16 +170,12 @@ // delete treatment from database function deleteTreatment(name) { var tracker = $q.defer(); - $amRoot.isTreatmentId().then(treatmentConfigFound).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(treatmentDocFound).catch(failure); return tracker.promise; - function treatmentConfigFound(res) { - pdbConfig.get($amRoot.docIds.treatment).then(treatmentDocFound).catch(failure); - } - function treatmentDocFound(res) { res.regular[name]._deleted = true; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } function success(res) { @@ -189,29 +193,29 @@ var i = { rate: treatment.rate }; - $amRoot.isTreatmentId().then(treatmentConfigFound).catch(failure); + if (treatment.orgcost) + i.orgcost = treatment.orgcost; + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(treatmentDocFound).catch(noTreatmentDoc); return tracker.promise; - function treatmentConfigFound(response) { - pdbConfig.get($amRoot.docIds.treatment).then(treatmentDocFound).catch(noTreatmentDoc); - } - function treatmentDocFound(res) { if (!res.regular) res.regular = {}; if (res.regular[treatment.name]) delete res.regular[treatment.name]['._deleted']; res.regular[treatment.name] = i; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } function noTreatmentDoc(err) { - var doc = {}; - doc['_id'] = utils.generateUUID('trtmnt'); - doc['creator'] = $amRoot.username; + var doc = { + _id: $rootScope.amGlobals.configDocIds.treatment, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel + }; doc.regular = {}; doc.regular[treatment.name] = i; - pdbConfig.save(doc).then(success).catch(failure); + pdbMain.save(doc).then(success).catch(failure); } function success(res) { @@ -226,12 +230,9 @@ // current treatment settings function getTreatmentSettings() { var tracker = $q.defer(); - $amRoot.isSettingsId().then(treatmentConfigFound).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(treatmentDocFound).catch(failure); return tracker.promise; - function treatmentConfigFound(response) { - pdbConfig.get($amRoot.docIds.settings).then(treatmentDocFound).catch(failure); - } function treatmentDocFound(res) { if (res.settings.treatments) tracker.resolve(res.settings.treatments); @@ -241,6 +242,7 @@ }); } } + function failure(error) { tracker.reject(error); } @@ -249,33 +251,34 @@ // change display format setting of treatments function changeDisplayAsList(displayAsList) { var tracker = $q.defer(); - $amRoot.isSettingsId().then(configFound).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.settings).then(configDocFound).catch(writeNewConfig); return tracker.promise; - function configFound(response) { - pdbConfig.get($amRoot.docIds.settings).then(configDocFound).catch(writeNewConfig); - } function configDocFound(res) { - if (!res.settings) res.settings = {}; if (!res.settings.treatments) res.settings.treatments = {}; res.settings.treatments['displayAsList'] = displayAsList; - pdbConfig.save(res).then(saveSuccess).catch(failure); + pdbMain.save(res).then(saveSuccess).catch(failure); } + function writeNewConfig(err) { - var doc = {}; - doc['_id'] = utils.generateUUID('sttngs'); - doc['creator'] = $amRoot.username; + var doc = { + _id: $rootScope.amGlobals.configDocIds.settings, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel + }; doc.settings = {}; doc.settings['treatments'] = {} doc.settings.treatments['displayAsList'] = displayAsList; - pdbConfig.save(doc).then(saveSuccess).catch(failure); + pdbMain.save(doc).then(saveSuccess).catch(failure); } + function saveSuccess(response) { tracker.resolve(response); } + function failure(error) { tracker.reject(error); } @@ -283,13 +286,9 @@ function getPackageInfo(name) { var tracker = $q.defer(); - $amRoot.isTreatmentId().then(getTreatmentsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(getTreatmentObject).catch(failure); return tracker.promise; - function getTreatmentsDoc(res) { - pdbConfig.get($amRoot.docIds.treatment).then(getTreatmentObject).catch(failure); - } - function getTreatmentObject(res) { if (res.packages && res.packages[name]) { tracker.resolve({ @@ -317,13 +316,9 @@ packages: [], total: 0 } - $amRoot.isTreatmentId().then(getTreatmentsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(getTreatmentObject).catch(failure); return tracker.promise; - function getTreatmentsDoc(res) { - pdbConfig.get($amRoot.docIds.treatment).then(getTreatmentObject).catch(failure); - } - function getTreatmentObject(res) { if (res.packages) Object.keys(res.packages).forEach(iteratePackages); @@ -347,17 +342,13 @@ function deletePackage(name) { var tracker = $q.defer(); - $amRoot.isTreatmentId().then(getTreatmentsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(getTreatmentObject).catch(failure); return tracker.promise; - function getTreatmentsDoc(res) { - pdbConfig.get($amRoot.docIds.treatment).then(getTreatmentObject).catch(failure); - } - function getTreatmentObject(res) { if (res.packages && res.packages[name]) { res.packages[name]._deleted = true; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } else failure(); } @@ -378,13 +369,9 @@ function savePackage(package, oldName) { var tracker = $q.defer(); - $amRoot.isTreatmentId().then(getTreatmentsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(getTreatmentObject).catch(writeTreatmentDoc); return tracker.promise; - function getTreatmentsDoc(res) { - pdbConfig.get($amRoot.docIds.treatment).then(getTreatmentObject).catch(writeTreatmentDoc); - } - function getTreatmentObject(res) { if (!res.packages) res.packages = {}; @@ -392,18 +379,19 @@ delete res.packages[oldName]; res.packages[package.name] = package; delete res.packages[package.name].name; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } function writeTreatmentDoc(err) { var doc = { - _id: utils.generateUUID('trtmnt'), - creator: $amRoot.username + _id: $rootScope.amGlobals.configDocIds.treatment, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel } doc.packages = {}; doc.packages[package.name] = package; delete doc.packages[package.name].name; - pdbConfig.save(doc).then(success).catch(failure); + pdbMain.save(doc).then(success).catch(failure); } function success(res) { @@ -417,13 +405,9 @@ function getMembershipInfo(name) { var tracker = $q.defer(); - $amRoot.isTreatmentId().then(getTreatmentsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(getTreatmentObject).catch(failure); return tracker.promise; - function getTreatmentsDoc(res) { - pdbConfig.get($amRoot.docIds.treatment).then(getTreatmentObject).catch(failure); - } - function getTreatmentObject(res) { if (res.memberships && res.memberships[name]) { var m = $.extend({}, res.memberships[name]); @@ -461,13 +445,9 @@ memberships: [], total: 0 } - $amRoot.isTreatmentId().then(getTreatmentsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(getTreatmentObject).catch(failure); return tracker.promise; - function getTreatmentsDoc(res) { - pdbConfig.get($amRoot.docIds.treatment).then(getTreatmentObject).catch(failure); - } - function getTreatmentObject(res) { if (res.memberships) Object.keys(res.memberships).forEach(iterateMemberships); @@ -497,17 +477,13 @@ function deleteMembership(name) { var tracker = $q.defer(); - $amRoot.isTreatmentId().then(getTreatmentsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(getTreatmentObject).catch(failure); return tracker.promise; - function getTreatmentsDoc(res) { - pdbConfig.get($amRoot.docIds.treatment).then(getTreatmentObject).catch(failure); - } - function getTreatmentObject(res) { if (res.memberships && res.memberships[name]) { res.memberships[name]._deleted = true; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } else failure(); } @@ -529,13 +505,9 @@ function saveMembership(membership, oldName) { var tracker = $q.defer(); - $amRoot.isTreatmentId().then(getTreatmentsDoc).catch(failure); + pdbMain.get($rootScope.amGlobals.configDocIds.treatment).then(getTreatmentObject).catch(writeTreatmentDoc); return tracker.promise; - function getTreatmentsDoc(res) { - pdbConfig.get($amRoot.docIds.treatment).then(getTreatmentObject).catch(writeTreatmentDoc); - } - function getTreatmentObject(res) { if (!res.memberships) res.memberships = {}; @@ -543,18 +515,19 @@ delete res.memberships[oldName]; res.memberships[membership.name] = membership; delete res.memberships[membership.name].name; - pdbConfig.save(res).then(success).catch(failure); + pdbMain.save(res).then(success).catch(failure); } function writeTreatmentDoc(err) { var doc = { - _id: utils.generateUUID('trtmnt'), - creator: $amRoot.username + _id: $rootScope.amGlobals.configDocIds.treatment, + creator: $rootScope.amGlobals.creator, + channel: $rootScope.amGlobals.channel } doc.memberships = {}; doc.memberships[membership.name] = membership; delete doc.memberships[membership.name].name; - pdbConfig.save(doc).then(success).catch(failure); + pdbMain.save(doc).then(success).catch(failure); } function success(res) { diff --git a/src/app/components/treatments/treatments_master.html b/src/app/components/treatments/treatments_master.html index 6474167c..6aabf4fe 100644 --- a/src/app/components/treatments/treatments_master.html +++ b/src/app/components/treatments/treatments_master.html @@ -53,7 +53,7 @@ - + @@ -147,7 +147,7 @@
{{membership.name}} -
Rs. {{membership.amount}}
+
{{msVm.currencySymbol}} {{membership.amount}}
diff --git a/src/app/lock/lockscreen.controller.js b/src/app/lock/lockscreen.controller.js new file mode 100644 index 00000000..79a637b0 --- /dev/null +++ b/src/app/lock/lockscreen.controller.js @@ -0,0 +1,57 @@ +/** + * Controller for lockscreen + * @author ndkcha + * @since 0.7.0 + * @version 0.7.0 + */ + +/// + +(function() { + angular.module('automintApp').controller('amCtrlLock', LockscreenController); + + LockscreenController.$inject = ['$rootScope', '$state', '$window', 'amAppbar', 'utils']; + + function LockscreenController($rootScope, $state, $window, amAppbar, utils) { + // initialize view model and temporary assignments + var vm = this, passcode, skip = true; + var pageTitle = $rootScope.page_title; + $rootScope.page_title = "Automint"; + + // named assignments and function mappings to view model + vm.isMessage = false; + vm.unlock = unlock; + vm.addService = addService; + vm.changePasscode = changePasscode; + + // default execution steps + amAppbar.getPasscode().then(gps).catch(unlock); + + // function definitions + + function changePasscode() { + vm.isMessage = false; + } + + function addService() { + $rootScope.isAutomintLocked = false; + $state.go('restricted.services.add', { + fromState: 'locked' + }); + } + + function gps(res) { + passcode = res.code; + } + + function unlock() { + $rootScope.page_title = pageTitle; + if (vm.passcode != passcode) { + vm.message = "Wrong Passcode!!!"; + vm.isMessage = true; + return; + } + $rootScope.isAutomintLocked = false; + } + } +})(); \ No newline at end of file diff --git a/src/app/lock/lockscreen.html b/src/app/lock/lockscreen.html new file mode 100644 index 00000000..e12bad9b --- /dev/null +++ b/src/app/lock/lockscreen.html @@ -0,0 +1,67 @@ + +
+ + Add a Service + add + + Add a Service +
+ + + +
+ + +
+
+ + Unlock + lock_open + +
+
+ {{lockVm.message}} +
+
+
\ No newline at end of file diff --git a/src/app/login/login.controller.js b/src/app/login/login.controller.js new file mode 100644 index 00000000..8c78f815 --- /dev/null +++ b/src/app/login/login.controller.js @@ -0,0 +1,126 @@ +/** + * Controller for Login Compoenent + * @author ndkcha + * @since 0.7.0 + * @version 0.7.0 + */ + +/// + +(function() { + var base64url = require('base64url'); + + angular.module('automintApp').controller('amLoginCtrl', LoginController); + + LoginController.$inject = ['$rootScope', '$amRoot', '$location', '$amLicense', 'amLogin']; + + function LoginController($rootScope, $amRoot, $location, $amLicense, amLogin) { + // initialize view model + var vm = this; + + // temporary named assignments + var channel = undefined, license = undefined, cloud = undefined, isLoggedIn = false; + + // named assignments for view model + vm.isLogingIn = false; + vm.username = ''; + vm.password = ''; + vm.code = ''; + vm.message = undefined; + + // named assignments for other scopes + $rootScope.hidePreloader = true; + + // function mappings + vm.changeCode = changeCode; + vm.changeUserDetails = changeUserDetails; + vm.submit = submit; + vm.OnKeyDown = OnKeyDown; + vm.convertToCodeToUppercase = convertToCodeToUppercase; + + // default execution steps + setTimeout(focusUsername, 300); + + // function definitions + + function convertToCodeToUppercase() { + vm.code = vm.code.toUpperCase(); + changeCode(); + } + + function focusUsername() { + $('#ami-username').focus(); + } + + function focusPassword() { + $('#ami-password').focus(); + } + + function focusCode() { + $('#ami-code').focus(); + } + + function changeCode() { + vm.password = ''; + vm.message = undefined; + } + + function changeUserDetails() { + vm.code = ''; + vm.message = undefined; + } + + function OnKeyDown(event) { + if (event.keyCode == 13) + submit(); + } + + function submit() { + vm.message = undefined; + if ((vm.username == '') && (vm.password == '') && (vm.code == '')) { + vm.message = 'Please Enter Username and Password, or Code!'; + setTimeout(focusUsername, 300); + return; + } + if (((vm.username != '') && (vm.password == '')) && (vm.code == '')) { + vm.message = 'Please Enter Password!'; + setTimeout(focusPassword, 300); + return; + } + if (((vm.password != '') && (vm.username == '')) && (vm.code == '')) { + vm.message = 'Please Enter Username!'; + setTimeout(focusUsername, 300); + return; + } + vm.isLogingIn = true; + if ((vm.username != undefined) && (vm.username != '') && (vm.password != undefined) && (vm.password != '')) { + $amLicense.loadCredentials(vm.username, vm.password); + $amLicense.login(false).then(success).catch(failure); + } else if ((vm.code != undefined) && (vm.code != '')) + $amLicense.login(true, vm.code).then(success).catch(failure); + + function success(res) { + if (res.isLoggedIn) { + if (res.isSyncableDb) { + $rootScope.isOnChangeMainDbBlocked = true; + $amRoot.syncDb(); + vm.message = "Preparing Automint"; + $amRoot.dbAfterLogin(true); + } else { + vm.message = "Preparing Dashboard.."; + $amRoot.dbAfterLogin(false); + } + } else { + failure({ + message: 'Your license has expired!' + }); + } + } + + function failure(err) { + vm.isLogingIn = false; + vm.message = err.message; + } + } + } +})(); \ No newline at end of file diff --git a/src/app/login/login.factory.js b/src/app/login/login.factory.js new file mode 100644 index 00000000..f61e53d3 --- /dev/null +++ b/src/app/login/login.factory.js @@ -0,0 +1,363 @@ +/** + * Factories for Login Mechanism + * @author ndkcha + * @since 0.7.0 + * @version 0.7.0 + */ + +/// + +(function() { + angular.module('automintApp').factory('amLogin', LoginFactory).factory('amLoginBase64', LoginBase64Factory); + + LoginBase64Factory.$inject = []; + LoginFactory.$inject = ['$rootScope', '$http', '$q', 'amLoginBase64', 'amFactory', 'constants', 'pdbLocal', 'pdbMain']; + + /* + === NOTE === + Do not include $amRoot as dependency as this module is used in it. + */ + + function LoginFactory($rootScope, $http, $q, amLoginBase64, amFactory, constants, pdbLocal, pdbMain) { + // initialize factory and functino mappings + var factory = { + saveLicense: saveLicense, + changeExistingDocs: changeExistingDocs, + saveActivationDetails: saveActivationDetails, + setLoginState: setLoginState, + savePassword: savePassword, + cloudForceEnabled: cloudForceEnabled + } + + return factory; + + // function definitions + + function cloudForceEnabled(force) { + var tracker = $q.defer(); + pdbLocal.get(constants.pdb_local_docs.login).then(getLoginDoc).catch(failure); + return tracker.promise; + + function getLoginDoc(res) { + res.isCloudForceEnabled = force; + pdbLocal.save(res).then(success).catch(failure); + } + + function success(res) { + tracker.resolve(res); + } + + function failure(err) { + tracker.reject(err); + } + } + + function savePassword(password) { + var tracker = $q.defer(); + pdbLocal.get(constants.pdb_local_docs.login).then(getLoginDoc).catch(failure); + return tracker.promise; + + function getLoginDoc(res) { + res.password = password; + pdbLocal.save(res).then(success).catch(failure); + } + + function success(res) { + tracker.resolve(res); + } + + function failure(err) { + tracker.reject(err); + } + } + + function saveActivationDetails(code, startdate, enddate) { + var tracker = $q.defer(); + pdbLocal.get(constants.pdb_local_docs.login).then(getLoginDoc).catch(writeLoginDoc); + return tracker.promise; + + function getLoginDoc(res) { + res.activation = { + code: code, + startdate: startdate, + enddate: enddate + } + pdbLocal.save(res).then(success).catch(failure); + } + + function writeLoginDoc(err) { + var doc = { + _id: constants.pdb_local_docs.login, + activation: { + code: code, + startdate: startdate, + enddate: enddate + } + } + pdbLocal.save(doc).then(success).catch(failure); + } + + function success(res) { + tracker.resolve(res); + } + + function failure(err) { + tracker.reject(err); + } + } + + function setLoginState(isLoggedIn) { + var tracker = $q.defer(); + pdbLocal.get(constants.pdb_local_docs.login).then(getLoginDoc).catch(writeLoginDoc); + return tracker.promise; + + function getLoginDoc(res) { + res.isLoggedIn = isLoggedIn; + pdbLocal.save(res).then(success).catch(failure); + } + + function writeLoginDoc(err) { + var doc = { + _id: constants.pdb_local_docs.login, + isLoggedIn: isLoggedIn + } + pdbLocal.save(doc).then(success).catch(failure); + } + + function success(res) { + tracker.resolve(res); + } + + function failure(err) { + tracker.reject(err); + } + } + + function saveLicense(username, password, channel, license, cloud) { + var tracker = $q.defer(); + if ($rootScope.amGlobals == undefined) + $rootScope.amGlobals = {}; + $rootScope.amGlobals.creator = username; + $rootScope.amGlobals.channel = channel; + if ($rootScope.amGlobals.validity == undefined) + $rootScope.amGlobals.validity = {}; + $rootScope.amGlobals.validity.license = license; + $rootScope.amGlobals.validity.cloud = cloud; + pdbLocal.get(constants.pdb_local_docs.login).then(getLoginDoc).catch(writeLoginDoc); + return tracker.promise; + + function getLoginDoc(res) { + res.username = username; + res.password = password; + res.channel = channel; + res.license = license; + res.cloud = cloud; + pdbLocal.save(res).then(success).catch(failure); + } + + function writeLoginDoc(err) { + var doc = { + _id: constants.pdb_local_docs.login, + username : username, + password: password, + channel: channel, + license: license, + cloud: cloud + } + pdbLocal.save(doc).then(success).catch(failure); + } + + function success(res) { + tracker.resolve(res); + } + + function failure(err) { + tracker.reject(err); + } + } + + function changeExistingDocs() { + var tracker = $q.defer(); + if (!$rootScope.amGlobals || ($rootScope.amGlobals && !$rootScope.amGlobals.creator) || ($rootScope.amGlobals && !$rootScope.amGlobals.channel)) + return 404; + pdbMain.getAll().then(getAllDocs).catch(failure); + return tracker.promise; + + function getAllDocs(res) { + var docsToSave = []; + res.rows.forEach(iterateRows); + pdbMain.saveAll(docsToSave).then(success).catch(failure); + + function iterateRows(row) { + switch (row.id) { + case 'settings': + convertSettingsDoc(row); + break; + case 'treatments': + convertTreatmentDoc(row); + break; + case 'workshop': + convertWorkshopDoc(row); + break; + case 'inventory': + convertInventoryDoc(row); + break; + default: + convertUserDoc(row); + break; + } + + function convertUserDoc(row) { + row.doc.channel = $rootScope.amGlobals.channel; + row.doc.creator = $rootScope.amGlobals.creator; + docsToSave.push(row.doc); + } + + function convertSettingsDoc(row) { + var sdoc = $.extend({}, row.doc); + row.doc._deleted = true; + delete sdoc._rev + sdoc._id = $rootScope.amGlobals.configDocIds.settings; + sdoc.creator = $rootScope.amGlobals.creator; + sdoc.channel = $rootScope.amGlobals.channel; + docsToSave.push(row.doc); + docsToSave.push(sdoc); + } + + function convertTreatmentDoc(row) { + var tdoc = $.extend({}, row.doc); + row.doc._deleted = true; + delete tdoc._rev; + tdoc._id = $rootScope.amGlobals.configDocIds.treatment; + tdoc.creator = $rootScope.amGlobals.creator; + tdoc.channel = $rootScope.amGlobals.channel; + docsToSave.push(row.doc); + docsToSave.push(tdoc); + } + + function convertWorkshopDoc(row) { + var wdoc = $.extend({}, row.doc); + row.doc._deleted = true; + delete wdoc._rev; + wdoc._id = $rootScope.amGlobals.configDocIds.workshop; + wdoc.creator = $rootScope.amGlobals.creator; + wdoc.channel = $rootScope.amGlobals.channel; + docsToSave.push(row.doc); + docsToSave.push(wdoc); + } + + function convertInventoryDoc(row) { + var idoc = $.extend({}, row.doc); + row.doc._deleted = true; + delete idoc._rev; + idoc._id = $rootScope.amGlobals.configDocIds.inventory; + idoc.creator = $rootScope.amGlobals.creator; + idoc.channel = $rootScope.amGlobals.channel; + docsToSave.push(row.doc); + docsToSave.push(idoc); + } + } + } + + function success(res) { + tracker.resolve(res); + } + + function failure(err) { + console.error(err); + tracker.reject(err); + } + } + } + + function LoginBase64Factory() { + // named assignments + var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + + // factory object and function mappings + var factory = { + encode: encode, + decode: decode + } + + return factory; + + // function definitions + + function encode(input) { + var output = ""; + var chr1, chr2, chr3 = ""; + var enc1, enc2, enc3, enc4 = ""; + var i = 0; + + do { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output = output + + keyStr.charAt(enc1) + + keyStr.charAt(enc2) + + keyStr.charAt(enc3) + + keyStr.charAt(enc4); + chr1 = chr2 = chr3 = ""; + enc1 = enc2 = enc3 = enc4 = ""; + } while (i < input.length); + + return output; + } + + function decode(input) { + var output = ""; + var chr1, chr2, chr3 = ""; + var enc1, enc2, enc3, enc4 = ""; + var i = 0; + + // remove all characters that are not A-Z, a-z, 0-9, +, /, or = + var base64test = /[^A-Za-z0-9\+\/\=]/g; + if (base64test.exec(input)) { + alert("There were invalid base64 characters in the input text.\n" + + "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" + + "Expect errors in decoding."); + } + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + + do { + enc1 = keyStr.indexOf(input.charAt(i++)); + enc2 = keyStr.indexOf(input.charAt(i++)); + enc3 = keyStr.indexOf(input.charAt(i++)); + enc4 = keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 != 64) { + output = output + String.fromCharCode(chr2); + } + if (enc4 != 64) { + output = output + String.fromCharCode(chr3); + } + + chr1 = chr2 = chr3 = ""; + enc1 = enc2 = enc3 = enc4 = ""; + + } while (i < input.length); + + return output; + } + } +})(); \ No newline at end of file diff --git a/src/app/login/login.html b/src/app/login/login.html new file mode 100644 index 00000000..01ee426a --- /dev/null +++ b/src/app/login/login.html @@ -0,0 +1,70 @@ + + + + + \ No newline at end of file diff --git a/src/app/login/login.service.js b/src/app/login/login.service.js new file mode 100644 index 00000000..e1956b0c --- /dev/null +++ b/src/app/login/login.service.js @@ -0,0 +1,437 @@ +/** + * Angular Service for Login and Licensing Mechanism + * @author ndkcha + * @since 0.7.0 + * @version 0.7.0 + */ + +/// + +(function() { + angular.module('automintApp').service('$amLicense', LicenseService); + + LicenseService.$inject = ['$rootScope', '$q', '$http', 'utils', 'amLogin', 'pdbLocal', 'constants', 'amFactory']; + + function LicenseService($rootScope, $q, $http, utils, amLogin, pdbLocal, constants, amFactory) { + // initialize view model for Service + var vm = this; + + // temporary assignments for instance + // no such assignments + + // named assignments to view model + // no such assignments + + // function mappings to view model + vm.loadCredentials = loadCredentials; + vm.checkLogin = checkLogin; + vm.login = login; + vm.changePassword = changePassword; + + // function definitions + + function changePassword(username, newPassword) { + var tracker = $q.defer(); + if (($rootScope.amGlobals == undefined) || ($rootScope.amGlobals.channel == undefined) || ($rootScope.amGlobals.channel == '')) { + failure({ + mint_error: 401 + }); + return; + } + var adminChannels = []; + adminChannels.push($rootScope.amGlobals.channel); + $http({ + method: 'PUT', + url: amFactory.generateChangePwdUrl(), + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + }, + data: $.param({ + name: $rootScope.amGlobals.credentials.username, + oldpass: $rootScope.amGlobals.credentials.password, + newpass: newPassword + }) + }).then(success, failure); + return tracker.promise; + + function success(res) { + if (res.data && res.data.mint_code) { + if (res.data.mint_code == 'PA100') { + $rootScope.amGlobals.credentials.password = newPassword; + amLogin.savePassword(newPassword).then(proceed).catch(doLogin); + return; + } + } + failure({ + mint_error: 300 + }); + } + + function proceed(pres) { + tracker.resolve(pres); + } + + function doLogin(err) { + amLogin.setLoginState(false).then(dl1).catch(dl1); + + function dl1(dl1res) { + failure({ + mint_error: 400 + }); + } + } + + function failure(err) { + var errorCode = -1; + var errorMessage = 'Please check your internet connectivity'; + if (err.mint_error) { + switch (err.mint_error) { + case 400: + vm.errorCode = 1; + vm.errorMessage = 'Cloud not save password! Please login again with new password!'; + break; + case 401: + vm.errorCode = 1; + vm.errorMessage = 'Automint could not collect license details. Please login again!'; + break; + case 300: + vm.errorCode = -1; + vm.errorMessage = 'Could not change password. Please try again!'; + break; + } + } + + tracker.reject({ + error_code: errorCode, + error_message: errorMessage + }); + } + } + + function loadCredentials(username, password) { + if (!$rootScope.amGlobals) + $rootScope.amGlobals = {}; + $rootScope.amGlobals.credentials = { + username: username, + password: password + } + } + + function login(isCodeUsed, code, ignoreCodeUsedError) { + var today = moment().format(), isLoggedIn = false, channel, isSyncableDb = false; + var tracker = $q.defer(); + if (isCodeUsed) + $http.get(amFactory.generateActivationUrl(code)).then(activate, failure); + else { + $http({ + method: 'POST', + url: amFactory.generateAuthUrl(), + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + }, + data: $.param({ + name: $rootScope.amGlobals.credentials.username, + password: $rootScope.amGlobals.credentials.password + }) + }).then(success, failure); + } + return tracker.promise; + + function activate(res) { + if (res.data == undefined) { + failure(); + return; + } + if ((ignoreCodeUsedError != true) && res.data.used) { + tracker.reject({ + message: 'The code is already in use! You cannot use it again!' + }); + return; + } + var startdate = moment(res.data.starts, 'YYYY-MM-DD').format(); + var enddate = moment(res.data.ends, 'YYYY-MM-DD').format(); + if ((res.data.ends == 0) || (res.data.ends == '0')) + isLoggedIn = true; + if ((startdate.localeCompare(today) < 0) && (enddate.localeCompare(today) > 0)) + isLoggedIn = true; + if ((res.data.code != undefined) && (res.data.code == 13)) + processMintCode(-404); + amLogin.saveActivationDetails(vm.code, res.data.starts, res.data.ends).then(proceed).catch(failure); + } + + function success(res) { + if (res.data && res.data.mint_code) { + switch (res.data.mint_code) { + case "AU100": + processLicense(res.data.userCtx, res.data.license); + break; + case "AU200": + processMintCode(200); + break; + case "AU321": + case "AU322": + processMintCode(300); + break; + case "AU330": + processMintCode(330); + break; + } + } else + failure(); + + function processLicense(userData, licenseData) { + if (userData && (userData.name != null) && userData.channels && (Object.keys(userData.channels).length > 1)) + channel = Object.keys(userData.channels)[1]; + checkLicense(); + + function checkLicense() { + if (licenseData) { + var licensestartdate = moment(licenseData.license.starts, 'YYYY-MM-DD').format(), licenseenddate; + if ((licenseData.license.ends == '0') || (licenseData.license.ends == 0)) + isLoggedIn = true; + else { + licenseenddate = moment(licenseData.license.ends, 'YYYY-MM-DD').format(); + if ((licensestartdate.localeCompare(today) < 0) && (licenseenddate.localeCompare(today) > 0)) + isLoggedIn = true; + } + amLogin.saveLicense($rootScope.amGlobals.credentials.username, $rootScope.amGlobals.credentials.password, channel, licenseData.license, licenseData.cloud).then(proceed).catch(failure); + } else + processMintCode(330); + } + } + } + + function proceed(res) { + if (!isLoggedIn) { + processMintCode(-1); + return; + } + $rootScope.amGlobals.configDocIds = { + settings: 'settings' + (channel ? '-' + channel : ''), + treatment: 'treatments' + (channel ? '-' + channel : ''), + inventory: 'inventory' + (channel ? '-' + channel : ''), + workshop: 'workshop' + (channel ? '-' + channel : '') + }; + + var isDbToBeChanged = (($rootScope.amGlobals != undefined) && ($rootScope.amGlobals.creator != '') && ($rootScope.amGlobals.channel != '')); + + if (isDbToBeChanged) + amLogin.changeExistingDocs().then(finalize).catch(finalize); + else + finalize(); + + function finalize(fres) { + isSyncableDb = (($rootScope.amGlobals != undefined) && ($rootScope.amGlobals.credentials != undefined) && ($rootScope.amGlobals.credentials.username != undefined) && ($rootScope.amGlobals.credentials.username != '') && ($rootScope.amGlobals.credentials.password != undefined) && ($rootScope.amGlobals.credentials.password != '')); + if (($rootScope.amGlobals == undefined) || ($rootScope.amGlobals.validity == undefined) || ($rootScope.amGlobals.validity.cloud == undefined) || !isSyncableDb) + isSyncableDb = false; + else { + var cloudstartdate = moment($rootScope.amGlobals.validity.cloud.starts, 'YYYY-MM-DD').format(); + var cloudenddate = moment($rootScope.amGlobals.validity.cloud.ends, 'YYYY-MM-DD').format(); + isSyncableDb = ((cloudstartdate.localeCompare(today) < 0) && (cloudenddate.localeCompare(today) > 0)); + if (($rootScope.amGlobals.validity.cloud.ends == 0) || ($rootScope.amGlobals.validity.cloud.ends == '0')) + isSyncableDb = true; + if (!isSyncableDb) + utils.showSimpleToast('Your cloud services have expired! Please contact Automint Care!'); + } + amLogin.setLoginState(isLoggedIn).then(finallyrespond).catch(finallyrespond); + + function finallyrespond(idk) { + tracker.resolve({ + isLoggedIn: isLoggedIn, + isSyncableDb: isSyncableDb + }); + } + } + } + + function processMintCode(code) { + var message; + switch (code) { + case -1: + message = 'Your license has expired!'; + break; + case 200: + message = 'Incorrect Username or Password'; + break; + case 300: + message = 'There seems to be problem at Server! Please try again or contact Automint Care!'; + break; + case 330: + message = 'No Licensing Details Found for ' + $rootScope.amGlobals.credentials.username + '! Please Try Again or Contact Automint Care!'; + break; + case -404: + message = 'Invalid Activation Code!'; + break; + } + tracker.reject({ + code: code, + message: message + }); + } + + function failure(err) { + if (err) + console.error(err); + tracker.reject({ + message: 'Please check your internet connectivity!' + }); + } + } + + function checkLogin(isLdtbSynced) { + var tracker = $q.defer(); + var errm = undefined; + var today = moment().format(), isLoggedIn = false, isCloudEnabled = false, type, isCloudForceEnabled; + if (isLdtbSynced) + pdbLocal.get(constants.pdb_local_docs.login).then(performLogin).catch(failure); + else + pdbLocal.get(constants.pdb_local_docs.login).then(checkFlags).catch(failure); + return tracker.promise; + + function performLogin(extLd) { + if (extLd.isLoggedIn) { + if (extLd.username && extLd.password) { + loadCredentials(extLd.username, extLd.password); + login(false).then(furtherCheck).catch(handleError); + } else if (extLd.activation && extLd.activation.code) + login(true, extLd.activation.code, true).then(furtherCheck).catch(handleError); + else { + failure(); + } + } else { + failure({ + mintSkipSave: true + }); + } + + function handleError(err) { + if (err.code == undefined) { + furtherCheck(); + return + } + switch (err.code) { + case -404: + errm = 'License Error: Invalid Activation Code!'; + break; + case -1: + errm = 'Your license has expired!'; + break; + case 200: + errm = 'Your password has been changed. Please Login Again'; + break; + case 300: + errm = 'There seems to be problem at Server! Please try again or contact Automint Care!'; + break; + case 330: + errm = 'No Licensing Details Found for ' + $rootScope.amGlobals.credentials.username + '! Please Try Again or Contact Automint Care!'; + break; + } + failure(err); + } + + function furtherCheck(res) { + pdbLocal.get(constants.pdb_local_docs.login).then(checkFlags).catch(failure); + } + } + + function checkFlags(res) { + if (!res.isLoggedIn) { + failure({ + mintSkipSave: true + }); + } + if (res.isCloudForceEnabled != undefined) + isCloudForceEnabled = res.isCloudForceEnabled; + if (res.username && res.password) { + loadCredentials(res.username, res.password); + if (res.license) { + var licensestartdate = moment(res.license.starts, 'YYYY-MM-DD').format(); + var licenseenddate = moment(res.license.ends, 'YYYY-MM-DD').format(); + if ((res.license.ends == 0) || (res.license.ends == '0')) + isLoggedIn = true; + if ((licensestartdate.localeCompare(today) < 0) && (licenseenddate.localeCompare(today) > 0)) + isLoggedIn = true; + } + if (isLoggedIn && res.cloud) { + var cloudstartdate = moment(res.cloud.starts, 'YYYY-MM-DD').format(); + var cloudenddate = moment(res.cloud.ends, 'YYYY-MM-DD').format(); + if ((res.cloud.ends == 0) || (res.cloud.ends == '0')) + isCloudEnabled = true; + if ((cloudstartdate.localeCompare(today) < 0) && (cloudenddate.localeCompare(today) > 0)) + isCloudEnabled = true; + } + if (isLoggedIn) { + type = "license"; + loadCredentials(res.username, res.password); + if (res.isLoggedIn != isLoggedIn) + amLogin.setLoginState(isLoggedIn).then(respond).catch(failure); + else + respond(); + return; + } + } + if (res.activation) { + if ((res.activation.startdate != undefined) && (res.activation.enddate != undefined)) { + var activationstartdate = moment(res.activation.startdate, 'YYYY-MM-DD').format(); + var activationenddate = moment(res.activation.enddate, 'YYYY-MM-DD').format(); + if ((res.activation.enddate == 0) || (res.activation.enddate == '0')) + isLoggedIn = true; + if ((activationstartdate.localeCompare(today) < 0) && (activationenddate.localeCompare(today) > 0)) + isLoggedIn = true; + if (isLoggedIn) { + type = "activation"; + if (res.isLoggedIn != isLoggedIn) + amLogin.setLoginState(isLoggedIn).then(respond).catch(failure); + else + respond(); + return; + } + } + } + failure(res); + + function respond(saveresponse) { + $rootScope.amGlobals.creator = (res.username ? res.username : ''); + $rootScope.amGlobals.channel = (res.channel ? res.channel : ''); + $rootScope.amGlobals.configDocIds = { + settings: 'settings' + (res.channel ? '-' + res.channel : ''), + treatment: 'treatments' + (res.channel ? '-' + res.channel : ''), + inventory: 'inventory' + (res.channel ? '-' + res.channel : ''), + workshop: 'workshop' + (res.channel ? '-' + res.channel : '') + } + var obj = { + isCloudForceEnabled: isCloudForceEnabled, + isLoggedIn: isLoggedIn, + isCloudEnabled: isCloudEnabled, + type: type, + } + switch (type) { + case "license": + obj.credentials = { + username: res.username, + password: res.password + }; + if (isCloudEnabled) + obj.cloudenddate = moment(res.cloud.ends, 'YYYY-MM-DD').format(); + break; + case "activation": + obj.enddate = res.activation.enddate; + break; + } + tracker.resolve(obj); + } + } + + function failure(err) { + if (err.mintSkipSave) + ro(); + else + amLogin.setLoginState(false).then(ro).catch(ro); + + function ro(rores) { + tracker.reject(errm); + } + } + } + } +})(); \ No newline at end of file diff --git a/src/app/views/initializing.html b/src/app/views/initializing.html new file mode 100644 index 00000000..44295336 --- /dev/null +++ b/src/app/views/initializing.html @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/src/app/views/lockscreen.html b/src/app/views/lockscreen.html deleted file mode 100644 index b5df879d..00000000 --- a/src/app/views/lockscreen.html +++ /dev/null @@ -1,77 +0,0 @@ - -
- - Add a Service - add - - Add a Service -
- -
- - - - Unlock - - {{vm.message}} -
-
\ No newline at end of file diff --git a/src/app/views/updatepassword.tmpl.html b/src/app/views/updatepassword.tmpl.html new file mode 100644 index 00000000..b784dfbe --- /dev/null +++ b/src/app/views/updatepassword.tmpl.html @@ -0,0 +1,51 @@ + + + +
+ Your password has been changed. Please provide your new password +
+ +
+ + {{$root.amGlobals.credentials.username}} +
+
+ + +
+
+ {{vm.message}} + + Submit + send + +
+
+
\ No newline at end of file diff --git a/src/assets/css/automint.css b/src/assets/css/automint.css index 742f9b42..24978463 100644 --- a/src/assets/css/automint.css +++ b/src/assets/css/automint.css @@ -2,15 +2,49 @@ * Customised style sheet for Automint App * @author ndkcha * @since 0.4.1 - * @version 0.6.4 + * @version 0.7.0 */ + .am-restart-app .message { + margin-bottom: 4px; + } + + .am-restart-app { + position: fixed; + z-index: 998; + width: 100%; + height: 100%; + background: rgba(10, 10, 10, 0.5); + } + +.am-loading-icon { + background: white; + box-shadow: 1px 1px 3px 1px rgba(30,30,30,0.3); + border-radius: 4px; +} + + #page_preloader { + width: 100%; + height: 100%; + z-index: 997; + background: white; + } + input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } +.am-input-box { + margin: 0.6rem; +} + +.am-input-box label { + margin-bottom: 0; + margin-right: 0.4rem; +} + .am-jobcard-text { color: #FB8C00; font-weight: 500; @@ -120,17 +154,22 @@ input[type=number]::-webkit-outer-spin-button { -webkit-transition: color 1s ease 0s; -moz-transition: color 1s ease 0s; transition: color 1s ease 0s; - box-shadow: 0px 1px 3px 1px rgba(30, 30, 30, 0.3); + box-shadow: 0px 1px 3px 1px rgba(30, 30, 30, 0.2); } .am-table-input:focus { color: rgba(30, 30, 30, 0.9); - box-shadow: 1px 1px 3px 1px rgba(30, 30, 30, 0.3); + box-shadow: 1px 1px 3px 1px rgba(30, 30, 30, 0.2); } .am-table-input.search-box { font-size: small; - box-shadow: 0px 1px 3px 1px rgba(30, 30, 30, 0.3); + box-shadow: 0px 1px 3px 1px rgba(30, 30, 30, 0.2); +} + +.am-table-input:disabled { + background: white; + box-shadow: none; } .am-checkbox .md-icon { @@ -284,7 +323,7 @@ md-sidenav.md-closed.md-locked-open-add-active { .am-back-button { background: transparent; - z-index: 999; + z-index: 99; position: fixed; top: 0.4rem; } @@ -382,23 +421,18 @@ md-sidenav.md-closed.md-locked-open-add-active { } .am-lockscreen { - z-index: 9999; - display: none; + z-index: 997; width: 100%; height: 100%; } -.am-lockscreen.active { - display: block; -} - .am-lockscreen.ng-enter { - animation: fadeIn 0.5s both ease-in; + animation: fadeIn 300ms both ease-in; } .am-lockscreen.ng-leave { transform-origin: 0% 0%; - animation: fadeOut 1s both ease-in; + animation: fadeOut 300ms both ease-in; } diff --git a/src/assets/img/loader.gif b/src/assets/img/loader.gif new file mode 100644 index 00000000..0adc2964 Binary files /dev/null and b/src/assets/img/loader.gif differ diff --git a/src/assets/js/angular-elastic-input.min.js b/src/assets/js/angular-elastic-input.min.js new file mode 100755 index 00000000..31dba480 --- /dev/null +++ b/src/assets/js/angular-elastic-input.min.js @@ -0,0 +1,11 @@ +/** + * angular-elastic-input + * A directive for AngularJS which automatically resizes the width of input field according to the content, while typing. + * @version: 2.4.0 + * @author: Jacek Pulit + * @license: MIT + * @build: Thursday, July 7th, 2016, 11:27:27 PM GMT+0200 + */ +(function(){ +"use strict";angular.module("puElasticInput",[]).directive("puElasticInput",["$document","$window",function(a,b){function c(a,b){var c="";if(window.getComputedStyle)c=getComputedStyle(a).getPropertyValue(b);else if(a.currentStyle)try{c=a.currentStyle[b]}catch(d){}return c}function d(a){var b,d=a[0];do d=d.parentNode,b=parseInt(c(d,"width"),10)-parseInt(c(d,"padding-left"),10)-parseInt(c(d,"padding-right"),10);while("block"!=c(d,"display")&&"body"!=d.nodeName.toLowerCase());return b+"px"}function e(a,c,e){var f=b.getComputedStyle(c[0]),g="none"===f.maxWidth?d(c):f.maxWidth;c.css("minWidth",e.puElasticInputMinwidth||f.minWidth),c.css("maxWidth",e.puElasticInputMaxwidth||g),angular.forEach(["fontFamily","fontSize","fontWeight","fontStyle","letterSpacing","textTransform","wordSpacing"],function(b){a.css(b,f[b])}),a.css("paddingLeft",f.textIndent),"border-box"===f.boxSizing?angular.forEach(["paddingLeft","paddingRight","borderLeftStyle","borderLeftWidth","borderRightStyle","borderRightWidth"],function(b){a.css(b,f[b])}):"padding-box"===f.boxSizing&&angular.forEach(["paddingLeft","paddingRight"],function(b){a.css(b,f[b])})}var f=angular.element('
');return angular.element(a[0].body).append(f),{restrict:"A",link:function(a,b,c){function d(){var a=b.val()||c.placeholder||"";if(g.text()!=a){g.text(a);var d=parseInt(c.puElasticInputWidthDelta)||1;b.css("width",g.prop("offsetWidth")+d+"px")}}c.$set("ngTrim","true"===c.ngTrim?"true":"false");var g=angular.element('');e(g,b,c),f.append(g),d(),a.$watch(c.ngModel,d),b.on("keydown keyup focus input propertychange change",d),a.$on("$destroy",function(){g.remove()})}}}]); +})(); \ No newline at end of file diff --git a/src/automint_modules/am-mailer.js b/src/automint_modules/am-mailer.js index afdb1bd3..5856c522 100644 --- a/src/automint_modules/am-mailer.js +++ b/src/automint_modules/am-mailer.js @@ -2,7 +2,7 @@ * Module to send emails * @author ndkcha * @since 0.4.1 - * @version 0.6.0 + * @version 0.7.0 */ /// @@ -45,7 +45,7 @@ html: emailTemplate }, function(err, email) { if (err) { - console.warn(err); + console.error(err); return; } diff --git a/src/automint_modules/am-preferences.js b/src/automint_modules/am-preferences.js index 6546af46..9738a859 100644 --- a/src/automint_modules/am-preferences.js +++ b/src/automint_modules/am-preferences.js @@ -2,7 +2,7 @@ * Module for storing local usage preferences * @author ndkcha * @since 0.6.4 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -13,7 +13,8 @@ var Promise = require('promise'); // named assignments - var PREF_DIR = __dirname + "/../../app.asar.unpacked/"; + // var PREF_DIR = __dirname + "/../../app.asar.unpacked/"; + var PREF_DIR = process.resourcesPath + "/app.asar.unpacked/"; var PREF_FILE = PREF_DIR + 'automint-preferences.json'; var e404 = { success: false, @@ -23,6 +24,7 @@ // export as module module.exports = { + getUserData: getUserData, storePreference: storePreference, getPreference: getPreference, getAllPreferences: getAllPreferences @@ -30,6 +32,15 @@ // function definitions + function getUserData() { + try { + var data = JSON.parse(fs.readFileSync(PREF_FILE), 'utf-8'); + return (data['automint.userDataPath']); + } catch(e) { + return e404; + } + } + function storePreference(key, value) { fs.readFile(PREF_FILE, changePreferences); diff --git a/src/automint_modules/googleoauth/google-auth.js b/src/automint_modules/googleoauth/google-auth.js index aea04e1c..fcf4697e 100644 --- a/src/automint_modules/googleoauth/google-auth.js +++ b/src/automint_modules/googleoauth/google-auth.js @@ -2,7 +2,7 @@ * Module to authenticate user to Google Server * @author ndkcha * @since 0.4.1 - * @version 0.6.4 + * @version 0.7.0 */ /// @@ -20,7 +20,8 @@ // initialize essential params for Google && Gmail API var SCOPE = ['https://www.googleapis.com/auth/gmail.readonly', 'https://www.googleapis.com/auth/gmail.send']; - var TOKEN_DIR = __dirname + "/../../../app.asar.unpacked/"; + var TOKEN_DIR = process.resourcesPath + "/app.asar.unpacked/"; + // var TOKEN_DIR = __dirname + "/../../../app.asar.unpacked/"; var TOKEN_PATH = TOKEN_DIR + 'google-cred.json'; // declare callback function and boolean for requesting new token @@ -42,7 +43,7 @@ // process file containing client secrets and extract its contents for authorization function processClientSecrets(err, content) { if (err) { - console.warn('Error loading content: ' + err); + console.error('Error loading content: ' + err); return; } authorize(JSON.parse(content), cbFn); @@ -108,7 +109,7 @@ function handleToken(err, token) { if (err) { - console.warn('Error while trying to retrieve access token', err); + console.error('Error while trying to retrieve access token', err); return; } oAuth2Client.credentials = token; diff --git a/src/automint_modules/print/am-save-html.js b/src/automint_modules/print/am-save-html.js index 22fc2a4a..78a009f5 100644 --- a/src/automint_modules/print/am-save-html.js +++ b/src/automint_modules/print/am-save-html.js @@ -12,7 +12,8 @@ var fs = require('fs'); // constants used for the module (but not exported) - var PREVIEW_DIR = __dirname + "/../../../app.asar.unpacked/"; + var PREVIEW_DIR = process.resourcesPath + "/app.asar.unpacked/"; + // var PREVIEW_DIR = __dirname + "/../../../app.asar.unpacked/"; var PREVIEW_PATH = PREVIEW_DIR + "print-preview.html"; // export relevant function as indevidual module diff --git a/src/index.html b/src/index.html index 57167ecd..2af251c4 100644 --- a/src/index.html +++ b/src/index.html @@ -49,21 +49,31 @@ + + -
+
+
+
+ {{busyApp.message}} + Restrating App.. +
+ +
+
+
+
- - -
-
+ +
- +
-
+
diff --git a/src/main.js b/src/main.js index e130ff03..88685114 100644 --- a/src/main.js +++ b/src/main.js @@ -2,7 +2,7 @@ * Entrance file for Atom Electron App * @author ndkcha * @since 0.1.0 - * @version 0.6.4 by @vrlkacha + * @version 0.7.0 */ 'use strict'; @@ -11,20 +11,31 @@ const electron = require('electron'); // Module to control application life. const app = electron.app; + const dialog = electron.dialog; // Module to create native browser window. const BrowserWindow = electron.BrowserWindow; - + // Module for IPC + const ipcMain = electron.ipcMain; // Importing Eelctron Squirrel Startup - if(require('electron-squirrel-startup')) return; + if (require('electron-squirrel-startup')) return; // Module to Auto Update app - var autoUpdater = electron.autoUpdater; - var os = require('os'); + var autoUpdater = electron.autoUpdater; + var os = require('os'); // var feedURL = 'http://updates.automint.in/releases/' + (os.platform()) + '/' + (os.arch()); var feedURL = 'http://updates.automint.in/releases/win32/ia32'; + // Module to check preferences + const ammPreferences = require('./automint_modules/am-preferences.js'); + const fs = require('fs'); + // Keep track of path whether it exists + var isUserDataPathExists = true; + autoUpdater.addListener("error", function(error) {}); + + autoUpdater.addListener("update-downloaded", OnAutomintUpdated); + autoUpdater.setFeedURL(feedURL); if (process.argv[1] == '--squirrel-firstrun') { - setTimeout(()=> { + setTimeout(() => { autoUpdater.checkForUpdates(); }, 180000) } else { @@ -42,9 +53,22 @@ return; } + // setUserDataPath(); + var amUserDataPath = ammPreferences.getUserData(); + if ((typeof amUserDataPath) == "string") { + try { + fs.accessSync(amUserDataPath); + app.setPath('userData', amUserDataPath); + isUserDataPathExists = true; + } catch (e) { + isUserDataPathExists = false; + } + } + + // This method will be called when Electron has finished // initialization and is ready to create browser windows. - app.on('ready', createWindow); + app.on('ready', OnAppReady); // Quit when all windows are closed. app.on('window-all-closed', function() { @@ -63,6 +87,60 @@ } }); + app.on('certificate-error', (event, webContents, url, error, certificate, callback) => { + // Verification logic. + event.preventDefault() + callback(true); + }) + + ipcMain.on('am-quit-update', updateAndRestartApp); + + ipcMain.on('am-do-restart', restartApp); + + function restartApp(event, args) { + app.relaunch({ + args: process.argv.slice(1).concat('--relaunch') + }); + app.quit(); + } + + function updateAndRestartApp(event, args) { + autoUpdater.quitAndInstall(); + } + + function OnAutomintUpdated(event, releaseNotes, releaseName, releaseDate, updateURL) { + if (mainWindow && mainWindow.webContents) + mainWindow.webContents.send('automint-updated', true); + } + + function OnAppReady() { + if (isUserDataPathExists) + createWindow(); + else { + var msgbox = dialog.showMessageBox({ + type: 'info', + message: 'Select Path of User Data', + buttons: ['OK'], + defaultId: 0, + icon: undefined + }, openCorrectFileUrl); + } + + function openCorrectFileUrl(buttonIndex) { + if (buttonIndex == 0) { + var newPath = dialog.showOpenDialog({ + properties: ['openDirectory'] + }); + if (newPath) { + ammPreferences.storePreference('automint.userDataPath', newPath[0]); + restartApp(); + return; + } + } + app.exit(0); + } + } + function createWindow() { // Create the browser window. mainWindow = new BrowserWindow({ @@ -71,8 +149,18 @@ }); mainWindow.maximize(); // and load the index.html of the app. + mainWindow.loadURL('file://' + __dirname + '/index.html'); + // mainWindow.webContents.openDevTools(); + + fs.watchFile(app.getPath('userData'), (curr, prev) => { + if (curr.ino == 0) { + fs.unwatchFile(app.getPath('userData')); + restartApp(); + } + }); + // Emitted when the window is closed. mainWindow.on('closed', function() { // Dereference the window object, usually you would store windows diff --git a/src/package.json b/src/package.json index ffffd125..0c8c684b 100644 --- a/src/package.json +++ b/src/package.json @@ -1,6 +1,6 @@ { "name": "Automint", - "version": "0.6.5", + "version": "0.7.0", "description": "CRM by Automint", "main": "main.js", "scripts": { @@ -16,6 +16,7 @@ }, "dependencies": { "base64url": "^1.0.6", + "fs-extra": "^0.30.0", "google-auth-library": "^0.9.8", "googleapis": "^5.2.1", "premailer-api": "^1.0.4",