Project:
View Issue Details[ Jump to Notes ] | [ Issue History ] [ Print ] | |||||||
ID | ||||||||
0051841 | ||||||||
Type | Category | Severity | Reproducibility | Date Submitted | Last Update | |||
defect | [Retail Modules] Web POS | major | always | 2023-03-13 12:33 | 2023-07-10 11:11 | |||
Reporter | sofidossant | View Status | public | |||||
Assigned To | ranjith_qualiantech_com | |||||||
Priority | high | Resolution | no change required | Fixed in Version | ||||
Status | closed | Fix in branch | Fixed in SCM revision | |||||
Projection | none | ETA | none | Target Version | ||||
OS | Any | Database | Any | Java version | ||||
OS Version | Database version | Ant version | ||||||
Product Version | pi | SCM revision | ||||||
Review Assigned To | ||||||||
Regression level | ||||||||
Regression date | ||||||||
Regression introduced in release | ||||||||
Regression introduced by commit | ||||||||
Triggers an Emergency Pack | No | |||||||
Summary | 0051841: ERROR with Chrome: 111.0.5563.64 | |||||||
Description | We have detected that with Chrome version: 111.0.5563.64 (official build) (64 bits) the WebPOS cannot be accessed via IP. We have tried with two different clients, one in version 22Q1 and the other in version 22Q2, and we get the same error. Entering through localhost or 127.0.0.1 there is no problem but if we try it through another computer and through IP we get the following error (attached) | |||||||
Steps To Reproduce | - Use a enviroment local - Checked the version of chrome 111.0.5563.64 (official build) (64 bits) - Open the webPos | |||||||
Tags | No tags attached. | |||||||
Attached Files | image.png [^] (156,052 bytes) 2023-03-13 12:33
issue51841_20Q4_posterminal.diff [^] (8,983 bytes) 2023-06-29 14:02 [Show Content] [Hide Content] diff --git a/src/org/openbravo/retail/posterminal/OBPOSComponentProvider.java b/src/org/openbravo/retail/posterminal/OBPOSComponentProvider.java index 42ee25530..00dee0a5a 100644 --- a/src/org/openbravo/retail/posterminal/OBPOSComponentProvider.java +++ b/src/org/openbravo/retail/posterminal/OBPOSComponentProvider.java @@ -398,6 +398,7 @@ public class OBPOSComponentProvider extends BaseComponentProvider { businesslogic( "app/model/business-object/ticket-list/actions/MarkIgnoreCheckIfIsActiveToPendingTickets"), // businesslogic("app/model/business-object/ticket-list/actions/UpdateBPInAllTickets"), // + businesslogic("app/model/business-object/ticket-list/actions/DeleteTicket"), // businesslogic("app/model/business-object/ticket-list/actions/SaveTicket"), // // Synchronization Buffer diff --git a/web/org.openbravo.retail.posterminal/app/model/business-object/ticket-list/actions/DeleteTicket.js b/web/org.openbravo.retail.posterminal/app/model/business-object/ticket-list/actions/DeleteTicket.js new file mode 100644 index 000000000..d7e6a66f0 --- /dev/null +++ b/web/org.openbravo.retail.posterminal/app/model/business-object/ticket-list/actions/DeleteTicket.js @@ -0,0 +1,27 @@ +/* + ************************************************************************************ + * Copyright (C) 2023 Openbravo S.L.U. + * Licensed under the Openbravo Commercial License version 1.0 + * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html + * or in the legal folder of this module distribution. + ************************************************************************************ + */ + +/** + * @fileoverview Declares an action that delete the tickets from the state.TicketList + */ +OB.App.StateAPI.TicketList.registerAction( + 'deleteTicket', + (ticketList, payload) => { + const newTicketList = [...ticketList]; + payload.ticketIdList.forEach(ticketIdToDelete => { + const index = newTicketList.findIndex( + ticket => ticket.id === ticketIdToDelete + ); + if (index >= 0) { + newTicketList.splice(index, 1); + } + }); + return newTicketList; + } +); diff --git a/web/org.openbravo.retail.posterminal/js/components/modal-pay-open-tickets.js b/web/org.openbravo.retail.posterminal/js/components/modal-pay-open-tickets.js index f822df5df..a49d55483 100644 --- a/web/org.openbravo.retail.posterminal/js/components/modal-pay-open-tickets.js +++ b/web/org.openbravo.retail.posterminal/js/components/modal-pay-open-tickets.js @@ -410,6 +410,7 @@ enyo.kind({ j, wrongOrder, firstCheck = true, + currentTicket = OB.App.State.getState().Ticket, cancellingOrdersToCheck = OB.App.State.TicketList.Utils.getAllTickets(), showSomeOrderIsPaidPopup; diff --git a/web/org.openbravo.retail.posterminal/js/data/windowmodel.js b/web/org.openbravo.retail.posterminal/js/data/windowmodel.js index 04b2145ab..e089a2f27 100644 --- a/web/org.openbravo.retail.posterminal/js/data/windowmodel.js +++ b/web/org.openbravo.retail.posterminal/js/data/windowmodel.js @@ -13,27 +13,15 @@ OB.Model.WindowModel = Backbone.Model.extend({ data: {}, load: function() { - var me = this; if (!this.models) { this.models = []; } _.extend(this.models, Backbone.Events); - - if (!OB.MobileApp.model.get('loggedOffline')) { - OB.Dal.loadModels(true, this.models, this.data, undefined, function() { - if (me.init) { - me.init(); - } - me.trigger('ready'); - }); - } else { - if (this.init) { - this.init(); - } - this.trigger('ready'); + if (this.init) { + this.init(); } - //TODO: load offline models when regesitering window + this.trigger('ready'); }, setAllOff: function(model) { diff --git a/web/org.openbravo.retail.posterminal/js/login/model/login-model.js b/web/org.openbravo.retail.posterminal/js/login/model/login-model.js index 4c9e5b1df..f1b812529 100644 --- a/web/org.openbravo.retail.posterminal/js/login/model/login-model.js +++ b/web/org.openbravo.retail.posterminal/js/login/model/login-model.js @@ -68,13 +68,10 @@ }, // setting here the localDB, overrides the OB.MobileApp.model localDB default localDB: { - size: - OB.UTIL.VersionManagement.current.posterminal.WebSQLDatabase.size, - name: - OB.UTIL.VersionManagement.current.posterminal.WebSQLDatabase.name, + size: OB.UTIL.VersionManagement.current.posterminal.database.size, + name: OB.UTIL.VersionManagement.current.posterminal.database.name, displayName: - OB.UTIL.VersionManagement.current.posterminal.WebSQLDatabase - .displayName + OB.UTIL.VersionManagement.current.posterminal.database.displayName }, logDBTrxThreshold: 300, logDBStmtThreshold: 1000, diff --git a/web/org.openbravo.retail.posterminal/js/main.js b/web/org.openbravo.retail.posterminal/js/main.js index 80903eb29..a58fe24f9 100644 --- a/web/org.openbravo.retail.posterminal/js/main.js +++ b/web/org.openbravo.retail.posterminal/js/main.js @@ -1,6 +1,6 @@ /* ************************************************************************************ - * Copyright (C) 2012-2019 Openbravo S.L.U. + * Copyright (C) 2012-2023 Openbravo S.L.U. * Licensed under the Openbravo Commercial License version 1.0 * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html * or in the legal folder of this module distribution. @@ -44,9 +44,9 @@ /** * Global versions for WebPOS */ - // Add the current WebSQL database version for WebPOS + // Add the current database version for WebPOS OB.UTIL.VersionManagement.current.posterminal = { - WebSQLDatabase: { + database: { name: 'WEBPOS', size: 50 * 1024 * 1024, displayName: 'Openbravo Web POS' diff --git a/web/org.openbravo.retail.posterminal/js/utils/ticketListUtils.js b/web/org.openbravo.retail.posterminal/js/utils/ticketListUtils.js index 6e74df82d..593a1c9bc 100644 --- a/web/org.openbravo.retail.posterminal/js/utils/ticketListUtils.js +++ b/web/org.openbravo.retail.posterminal/js/utils/ticketListUtils.js @@ -1028,29 +1028,28 @@ ).filter(ticket => ticket.hasbeenpaid === 'N'); if (ordersNotProcessed.length > 0) { - var existingOrder = _.find(ordersNotProcessed.models, function(order) { + const existingOrder = ordersNotProcessed.find(order => { return ( - order.get('id') === model.get('id') || - order.get('oldId') === model.get('id') || - (order.get('canceledorder') && - order.get('canceledorder').get('id') === model.get('id')) + order.id === model.get('id') || + order.oldId === model.get('id') || + (order.canceledorder && order.canceledorder.id === model.get('id')) ); }); if (existingOrder) { orderTypeMsg = OB.I18N.getLabel('OBPOS_ticket'); - if (existingOrder.get('isLayaway')) { + if (existingOrder.isLayaway) { orderTypeMsg = OB.I18N.getLabel('OBPOS_LblLayaway'); - } else if (existingOrder.get('isQuotation')) { + } else if (existingOrder.isQuotation) { orderTypeMsg = OB.I18N.getLabel('OBPOS_Quotation'); } // Getting Other Session User's username - OB.App.OfflineSession.sessionWithId(existingOrder.get('session')) + OB.App.OfflineSession.sessionWithId(existingOrder.session) .then(session => { if (!session) { return null; } - return OB.App.OfflineSession.withId(this.model.get('updatedBy')); + return OB.App.OfflineSession.withId(existingOrder.updatedBy); }) .then(user => { if (!user) { @@ -1060,7 +1059,7 @@ enyo.format( OB.I18N.getLabel('OBPOS_ticketAlreadyOpenedInSession'), orderTypeMsg, - existingOrder.get('documentNo'), + existingOrder.documentNo, user.name ), enyo.format( @@ -1071,14 +1070,11 @@ { label: OB.I18N.getLabel('OBMOBC_LblOk'), action: function() { - //replace for state action that removes ticket in ticketlist - OB.Dal.remove( - existingOrder, - function() { - callback(model); - }, - OB.UTIL.showError - ); + OB.App.State.TicketList.deleteTicket({ + ticketIdList: [existingOrder.id] + }).then(() => { + callback(model); + }); } }, { issue51841_20Q4_core.diff [^] (113,976 bytes) 2023-06-29 16:36 [Show Content] [Hide Content] diff --git a/web/org.openbravo.mobile.core/app/model/masterdata/MasterdataController.js b/web/org.openbravo.mobile.core/app/model/masterdata/MasterdataController.js index 6b8885ba..c4d279f8 100644 --- a/web/org.openbravo.mobile.core/app/model/masterdata/MasterdataController.js +++ b/web/org.openbravo.mobile.core/app/model/masterdata/MasterdataController.js @@ -82,15 +82,16 @@ * Opens the master data IndexedDB database, creating it if it does not exist * @throws {Error} Database can not be opened */ - async openDatabase() { - // do not check model changes if the db was already opened - if (databaseController.getDatabase()) { - return; - } - const existModelChanges = this.recomputeModelHash(); + async openDatabase( + { checkModelChanges = true, statusCallback } = { checkModelChanges: true } + ) { + const existModelChanges = checkModelChanges && this.recomputeModelHash(); if (existModelChanges) { // there are changes in the master data models, db should be recreated OB.info(`Deleting IndexedDB master data database`); + if (statusCallback) { + statusCallback({ deleteDatabase: true }); + } await databaseController .deleteDatabase() .catch(error => OB.error(error)); @@ -107,6 +108,9 @@ OB.UTIL.localStorage.removeItem('POSLastIncRefresh'); } await databaseController.openDatabase(); + if (statusCallback) { + statusCallback({ openDatabase: true }); + } } /** diff --git a/web/org.openbravo.mobile.core/source/data/ob-dal.js b/web/org.openbravo.mobile.core/source/data/ob-dal.js index 3afb27e9..1ded2ee9 100644 --- a/web/org.openbravo.mobile.core/source/data/ob-dal.js +++ b/web/org.openbravo.mobile.core/source/data/ob-dal.js @@ -1,6 +1,6 @@ /* ************************************************************************************ - * Copyright (C) 2012-2020 Openbravo S.L.U. + * Copyright (C) 2012-2023 Openbravo S.L.U. * Licensed under the Openbravo Commercial License version 1.0 * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html * or in the legal folder of this module distribution. @@ -26,45 +26,6 @@ OB.Dal = OB.Dal || {}; OB.Dal.stackSize = 0; OB.Dal.ErrorWritingToDisk = false; - function executeSqlErrorHandler( - logLevel, - header, - objectInvolved, - txError, - e, - caller - ) { - // arguments check - OB.UTIL.Debug.execute(function() { - if (!logLevel) { - throw 'executeSqlErrorHandler: missing logLevel'; - } - if (!header) { - throw 'executeSqlErrorHandler: missing header'; - } - if (!objectInvolved) { - throw 'executeSqlErrorHandler: missing objectInvolved'; - } - if (!e) { - throw 'executeSqlErrorHandler: missing e'; - } - }); - // show an error - var link = OB.UTIL.getStackLink(3); - - var header2 = header + " '" + objectInvolved + "'"; - // log depending on the logLevel - if (logLevel === 'warn') { - OB.warn(OB.UTIL.argumentsToStringifyed(header2, e, link)); - return; - } - if (caller) { - OB.error(OB.UTIL.argumentsToStringifyed(header2, e, caller)); - } else { - OB.error(OB.UTIL.argumentsToStringifyed(header2, e, link)); - } - } - function getCallerInfo() { var message = ''; // Activate this lines to see the caller function @@ -78,89 +39,6 @@ OB.Dal = OB.Dal || {}; return message; } - function silentFunction(f) { - return function() { - if (_.isFunction(f)) { - try { - f(arguments); - } catch (e) { - OB.error( - 'OB.Dal: a success callback threw an exception', - f, - '\n' + e.stack - ); - } - } - }; - } - - /* - * initialize the WebSQL dababase - */ - OB.Dal.openWebSQL = function() { - if (!window.openDatabase) { - return; // Supported browsers check will show browsers supported information. - } - - // do not initialize the db if it was already initialized - if (OB.Data.localDB && OB.Data.localDB.version) { - return OB.Data.localDB; - } - - var dbInfo = OB.MobileApp.model.get('localDB'); - - // arguments check - if (!dbInfo) { - OB.UTIL.Debug.execute(function() { - throw "The database version information must be available before 'OB.Dal.openWebSQL' is called"; - }); - return; - } - - OB.info('OB.Dal.openWebSQL: initializing WebSQL'); - if (OB.I18N.labels) { - OB.UTIL.showLoadingMessage( - OB.I18N.getLabel('OBMOBC_InitializingDatabase') - ); - } - - var undef; - var wsql = window.openDatabase !== undef; - var db; - - if (wsql === false) { - // Support should get this error. Show it in productionn - OB.error('WebSQL error: Unable find the database engine'); - } - - try { - db = - wsql && - window.openDatabase(dbInfo.name, '', dbInfo.displayName, dbInfo.size); - } catch (e) { - // if the database could not be created, logging with OB.error is not available - // Support should get this error. Show it in production - OB.error('Web SQL error: ' + e); - OB.UTIL.Debug.execute(function(e) { - throw 'Web SQL error: ' + e; - }); - return; - } - if (!db) { - // if the database could not be created, logging with OB.error is not available - // Support should get this error. Show it in production - OB.error('Web SQL error'); - OB.UTIL.Debug.execute(function() { - throw 'Web SQL error'; - }); - return; - } - - OB.Data.localDB = db; - - return db; - }; - /** * TODO: localStorage * This is a function to centralize TODO Dal code related to localstorage @@ -212,85 +90,6 @@ OB.Dal = OB.Dal || {}; return new model(tmp); }; - OB.Dal.getWhereClause = function(criteria, propertyMap) { - var appendWhere = true, - firstParam = true, - sql = '', - params = [], - res = {}, - orAnd = ' AND '; - if (criteria && !_.isEmpty(criteria)) { - if (criteria.obdalcriteriaType) { - orAnd = ' ' + criteria.obdalcriteriaType + ' '; - delete criteria.obdalcriteriaType; - } - _.each(_.keys(criteria), function(k) { - var undef, - colName, - val = criteria[k], - operator = - val !== undef && val !== null && val.operator !== undef - ? val.operator - : '=', - value = - val !== undef && val !== null && val.value !== undef - ? val.value - : val; - if (k !== '_orderByClause' && k !== '_orderBy' && k !== '_limit') { - if (appendWhere) { - sql = sql + ' WHERE '; - params = []; - appendWhere = false; - } - - if (_.isArray(propertyMap)) { - if (k === '_filter') { - colName = '_filter'; - } else { - colName = _.find(propertyMap, function(p) { - return k === p.name; - }).column; - } - } else { - colName = propertyMap[k]; - } - - sql = sql + (firstParam ? '' : orAnd) + ' ' + colName + ' '; - - if (value === null || operator === OB.Dal.ISNULL) { - sql = sql + ' IS null '; - } else if (operator === OB.Dal.ISNOTNULL) { - sql = sql + ' IS NOT null '; - } else { - if (operator === OB.Dal.EQ) { - sql = sql + ' = ? '; - } else if (operator === OB.Dal.NEQ) { - sql = sql + ' != ? '; - } else { - sql = sql + ' like ? '; - } - - if (operator === OB.Dal.CONTAINS) { - value = '%' + value + '%'; - } else if (operator === OB.Dal.STARTSWITH) { - value = value + '%'; - } else if (operator === OB.Dal.ENDSWITH) { - value = value + '%'; - } - params.push(value); - } - - if (firstParam) { - firstParam = false; - } - } - }); - } - res.sql = sql; - res.params = params; - return res; - }; - OB.Dal.getTableName = function(model) { if (model) { if (model.getTableName) { @@ -321,13 +120,6 @@ OB.Dal = OB.Dal || {}; return null; }; - OB.Dal.transaction = function(callback, errorCallback, successCallback) { - OB.warn( - 'WebSQL is no longer supported. OB.Dal.transaction should not be used' - ); - OB.Data.localDB.transaction(callback, errorCallback, successCallback); - }; - OB.Dal.findUsingCache = function( cacheName, model, @@ -382,17 +174,6 @@ OB.Dal = OB.Dal || {}; } }; - OB.Dal.findInTransaction = function( - tx, - model, - whereClause, - success, - error, - args - ) { - OB.Dal.find(model, whereClause, success, error, args, tx); - }; - OB.Dal.find = function( model, whereClause, @@ -402,7 +183,6 @@ OB.Dal = OB.Dal || {}; currentTransaction, forceLocal ) { - var callerInfo = getCallerInfo(); var params = null, undef, colType, @@ -411,7 +191,6 @@ OB.Dal = OB.Dal || {}; i, criteria, j, - orderBy, limit; if (OB.UTIL.isNullOrUndefined(model.prototype)) { OB.error('Model name without prototype: ' + model.getTableName()); @@ -617,1201 +396,44 @@ OB.Dal = OB.Dal || {}; } } ); - } else if (OB.Data.localDB) { - var tableName = OB.Dal.getTableName(model), - propertyMap = OB.Dal.getPropertyMap(model), - sql = 'SELECT * FROM ' + tableName, - processResult, - processError; - - processResult = function(tr, result) { - var i, - collectionType = - OB.Collection[model.prototype.modelName + 'List'] || - Backbone.Collection, - collection = new collectionType(); - const len = result.rows ? result.rows.length : result.length; - if (len === 0) { - success(collection, args); - } else { - for (i = 0; i < len; i++) { - collection.add( - OB.Dal.transform( - model, - result.rows ? result.rows.item(i) : result[i] - ) - ); - } - success(collection, args); - } - }; - - processError = function(txError, e) { - if (!args || !args.doNotShowErrors) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.find: table', - tableName, - txError, - e, - callerInfo - ); - } - if (error) { - error(); - } - }; - - if (model.prototype.indexDBModel) { - const indexDBcriteria = new OB.App.Class.Criteria(); - for (var prop in whereClause) { - if (Object.prototype.hasOwnProperty.call(whereClause, prop)) { - indexDBcriteria.criterion(prop, whereClause[prop]); - } - } - OB.App.MasterdataController.find( - model.prototype.indexDBModel, - indexDBcriteria.build() - ) - .then(result => { - processResult(undefined, result); - }) - .catch(error => { - processError(undefined, error.message); - }); - return; - } - - // websql - // arguments check - if (tableName === null) { - OB.warn('OB.Dal.find: tableName not found'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.find: tableName not found'; - }); - } - if (propertyMap === null) { - OB.warn('OB.Dal.find: propertyMap not found'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.find: propertyMap not found'; - }); - } - - if (whereClause && whereClause._orderByClause) { - orderBy = whereClause._orderByClause; - } - - if (whereClause && whereClause._orderBy) { - _.forEach(whereClause._orderBy, function(elem) { - if (_.isUndefined(orderBy)) { - orderBy = ''; - } else { - orderBy += ', '; - } - orderBy += elem.column; - if (!_.isUndefined(elem.asc)) { - if (elem.asc) { - orderBy += ' asc'; - } else { - orderBy += ' desc'; - } - } - }); - } - - if (whereClause && whereClause._limit) { - //set in the model temporary the limit set by the query - model.prototype.tempDataLimit = whereClause._limit; - // set limit + 1 to see if there are more items to retrieve and in that case show a message to narrow the query in order to less items - limit = whereClause._limit + 1; - } else { - limit = model.prototype.dataLimit; - model.prototype.tempDataLimit = undefined; - } - if (whereClause && whereClause._whereClause) { - whereClause.sql = ' ' + whereClause._whereClause; - } else { - whereClause = OB.Dal.getWhereClause(whereClause, propertyMap); - } - sql = sql + whereClause.sql; - params = _.isEmpty(whereClause.params) ? [] : whereClause.params; - - if (orderBy) { - sql = sql + ' ORDER BY ' + orderBy + ' '; - } else if (model.propertyList || model.prototype.propertyMap._idx) { - sql = sql + ' ORDER BY _idx '; - } - - if (limit) { - sql = sql + ' LIMIT ' + limit; - } - - if (currentTransaction) { - currentTransaction.executeSql(sql, params, processResult, processError); - } else { - OB.Data.localDB.readTransaction(function(tx) { - tx.executeSql(sql, params, processResult, processError); - }); - } } else { this.missingLocalStorageLogic(); } }; - OB.Dal.queryUsingCache = function(model, sql, params, success, error, args) { - if ( - OB.Cache.hasItem(sql, params, args ? args.modelsAffectedByCache : null) - ) { - OB.Dal.stackSize++; - if (OB.Dal.stackSize % 50 === 0) { - setTimeout(function() { - success( - OB.Cache.getItem( - sql, - params, - args ? args.modelsAffectedByCache : null - ), - args, - args ? args.modelsAffectedByCache : null - ); - }, 0); - } else { - success( - OB.Cache.getItem( - sql, - params, - args ? args.modelsAffectedByCache : null - ), - args, - args ? args.modelsAffectedByCache : null - ); - } - } else { - OB.Dal.query( - model, - sql, - params, - function(records) { - OB.Cache.putItem( - sql, - params, - records, - args ? args.modelsAffectedByCache : null - ); - success(records, args); - }, - error, - args - ); - } - }; - - OB.Dal.queryInTransaction = function( - tx, - model, - sql, - params, - success, - error, - args - ) { - OB.Dal.query(model, sql, params, success, error, args, tx); - }; - - OB.Dal.query = function( + OB.Dal.get = function( model, - sql, - params, + id, success, error, - args, + empty, currentTransaction, - limit + local ) { - var processResult, processError; - processResult = function(tr, result) { - var i, - collectionType = - OB.Collection[model.prototype.modelName + 'List'] || - Backbone.Collection, - collection = new collectionType(), - len = result.rows.length; - if (len === 0) { - success(collection, args); - } else { - for (i = 0; i < len; i++) { - collection.add(OB.Dal.transform(model, result.rows.item(i))); - } - success(collection, args); - } - }; - - processError = function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.query: table', - model.prototype.modelName, - txError, - e - ); - if (_.isFunction(error)) { - error(); - } - }; - - if (OB.Data.localDB) { - if (_.isNumber(limit)) { - //set in the model temporary the limit set by the query - model.prototype.tempDataLimit = limit; - // set limit + 1 to see if there are more items to retrieve and in that case show a message to narrow the query in order to less items - sql = sql + ' LIMIT ' + limit + 1; - } else if (model.prototype.dataLimit) { - sql = sql + ' LIMIT ' + model.prototype.dataLimit; - model.prototype.tempDataLimit = undefined; - } - if (currentTransaction) { - currentTransaction.executeSql( - sql, - _.isEmpty(params) ? [] : params, - processResult, - processError + OB.UTIL.Debug.execute(function() { + var caller = OB.UTIL.getStackTrace('get', true); + var callerInfo = getCallerInfo(); + if (!id) { + OB.warn( + '[dberror] OB.Dal.get: id not found. - Caller: ' + + caller + + ' - Caller info: ' + + callerInfo ); - } else { - OB.Data.localDB.transaction(function(tx) { - tx.executeSql( - sql, - _.isEmpty(params) ? [] : params, - processResult, - processError - ); - }); - } - } else { - this.missingLocalStorageLogic(); - } - }; - - OB.Dal.saveInTransaction = function(tx, model, success, error, forceInsert) { - OB.Dal.save(model, success, error, forceInsert, tx); - }; - - OB.Dal.save = function( - model, - success, - error, - forceInsert, - currentTransaction - ) { - var caller = OB.UTIL.getStackTrace('save', true); - var callerInfo = getCallerInfo(); - var modelProto = model.constructor.prototype, - xhr, - rr, - data = {}; - forceInsert = forceInsert || false; - - // Orders should not be saved to WebSQL. Use IndexedDB instead - if (model.modelName === 'Order') { - OB.warn('OB.Dal.save: Attempted to save an Order instance'); - if (_.isFunction(success)) { - success(); } - return; - } - - //Validation to avoid wrong saves - if ( - !_.isUndefined(model.get('json')) && - (_.isEmpty(model.get('json')) || _.isNull(model.get('json'))) - ) { - OB.error( - '[OB.Dal.save] Wrong write in ' + - model.modelName + - ' because json column is undefined.' + - ' - Caller: ' + - caller + - ' - callerInfo: ' + - callerInfo + - '- Model to save is: ' + - JSON.stringify(model.toJSON()) - ); - } - //The id cannot be null + }); if ( - _.isNull(model.get('id')) || - (model.get('json') && - JSON.parse(model.get('json')) && - _.isNull(JSON.parse(model.get('json')).id)) + !local && + model.prototype.remote && + OB.MobileApp.model.hasPermission(model.prototype.remote, true) ) { - OB.error( - '[OB.Dal.save] Wrong model, it has no id. ' + - ' - Caller: ' + - caller + - ' - callerInfo: ' + - callerInfo + - ' Model: ' + - JSON.stringify(model.toJSON()) + - '\n callerInfo: ' + - OB.UTIL.getStackTrace('getCallerInfo', false) - ); - var uuidTmp = OB.UTIL.get_UUID(); - model.set('id', uuidTmp); - model.set('json', JSON.stringify(model.serializeToJSON())); - forceInsert = true; - } - // TODO: properly check model type - if (modelProto && modelProto.online) { - if (!model) { - OB.warn('OB.Dal.save: you need to pass a Model instance to save'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.save: you need to pass a Model instance to save'; - }); - } - data.operationType = 'update'; - data.data = model.toJSON(); - - xhr = new enyo.Ajax({ - url: modelProto.source, - method: 'PUT', - data: JSON.stringify(data), - success: function(inSender, inResponse) { - success(inResponse); - } - }); - rr = new OB.RR.Request({ - ajaxRequest: xhr - }); - rr.exec(xhr.url); - } else if (OB.Data.localDB) { - var modelDefinition = OB.Model[modelProto.modelName], - tableName = OB.Dal.getTableName(modelDefinition), - primaryKey, - primaryKeyProperty = 'id', - sql = '', - params = null, - firstParam = true, - uuid, - propertyName, - filterVal, - processError, - successFunction; - - successFunction = function() { - if (success) { - success(); - } - OB.Cache.resetCacheForModel(modelProto.modelName); - }; - - var updateToBeChecked = false; - - processError = function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.save: table', - tableName, - txError, - e, - callerInfo - ); - if (_.isFunction(error)) { - error(); - } - - if (OB.Dal.ErrorWritingToDisk) { - return false; - } - - OB.UTIL.showConfirmation.display( - OB.I18N.getLabel('OBMOBC_Error'), - //OB.I18N.getLabel('OBMOBC_CriticalErrorObDalSave'), - OB.I18N.getLabel('OBMOBC_CriticalErrorObDalSave') + - '___________ Error: ' + - e.message, - [ - { - label: OB.I18N.getLabel('OBPOS_LblEndSession'), - isConfirmButton: true, - action: function() { - OB.MobileApp.model.logout(); - } - } - ], - { - autoDismiss: false, - onHideFunction: function() { - OB.MobileApp.model.logout(); - }, - classes: 'error' - } - ); - - OB.Dal.ErrorWritingToDisk = true; - return false; - }; - - // websql - // argument checks - if (!tableName) { - OB.warn('OB.Dal.save: tableName not found'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.save: tableName not found'; - }); - } - - if (modelDefinition.getPrimaryKey) { - primaryKey = modelDefinition.getPrimaryKey(); - primaryKeyProperty = primaryKey.name; - } - - if (model.get(primaryKeyProperty) && forceInsert === false) { - if (modelDefinition.getUpdateStatement) { - sql = modelDefinition.getUpdateStatement(); - params = []; - _.each(modelDefinition.getPropertiesForUpdate(), function(property) { - //filter doen't have name and always is the last one - if (property.name) { - params.push(model.get(property.name)); - } - }); - //filter param - if (modelDefinition.hasFilter()) { - filterVal = ''; - _.each(modelDefinition.getFilterProperties(), function( - filterProperty - ) { - filterVal = - OB.UTIL.unAccent(filterVal) + - (model.get(filterProperty) - ? model.get(filterProperty) + '###' - : ''); - }); - params.push(filterVal); - } - //Where param - params.push(model.get(primaryKeyProperty)); - } else { - // UPDATE - if (tableName === 'c_order' || tableName === 'cashmanagement') { - updateToBeChecked = true; - } - sql = 'UPDATE ' + tableName + ' SET '; - - _.each(_.keys(modelProto.properties), function(attr) { - propertyName = modelProto.properties[attr]; - if (attr === 'id') { - return; - } - - if (firstParam) { - firstParam = false; - params = []; - } else { - sql = sql + ', '; - } - - sql = sql + modelProto.propertyMap[propertyName] + ' = ? '; - params.push(model.get(propertyName)); - }); - - if (modelProto.propertiesFilter) { - filterVal = ''; - _.each(modelProto.propertiesFilter, function(prop) { - filterVal = - filterVal + (model.get(prop) ? model.get(prop) + '###' : ''); - }); - sql = sql + ', _filter = ? '; - params.push(filterVal); - } - sql = sql + ' WHERE ' + tableName + '_id = ?'; - params.push(model.get('id')); - } - } else { - params = []; - // INSERT - sql = modelDefinition.getInsertStatement - ? modelDefinition.getInsertStatement() - : modelProto.insertStatement; - if (forceInsert === false) { - uuid = OB.UTIL.get_UUID(); - params.push(uuid); - if (model.getPrimaryKey) { - primaryKey = model.getPrimaryKey(); - model.set(primaryKey.name, uuid); - } else { - model.set('id', uuid); - } - } - //Set params - if (modelDefinition.getProperties) { - _.each(modelDefinition.getProperties(), function(property) { - if (forceInsert === false) { - if (property.primaryKey) { - return; - } - } - //_filter property doesn't have name. - //don't set the filter column. We will do it in the next step - if (property.name === '_filter') { - return; - } - if (property.name) { - params.push( - model.get(property.name) === undefined - ? null - : model.get(property.name) - ); - } - }); - } else { - _.each(modelProto.properties, function(property) { - if (forceInsert === false) { - if ('id' === property) { - return; - } - } - if (model.get(property) === '_filter') { - return; - } - params.push( - model.get(property) === undefined ? null : model.get(property) - ); - }); - } - //set filter column - if (modelDefinition.hasFilter) { - if (modelDefinition.hasFilter()) { - filterVal = ''; - _.each(modelDefinition.getFilterProperties(), function(filterProp) { - filterVal = - OB.UTIL.unAccent(filterVal) + - (model.get(filterProp) ? model.get(filterProp) + '###' : ''); - }); - //Include in the last position but before _idx - params.splice(params.length - 1, 0, filterVal); - } - } else { - if (modelProto.propertiesFilter) { - filterVal = ''; - _.each(modelProto.propertiesFilter, function(prop) { - filterVal = - filterVal + (model.get(prop) ? model.get(prop) + '###' : ''); - }); - //Include in the last position but before _idx - params.splice(params.length - 1, 0, filterVal); - } - } - } - - if (currentTransaction) { - try { - if (updateToBeChecked) { - currentTransaction.executeSql( - sql + - (tableName === 'c_order' - ? " AND hasbeenpaid = 'N'" - : " AND isbeingprocessed = 'N'"), - params, - function(trx, result) { - if (result.rowsAffected !== 1) { - if (tableName === 'c_order') { - OB.error( - '[checkBlocked][transaction]The order does not exists or is frozen. Wrong write in c_order avoided [' + - model.get('id') + - '][' + - model.get('documentNo') + - '] - Caller: ' + - caller + - ' - callerInfo: ' + - callerInfo - ); - } else { - OB.error( - '[checkBlocked][transaction]The cash management does not exists or is frozen. Wrong write in cashmanagement avoided [' + - model.get('id') + - '][' + - model.get('description') + - '] - Caller: ' + - caller + - ' - callerInfo: ' + - callerInfo - ); - } - OB.UTIL.showConfirmation.display( - OB.I18N.getLabel('OBMOBC_WrongUpdate_header'), - OB.I18N.getLabel('OBMOBC_WrongUpdate_body'), - [ - { - label: OB.I18N.getLabel('OBMOBC_Reload'), - classes: 'error', - action: function() { - window.location.reload(); - } - } - ], - { - classes: 'error', - onHideFunction: function() { - window.location.reload(); - } - } - ); - return; - } - if (successFunction) { - successFunction(); - } - }, - processError - ); - } else { - currentTransaction.executeSql( - sql, - params, - silentFunction(successFunction), - processError - ); - } - } catch (e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.save: table', - tableName, - null, - e, - callerInfo - ); - } - } else { - OB.Data.localDB.transaction(function(tx) { - try { - if (updateToBeChecked) { - tx.executeSql( - sql + - (tableName === 'c_order' - ? " AND hasbeenpaid = 'N'" - : " AND isbeingprocessed = 'N'"), - params, - function(trx, result) { - if (result.rowsAffected !== 1) { - if (tableName === 'c_order') { - OB.error( - '[checkBlocked][transaction]The order does not exists or is frozen. Wrong write in c_order avoided [' + - model.get('id') + - '][' + - model.get('documentNo') + - '] - Caller: ' + - caller + - ' - callerInfo: ' + - callerInfo - ); - } else { - OB.error( - '[checkBlocked][transaction]The cash management does not exists or is frozen. Wrong write in cashmanagement avoided [' + - model.get('id') + - '][' + - model.get('description') + - '] - Caller: ' + - caller + - ' - callerInfo: ' + - callerInfo - ); - } - OB.UTIL.showConfirmation.display( - OB.I18N.getLabel('OBMOBC_WrongUpdate_header'), - OB.I18N.getLabel('OBMOBC_WrongUpdate_body'), - [ - { - label: OB.I18N.getLabel('OBMOBC_Reload'), - classes: 'error', - action: function() { - window.location.reload(); - } - } - ], - { - classes: 'error', - onHideFunction: function() { - window.location.reload(); - } - } - ); - return; - } - if (successFunction) { - successFunction(); - } - }, - processError - ); - } else { - tx.executeSql( - sql, - params, - silentFunction(successFunction), - processError - ); - } - } catch (e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.save: table', - tableName, - null, - e, - callerInfo - ); - } - }); - } - } else { - this.missingLocalStorageLogic(); - } - }; - - OB.Dal.removeInTransaction = function(tx, model, success, error) { - OB.Dal.remove(model, success, error, tx); - }; - - /* - * This method checks if model to save is present in the database before saving it. - * If the model is there it does nothing, if not it does an insert. - */ - OB.Dal.saveIfNew = function(model, success, error) { - OB.Dal.transaction(function(tx) { - OB.Dal.getInTransaction( - tx, - OB.Model[model.modelName], - model.get('id'), - success, - error, - function() { - OB.Dal.saveInTransaction(tx, model, success, error, true); - }, - true - ); - }); - }; - - /* - * This method checks if model to save is present in the database before saving it. - * If the model is there it will update, else it will insert. - */ - OB.Dal.saveOrUpdate = function(model, success, error) { - OB.Dal.transaction(function(tx) { - OB.Dal.getInTransaction( - tx, - OB.Model[model.modelName], - model.get('id'), - function() { - OB.Dal.save(model, success, error, false, tx); - }, - error, - function() { - OB.Dal.saveInTransaction(tx, model, success, error, true); - }, - true - ); - }); - }; - - OB.Dal.updateRecordColumn = function( - record, - columnName, - newValue, - successCallback, - errorCallback, - currentTransaction - ) { - if (OB.Data.localDB) { - var modelProto = record.constructor.prototype; - var modelDefinition = OB.Model[modelProto.modelName]; - var tableName = OB.Dal.getTableName(modelDefinition); - var sql = - 'UPDATE ' + - tableName + - ' SET ' + - columnName + - ' = ? WHERE ' + - tableName + - '_id = ?'; - var params = [newValue, record.get('id')]; - if (currentTransaction) { - try { - currentTransaction.executeSql( - sql, - params, - function() { - // success - OB.info( - "'isbeingprocessed' has been set to 'Y' in the '" + - tableName + - "' table, record id: " + - record.get('id') - ); - successCallback(); - }, - function(txError, e) { - // error - OB.error( - "'isbeingprocessed' has NOT been set to 'Y' in the '" + - tableName + - "' table, record id: " + - record.get('id') + - '. Error message: ' + - e.message - ); - errorCallback(txError, e); - } - ); - } catch (e) { - OB.error( - "cannot create a transaction for the '" + - tableName + - "' table, record id: " + - record.get('id') + - '. Error message: ' + - e - ); - errorCallback(null, e); - } - } else { - OB.Data.localDB.transaction(function(tx) { - try { - tx.executeSql( - sql, - params, - function() { - // success - OB.info( - "'isbeingprocessed' has been set to 'Y' in the '" + - tableName + - "' table, record id: " + - record.get('id') - ); - successCallback(); - }, - function(txError, e) { - // error - OB.error( - "'isbeingprocessed' has NOT been set to 'Y' in the '" + - tableName + - "' table, record id: " + - record.get('id') + - '. Error message: ' + - e.message - ); - errorCallback(txError, e); - } - ); - } catch (e) { - OB.error( - "cannot create a transaction for the '" + - tableName + - "' table, record id: " + - record.get('id') + - '. Error message: ' + - e - ); - errorCallback(null, e); - } - }); - } - } - }; - - OB.Dal.createDataDump = function(models, callback) { - var result = [], - cnt = 0, - promises = []; - - if (models.length === 0) { - if (callback) { - callback(); - } - return; - } - - _.each(models, function(model) { - promises.push( - new Promise(function(resolve, reject) { - OB.Dal.find( - model, - null, - function(data) { - cnt++; - // arbitrary high number we can't load more in memory - if (cnt > 5000) { - var msg = - 'Creating backup of more 5000 records, this it probably not supported, last record ' + - JSON.stringify(data); - OB.UTIL.showError(msg); - OB.error(msg); - throw msg; - } - result.push({ - model: model, - data: data.models - }); - resolve(); - }, - function() { - reject(); - } - ); - }) - ); - }); - - Promise.all(promises).then(function() { - if (callback) { - callback(result); - } - }); - }; - - OB.Dal.restoreDataDump = function(dataDump, callback) { - if (!dataDump) { - if (callback) { - callback(); - } - return; - } - - OB.Dal.transaction( - function(tx) { - _.each(dataDump, function(dataDumpEntry) { - OB.Dal.removeAllInTransaction(tx, dataDumpEntry.model); - _.each(dataDumpEntry.data, function(dataEntry) { - OB.Dal.saveInTransaction(tx, dataEntry, null, null, true); - }); - }); - }, - function() { - OB.error( - 'The restore dump failed failed to be commited. data: ' + - JSON.stringify(dataDump) - ); - }, - function() { - if (callback) { - callback(); - } - } - ); - }; - - OB.Dal.remove = function(model, success, error, currentTransaction) { - if (OB.Data.localDB) { - var modelDefinition = OB.Model[model.constructor.prototype.modelName], - modelProto = model.constructor.prototype, - tableName = OB.Dal.getTableName(modelDefinition), - pk, - pkProperty = 'id', - sql = '', - params = [], - processError; - - processError = function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.remove: table', - tableName, - txError, - e - ); - if (_.isFunction(error)) { - error(); - } - }; - - // websql - if (!tableName) { - OB.warn('OB.Dal.remove: tableName not found'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.remove: tableName not found'; - }); - } - if (modelDefinition.getPrimaryKey) { - pk = modelDefinition.getPrimaryKey() - ? modelDefinition.getPrimaryKey() - : null; - if (pk) { - pkProperty = pk.name; - } - } - if (model.get(pkProperty)) { - if (modelDefinition.getDeleteByIdStatement) { - sql = modelDefinition.getDeleteByIdStatement(); - } else { - sql = - 'DELETE FROM ' + - tableName + - ' WHERE ' + - modelProto.propertyMap[pkProperty] + - ' = ? '; - } - // UPDATE - params.push(model.get(pkProperty)); - } else { - OB.warn( - 'OB.Dal.remove: an object without primary key cannot be deleted' - ); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.remove: an object without primary key cannot be deleted'; - }); - } - - if (currentTransaction) { - currentTransaction.executeSql( - sql, - params, - silentFunction(success), - processError - ); - } else { - OB.Data.localDB.transaction(function(tx) { - tx.executeSql(sql, params, silentFunction(success), processError); - }); - } - } else { - this.missingLocalStorageLogic(); - } - }; - - OB.Dal.removeAllInTransaction = function( - tx, - model, - criteria, - success, - error - ) { - OB.Dal.removeAll(model, criteria, success, error, tx); - }; - - OB.Dal.removeAll = function( - model, - criteria, - success, - error, - currentTransaction - ) { - if (OB.Data.localDB) { - var tableName = OB.Dal.getTableName(model), - propertyMap = OB.Dal.getPropertyMap(model), - sql, - params, - whereClause, - processError; - - processError = function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.removeAll: table', - tableName, - txError, - e - ); - if (_.isFunction(error)) { - error(); - } - }; - - // websql - if (!tableName) { - OB.warn('OB.Dal.removeAll: tableName not found'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.removeAll: tableName not found'; - }); - } - - sql = 'DELETE FROM ' + tableName; - if (criteria && criteria.whereClause) { - whereClause = criteria.whereClause; - sql = sql + whereClause; - } else { - whereClause = OB.Dal.getWhereClause(criteria, propertyMap); - sql = sql + whereClause.sql; - params = _.isEmpty(whereClause.params) ? [] : whereClause.params; - } - - if (currentTransaction) { - currentTransaction.executeSql( - sql, - params, - silentFunction(success), - processError - ); - } else { - OB.Data.localDB.transaction(function(tx) { - tx.executeSql(sql, params, silentFunction(success), processError); - }); - } - } else { - this.missingLocalStorageLogic(); - } - }; - - OB.Dal.removeRemoteModels = function() { - var model; - for (model in OB.Model) { - if ( - OB.Model.hasOwnProperty(model) && - OB.Model[model].prototype && - OB.Model[model].prototype.remote && - OB.Dal.getTableName(OB.Model[model]) && - OB.MobileApp.model.hasPermission(OB.Model[model].prototype.remote, true) - ) { - OB.Dal.removeAll(OB.Model[model]); - } - } - }; - - OB.Dal.getInTransaction = function( - tx, - model, - id, - success, - error, - empty, - local - ) { - OB.Dal.get(model, id, success, error, empty, tx, local); - }; - - OB.Dal.get = function( - model, - id, - success, - error, - empty, - currentTransaction, - local - ) { - OB.UTIL.Debug.execute(function() { - var caller = OB.UTIL.getStackTrace('get', true); - var callerInfo = getCallerInfo(); - if (!id) { - OB.warn( - '[dberror] OB.Dal.get: id not found. - Caller: ' + - caller + - ' - Caller info: ' + - callerInfo - ); - } - }); - if ( - !local && - model.prototype.remote && - OB.MobileApp.model.hasPermission(model.prototype.remote, true) - ) { - var process = new OB.DS.Process(model.prototype.source); - var currentDate = new Date(); - var params = {}; - params.terminalTime = currentDate; - params.terminalTimeOffset = currentDate.getTimezoneOffset(); - var p, i; - var data = {}; + var process = new OB.DS.Process(model.prototype.source); + var currentDate = new Date(); + var params = {}; + params.terminalTime = currentDate; + params.terminalTimeOffset = currentDate.getTimezoneOffset(); + var p, i; + var data = {}; if (params) { p = {}; @@ -1880,633 +502,8 @@ OB.Dal = OB.Dal || {}; } } ); - } else if (OB.Data.localDB) { - var tableName = OB.Dal.getTableName(model), - sql = 'SELECT * FROM ' + tableName + ' WHERE ' + tableName + '_id = ?', - processResult, - processError; - - processResult = function(tr, result) { - const len = result.rows ? result.rows.length : result.length; - if (len === 0) { - if (empty) { - empty(); - } else { - return null; - } - } else { - success( - OB.Dal.transform( - model, - result.rows - ? result.rows.item(0) - : _.isArray(result) - ? result[0] - : result - ) - ); - } - }; - - processError = function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.get: table', - tableName, - txError, - e - ); - if (_.isFunction(error)) { - error(); - } - }; - - if (model.prototype.indexDBModel) { - OB.App.MasterdataController.get(model.prototype.indexDBModel, id) - .then(result => { - processResult(undefined, result); - }) - .catch(error => { - processError(undefined, error.message); - }); - return; - } - - // websql - if (currentTransaction) { - currentTransaction.executeSql(sql, [id], processResult, processError); - } else { - OB.Data.localDB.readTransaction(function(tx) { - tx.executeSql(sql, [id], processResult, processError); - }); - } } else { this.missingLocalStorageLogic(); } }; - - OB.Dal.dropTable = function(model, successCallback, errorCallback) { - if (OB.Data.localDB) { - var sql = model.getDropStatement - ? model.getDropStatement() - : model.prototype.dropStatement; - OB.Data.localDB.transaction(function(tx) { - tx.executeSql( - sql, - [], - function() { - OB.debug('succesfully dropped table: ' + sql); - successCallback(); - }, - errorCallback - ); - }); - } else { - this.missingLocalStorageLogic(); - } - }; - - OB.Dal.initCache = function(model, initialData, success, error, incremental) { - if (OB.Data.localDB) { - // error must be defined, if not it fails in some android versions - error = error || function() {}; - - if ( - !model.propertyList && - (!model.prototype.createStatement || !model.prototype.dropStatement) - ) { - OB.warn('OB.Dal.initCache: model requires a create and drop statement'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.initCache: model requires a create and drop statement'; - }); - } - - if (!initialData) { - OB.warn('OB.Dal.initCache: initialData must be passed as parameter'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.initCache: initialData must be passed as parameter'; - }); - } - - if (!model.prototype.local && !incremental) { - OB.Data.localDB.transaction(function(tx) { - var st = model.getDropStatement - ? model.getDropStatement() - : model.prototype.dropStatement; - tx.executeSql(st, [], null, function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.initCache: table', - model.prototype.modelName, - txError, - e - ); - if (_.isFunction(error)) { - error(); - } - }); - }, error); - } - - OB.Data.localDB.transaction(function(tx) { - var createStatement = model.getCreateStatement - ? model.getCreateStatement() - : model.prototype.createStatement; - - // Issue 30939: Do not allow nulls in the primary key - if (createStatement.indexOf('PRIMARY KEY NOT NULL') === -1) { - createStatement = createStatement.replace( - 'PRIMARY KEY', - 'PRIMARY KEY NOT NULL' - ); - } - OB.UTIL.Debug.execute(function() { - if (createStatement.indexOf('PRIMARY KEY NOT NULL') === -1) { - throw "The create statement must contain a 'PRIMARY KEY NOT NULL' (createStatement: '" + - createStatement + - "'"; - } - }); - - var createIndexStatement; - tx.executeSql( - createStatement, - [], - function() { - //Create Index - if (model.hasIndex && model.hasIndex()) { - _.each(model.getIndexes(), function(indexDefinition) { - createIndexStatement = model.getCreateIndexStatement( - indexDefinition - ); - tx.executeSql(createIndexStatement, [], null, function( - txError, - e - ) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.initCache: index for table', - model.prototype.modelName, - txError, - e - ); - }); - }); - } - - model.areTablesCreated = true; - }, - function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.initCache: table', - model.prototype.modelName, - txError, - e - ); - } - ); - }, error); - - if (_.isArray(initialData)) { - OB.Dal.insertData(model, initialData, success, error, incremental, 0); - } else { - // no initial data - OB.warn('OB.Dal.initCache: initialData must be an Array'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.initCache: initialData must be an Array'; - }); - } - } else { - this.missingLocalStorageLogic(); - } - }; - - /** - * Inserts data into a local table - * - * - */ - OB.Dal.insertData = function( - model, - data, - success, - error, - incremental, - offset - ) { - OB.Data.localDB.transaction( - function(tx) { - var props = model.getProperties - ? model.getProperties() - : model.prototype.properties, - filterVal, - values, - _idx = offset, - updateRecord, - handleError, - insertStatement, - filterProps; - handleError = function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.insertData: model insert', - model.prototype.modelName, - txError, - e - ); - }; - updateRecord = function(tx, model, values, active) { - var deleteStatement; - deleteStatement = model.getDeleteByIdStatement - ? model.getDeleteByIdStatement() - : 'DELETE FROM ' + - model.prototype.tableName + - ' WHERE ' + - model.prototype.propertyMap.id + - '=?'; - tx.executeSql( - deleteStatement, - [values[0]], - function() { - if (_.isUndefined(active) || active) { - var insertSatement; - insertSatement = model.getInsertStatement - ? model.getInsertStatement() - : model.prototype.insertStatement; - tx.executeSql(insertSatement, values, null, function(tx, e) { - handleError(tx, e); - return true; - }); - } - }, - handleError - ); - }; - insertStatement = model.getInsertStatement - ? model.getInsertStatement() - : model.prototype.insertStatement; - filterProps = model.getFilterProperties - ? model.getFilterProperties() - : model.prototype.propertiesFilter; - _.each(data, function(item) { - values = []; - _.each(props, function(prop) { - var value, - propName = typeof prop === 'string' ? prop : prop.name; - if (!propName || '_idx' === propName || '_filter' === propName) { - return; - } - value = item[propName]; - values.push(value === undefined ? null : value); - }); - if ( - (model.hasFilter && model.hasFilter()) || - model.prototype.propertiesFilter - ) { - filterVal = ''; - _.each(filterProps, function(prop) { - filterVal = - OB.UTIL.unAccent(filterVal) + - (item[prop] ? item[prop] + '###' : ''); - }); - values.push(filterVal); - } - values.push(_idx); - if (incremental) { - updateRecord(tx, model, values, item.active); - } else if ( - OB.UTIL.isNullOrUndefined(item.active) || - (item.active && item.active === true) - ) { - tx.executeSql(insertStatement, values, null, function(tx, e) { - handleError(tx, e); - return true; - }); - } - _idx++; - }); - }, - error, - function() { - if (data.length > 0) { - OB.Cache.resetCacheForModel(model.prototype.modelName); - } - if (_.isFunction(success)) { - success(); - } - } - ); - }; - - /** - * Loads a set of models - * - * - */ - OB.Dal.loadModels = function( - online, - models, - data, - incremental, - callback, - background - ) { - var timestamp = 0; - var key; - - var modelsInLocalDb = []; - - function dalLoadModelsCallback() { - if (callback instanceof Function) { - callback(); - } - } - - function forceLocalDatabaseLoad(models, idx, callback) { - if (idx === models.length) { - if (callback) { - callback(); - } - return; - } - - OB.Dal.find( - models[idx], - {}, - function() { - forceLocalDatabaseLoad(models, idx + 1, callback); - }, - function() { - forceLocalDatabaseLoad(models, idx + 1, callback); - } - ); - } - - function triggerReady(models) { - if ( - incremental && - models._LoadQueue && - OB.UTIL.queueStatus(models._LoadQueue) && - OB.MobileApp.model.get('modelsToLoad').length === 0 - ) { - dalLoadModelsCallback(); - return; - } - if ( - OB.MobileApp.model.get('modelsToLoad').length === 0 && - OB.UTIL.queueStatus(models._LoadQueue || {}) - ) { - // this is only triggered when all models (online and offline) are loaded. - // offline models are loaded first but don't trigger this, it is not till - // windowModel is going to be rendered when online models are loaded and this - // is triggered. - if (!OB.MobileApp.model.get('datasourceLoadFailed')) { - forceLocalDatabaseLoad(modelsInLocalDb, 0, function() { - dalLoadModelsCallback(); - }); - } else { - dalLoadModelsCallback(); - } - } else { - dalLoadModelsCallback(); - } - } - - function buildLoadQueue() { - models._LoadQueue = models._LoadQueue || {}; - _.each(models, function(item) { - if (item && item.generatedModel) { - item = OB.Model[item.modelName]; - } - if ( - item && - ((online && item.prototype.online) || - (!online && !item.prototype.online)) && - !item.prototype.local && - (!item.prototype.remote || - (item.prototype.remote && - !OB.MobileApp.model.hasPermission(item.prototype.remote, true))) - ) { - models._LoadQueue[item.prototype.modelName] = false; - } - }); - } - - function processModelAtIndex(index) { - var ds, - load, - item = models[index]; - var removeLoadedModelsFromArray = function(modelName) { - var position = OB.MobileApp.model - .get('modelsToLoad') - .indexOf(modelName); - //var modelsList = ; - if (position !== -1) { - OB.MobileApp.model.get('modelsToLoad').splice(position, 1); - } - }; - - if (index === models.length) { - triggerReady(models); - return; - } - - if (item && item.generatedModel) { - item = OB.Model[item.modelName]; - } - load = - item && - ((online && item.prototype.online) || - (!online && !item.prototype.online)) && - (!item.prototype.remote || - (item.prototype.remote && - !OB.MobileApp.model.hasPermission(item.prototype.remote, true))); - //TODO: check permissions - if (load) { - models._failedModels = models._failedModels || []; - models._LoadQueue = models._LoadQueue || {}; - if (item.prototype.local) { - OB.Dal.initCache( - item, - [], - function() { - // OB.info('init success: ' + item.prototype.modelName); - processModelAtIndex(index + 1); - }, - function() { - OB.error('init error', arguments); - processModelAtIndex(index + 1); - } - ); - } else { - // OB.info('[sdrefresh] load model ' + item.prototype.modelName + ' ' + (incremental ? 'incrementally' : 'full')); - if ( - incremental && - OB.UTIL.localStorage.getItem( - 'lastUpdatedTimestamp' + item.prototype.modelName - ) - ) { - timestamp = OB.UTIL.localStorage.getItem( - 'lastUpdatedTimestamp' + item.prototype.modelName - ); - } - if (!item.prototype.online) { - modelsInLocalDb.push(item); - } - OB.UTIL.localStorage.removeItem( - 'recordsFromBackendFor' + item.prototype.modelName - ); - ds = new OB.DS.DataSource(new OB.DS.Request(item, timestamp)); - ds.on('ready', function(status) { - var finishTransaction = function() { - models._LoadQueue[item.prototype.modelName] = true; - if (item && item.prototype) { - removeLoadedModelsFromArray(item.prototype.modelName); - } - if (models._failedModels.length > 0) { - OB.MobileApp.model.set('datasourceLoadFailed', { - silent: true - }); - } - processModelAtIndex(index + 1); - }; - if (status === 'failed' || status === 'timeout') { - models._failedModels.push(item.prototype.modelName); - if (!incremental) { - finishTransaction(); - } - } else { - var logMsgForTransaction = function( - isSuccess, - modelName, - totalRecords - ) { - OB.debug( - isSuccess - ? '[sdreresh-' + - (incremental ? 'inc' : 'full') + - '] The model ' + - modelName + - ' has in local db ' + - totalRecords + - ' records' - : '[sdreresh-' + - (incremental ? 'inc' : 'full') + - '] There model ' + - modelName + - ' has an error getting the number of records from local db' - ); - if (data && online) { - data[modelName] = new Backbone.Collection(ds.cache); - } - }; - var checkRecordsWithBackend = function(modelName, totalRecords) { - // If the number of records in websql is not equal to the number of recrods sent by the server, an error is raised - // This shloud only be done during a full refresh - if (!incremental) { - if ( - totalRecords !== - parseInt( - OB.UTIL.localStorage.getItem( - 'recordsFromBackendFor' + modelName - ), - 10 - ) - ) { - models._failedModels.push(modelName); - } - } - }; - if (incremental) { - finishTransaction(); - } else { - OB.Data.localDB.transaction( - function(tx) { - tx.executeSql( - 'select count(1) as totalRecords from ' + - item.prototype.tableName, - [], - function(tx, result) { - logMsgForTransaction( - true, - item.prototype.modelName, - result.rows.item(0).totalRecords - ); - checkRecordsWithBackend( - item.prototype.modelName, - result.rows.item(0).totalRecords - ); - }, - function() { - logMsgForTransaction(false, item.prototype.modelName); - } - ); - }, - function(errorMsg) { - OB.error(errorMsg); - finishTransaction(); - }, - function() { - finishTransaction(); - } - ); - } - } - - // Skip load of models if it's a incremental refresh and the request timeout has been reached - if (incremental && (status === 'timeout' || status === 'failed')) { - dalLoadModelsCallback(); - return; - } - }); - - if (item.prototype.includeTerminalDate) { - var currentDate = new Date(); - item.params = item.params || {}; - item.params.terminalTime = currentDate; - item.params.terminalTimeOffset = currentDate.getTimezoneOffset(); - } - ds.load(item.params, incremental, background); - } - } else if ( - item && - item.prototype.remote && - OB.MobileApp.model.hasPermission(item.prototype.remote, true) - ) { - if (models._LoadQueue) { - models._LoadQueue[item.prototype.modelName] = true; - } - if (item && item.prototype) { - removeLoadedModelsFromArray(item.prototype.modelName); - } - processModelAtIndex(index + 1); - } else { - if (item && item.prototype) { - removeLoadedModelsFromArray(item.prototype.modelName); - } - processModelAtIndex(index + 1); - } - } - - models._LoadOnline = online; - - buildLoadQueue(); - - if (models.length === 0) { - triggerReady(models); - return; - } - - // Create an array of models to load to know when all the models are loaded - for (key in models._LoadQueue) { - if (models._LoadQueue.hasOwnProperty(key)) { - if (OB.MobileApp.model.get('modelsToLoad').indexOf(key) === -1) { - OB.MobileApp.model.get('modelsToLoad').push(key); - } - } - } - - processModelAtIndex(0); - }; })(); diff --git a/web/org.openbravo.mobile.core/source/data/ob-datasource.js b/web/org.openbravo.mobile.core/source/data/ob-datasource.js index 24713dc8..6cf060b7 100644 --- a/web/org.openbravo.mobile.core/source/data/ob-datasource.js +++ b/web/org.openbravo.mobile.core/source/data/ob-datasource.js @@ -1,13 +1,13 @@ /* ************************************************************************************ - * Copyright (C) 2012-2020 Openbravo S.L.U. + * Copyright (C) 2012-2023 Openbravo S.L.U. * Licensed under the Openbravo Commercial License version 1.0 * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html * or in the legal folder of this module distribution. ************************************************************************************ */ -/*global OB, Backbone, _, enyo, $ */ +/*global OB, Backbone, _, enyo */ (function() { OB.DS = window.OB.DS || {}; @@ -574,566 +574,4 @@ ); } }; - - function check(elem, filter) { - var p; - - for (p in filter) { - if (filter.hasOwnProperty(p)) { - if (typeof filter[p] === 'object') { - return check(elem[p], filter[p]); - } else { - if (filter[p].substring(0, 2) === '%i') { - if (!new RegExp(filter[p].substring(2), 'i').test(elem[p])) { - return false; - } - } else if (filter[p].substring(0, 2) === '%') { - if (!new RegExp(filter[p].substring(2)).test(elem[p])) { - return false; - } - } else if (filter[p] !== elem[p]) { - return false; - } - } - } - } - return true; - } - - function findInData(data, filter) { - var i, max; - - if ($.isEmptyObject(filter)) { - return { - exception: 'filter not defined' - }; - } else { - for (i = 0, max = data.length; i < max; i++) { - if (check(data[i], filter)) { - return data[i]; - } - } - return null; - } - } - - function execInData(data, filter, filterfunction) { - var newdata, info, i, max, f, item; - - if ($.isEmptyObject(filter) && !filterfunction) { - return { - data: data.slice(0, OB.DS.MAXSIZE), - info: data.length > OB.DS.MAXSIZE ? 'OBMOBC_DataMaxReached' : null - }; - } else { - f = - filterfunction || - function(item) { - return item; - }; - newdata = []; - info = null; - for (i = 0, max = data.length; i < max; i++) { - if (check(data[i], filter)) { - item = f(data[i]); - if (item) { - if (newdata.length >= OB.DS.MAXSIZE) { - info = 'OBMOBC_DataMaxReached'; - break; - } - newdata.push(data[i]); - } - } - } - return { - data: newdata, - info: info - }; - } - } - - // DataSource objects - // OFFLINE GOES HERE - OB.DS.DataSource = function(request) { - this.request = request; - this.cache = null; - }; - _.extend(OB.DS.DataSource.prototype, Backbone.Events); - - OB.DS.DataSource.prototype.load = function(params, incremental, background) { - this.modelPagination = 1; - var me = this, - handleError, - handleIncrementalRequest, - dataLoaded = 0; - OB.UTIL.localStorage.setItem( - 'recordsFromBackendFor' + me.request.model.prototype.modelName, - 0 - ); - handleError = function() { - var msg = arguments[0] ? arguments[0].message : arguments; - OB.error( - 'Error in table ' + - me.request.model.prototype.modelName + - ' during initCache or insertData: ' + - msg - ); - - me.trigger('ready', 'failed'); - }; - - const doModelRequest = function(params, functionSave, errorCallback) { - var offset = params._offset; - var limit = params._limit; - if (offset === 0) { - OB.UTIL.localStorage.setItem( - 'requestTimestamp' + me.request.model.prototype.modelName, - new Date().getTime() - ); - OB.UTIL.showLoadingMessage( - OB.I18N.getLabel('OBMOBC_LoadingMessageModel', [ - me.request.model.prototype.modelName - ]) - ); - } else { - OB.UTIL.showLoadingMessage( - OB.I18N.getLabel('OBMOBC_LoadingMessageModelPage', [ - me.request.model.prototype.modelName, - offset / limit + 1 - ]) - ); - } - delete params._data; - delete params._model; - delete params._lastUpdated; - delete params._totalRows; - me.request.exec( - params, - function(data, message, lastUpdated, totalRows) { - var newLastId; - - function updateParamsForBackgroundRequestLogs(dataLoaded) { - let alreadyProccesedRecords = Number( - OB.UTIL.localStorage.getItem('totalRecordsBackgroundRequest') - ); - OB.UTIL.localStorage.setItem( - 'totalRecordsBackgroundRequest', - Number(alreadyProccesedRecords) + Number(dataLoaded) - ); - - let startingRequestModel = OB.UTIL.localStorage.getItem( - 'requestTimestamp' + me.request.model.prototype.modelName - ); - let executionTimeBackgroundRequest = - Number(new Date().getTime()) - Number(startingRequestModel); - let alreadyProccessTime = Number( - OB.UTIL.localStorage.getItem('totalTimeBackgroundRequest') - ); - let totalRequestTime = - Number(alreadyProccessTime) + - Number(executionTimeBackgroundRequest); - OB.UTIL.localStorage.setItem( - 'totalTimeBackgroundRequest', - totalRequestTime - ); - } - - function success() { - dataLoaded += data.length; - if (data.length >= limit) { - OB.debug( - '[sdreresh-' + - (incremental ? 'inc' : 'full') + - '] The model ' + - me.request.model.prototype.modelName + - ' has loaded from ' + - offset + - ' to ' + - (offset + limit + 1) + - ' with a ' + - data.length + - ' records in the pagination ' + - me.modelPagination - ); - me.modelPagination = me.modelPagination + 1; - newLastId = null; - if (me.request.model.prototype.paginationById) { - newLastId = - data[data.length - 1][me.request.model.getPrimaryKey().name]; - } - //remove the lastUpdated timestamp while the paged request is being processed to prevent half loaded models - OB.UTIL.localStorage.removeItem( - 'lastUpdatedTimestamp' + me.request.model.prototype.modelName - ); - OB.UTIL.localStorage.setItem( - 'recordsFromBackendFor' + me.request.model.prototype.modelName, - totalRows - ); - handleIncrementalRequest( - limit, - offset + limit, - params, - incremental, - newLastId, - background - ); - } else { - OB.UTIL.completeLoadingStep(); - OB.debug( - '[sdreresh-' + - (incremental ? 'inc' : 'full') + - '] The model ' + - me.request.model.prototype.modelName + - ' has loaded from ' + - offset + - ' to ' + - (offset + limit + 1) + - ' with a ' + - data.length + - ' records in the pagination ' + - me.modelPagination - ); - if (dataLoaded > 0) { - OB.info( - '[sdreresh-' + - (incremental ? 'inc' : 'full') + - '] The model ' + - me.request.model.prototype.modelName + - ' has finished loading with a total of ' + - dataLoaded + - ' records. ' + - (me.modelPagination === 1 - ? 'There was no pagination.' - : 'The number of paginations created were ' + - me.modelPagination) - ); - updateParamsForBackgroundRequestLogs(dataLoaded); - } - - if (background === undefined) { - OB.App.MasterdataController.updateModelLastUpdatedTimestamp( - me.request.model.prototype.modelName, - lastUpdated, - data, - totalRows - ); - } - - me.trigger('ready'); - } - } - - if (data.exception) { - OB.error('Error in datasource: ' + data.exception); - OB.DS.masterdataBackgroundModels = {}; - me.trigger('ready', 'failed'); - return; - } - if (me.request.model && me.request.model.prototype.online) { - me.cache = me.cache ? me.cache.concat(data) : data; - } - - params._data = data; - params._model = me.request.model; - params._lastUpdated = lastUpdated; - params._totalRows = totalRows; - functionSave(params, success, errorCallback); - }, - function(data) { - OB.UTIL.Debug.execute(function() { - if (data && data.exception && data.exception.message) { - OB.error( - 'OB.DS.DataSource.prototype.exec: ' + data.exception.message - ); - return; - } - }); - OB.DS.masterdataBackgroundModels = {}; - - OB.info( - OB.I18N.getLabel('OBMOBC_MasterdataRequestError') + - '. URL which failed: ' + - me.request.source - ); - OB.UTIL.showI18NWarning('OBMOBC_MasterdataRequestError'); - if ( - data && - data.exception && - data.exception.message && - data.exception.message === 'Application server is not available.' - ) { - me.trigger('ready', 'timeout'); - } else { - me.trigger('ready', 'failed'); - } - }, - true, - incremental - ? OB.RR.RequestRouter.getServiceByName( - me.request.source - ).getServiceTimeout(5000) - : OB.RR.RequestRouter.getServiceByName( - me.request.source - ).getServiceTimeout(5000) * 20 - ); - }; - - const updateParamsForBackgroundSaveLogs = function(modelName, dataLoaded) { - let alreadySavedRecords = OB.UTIL.localStorage.getItem( - 'totalRecordsBackgroundSave' - ); - let totalSavedRecords = Number(alreadySavedRecords) + Number(dataLoaded); - OB.UTIL.localStorage.setItem( - 'totalRecordsBackgroundSave', - totalSavedRecords - ); - - let alreadySaveTime = OB.UTIL.localStorage.getItem( - 'totalTimeBackgroundSave' - ); - let startingSaveModel = OB.UTIL.localStorage.getItem( - 'startSavingTimestamp' + modelName - ); - let executionTimeBackgroundSave = - Number(new Date().getTime()) - Number(startingSaveModel); - let totalSaveTime = - Number(alreadySaveTime) + Number(executionTimeBackgroundSave); - OB.UTIL.localStorage.setItem('totalTimeBackgroundSave', totalSaveTime); - }; - - const doModelDataSave = function(params, success, handleError) { - const offset = params._offset; - const data = params._data; - const model = params._model; - if (model && !model.prototype.online) { - OB.UTIL.localStorage.setItem( - 'startSavingTimestamp' + model.prototype.modelName, - new Date().getTime() - ); - if (offset === 0) { - OB.Dal.initCache( - model, - data, - function() { - updateParamsForBackgroundSaveLogs( - model.prototype.modelName, - data.length - ); - success(); - }, - handleError, - incremental - ); - } else { - OB.Dal.insertData( - model, - data, - function() { - updateParamsForBackgroundSaveLogs( - model.prototype.modelName, - data.length - ); - success(); - }, - handleError, - incremental, - dataLoaded - ); - } - } else { - success(); - } - }; - - const doModelDataSaveInRAM = function(params, success, handleError) { - const data = params._data; - const limit = params._limit; - const currentLength = data.length; - const backgroundLimit = OB.MobileApp.model.hasPermission( - 'OBMOBC_BackgroundMasterdataMaxSize', - true - ) - ? OB.MobileApp.model.hasPermission( - 'OBMOBC_BackgroundMasterdataMaxSize', - true - ) - : limit; - if ( - OB.DS.masterdataBackgroundModels['totalLength'] + currentLength > - backgroundLimit - ) { - OB.info( - 'Failed to do masterdata refresh in background because exceeds the limit of data. Trying normal refresh.' - ); - OB.UTIL.localStorage.setItem('neededForeGroundMasterDataRefresh'); - OB.UTIL.refreshMasterDataForeground(); - OB.DS.masterdataBackgroundModels = {}; - return; - } - if (!OB.DS.masterdataBackgroundModels.hasOwnProperty(me.request.source)) { - OB.DS.masterdataBackgroundModels[me.request.source] = {}; - OB.DS.masterdataBackgroundModels[me.request.source]['data'] = []; - } - - OB.DS.masterdataBackgroundModels[me.request.source]['data'] = [ - ...OB.DS.masterdataBackgroundModels[me.request.source]['data'], - ...params._data - ]; - - OB.DS.masterdataBackgroundModels[me.request.source]['model'] = - params._model; - OB.DS.masterdataBackgroundModels[me.request.source]['lastUpdated'] = - params._lastUpdated; - OB.DS.masterdataBackgroundModels[me.request.source]['totalRows'] = - params._totalRows; - - OB.DS.masterdataBackgroundModels[me.request.source]['lastUpdated'] = - me.request.lastUpdated; - - if (!OB.DS.masterdataBackgroundModels.hasOwnProperty('totalLength')) { - OB.DS.masterdataBackgroundModels['totalLength'] = 0; - } - OB.DS.masterdataBackgroundModels['totalLength'] += currentLength; - success(); - }; - - const doModelReadFromRAM = function(params, functionSave, errorCallback) { - if ( - OB.DS.masterdataBackgroundModels[me.request.source]['data'].length === 0 - ) { - me.trigger('ready'); - return; - } - let parameters = {}; - parameters._data = - OB.DS.masterdataBackgroundModels[me.request.source]['data']; - parameters._model = - OB.DS.masterdataBackgroundModels[me.request.source]['model']; - const lastUpdated_ = - OB.DS.masterdataBackgroundModels[me.request.source]['lastUpdated']; - const totalRows = - OB.DS.masterdataBackgroundModels[me.request.source]['totalRows']; - parameters._offset = 0; // in background all the pages are concatenated into one - - const success = function() { - OB.info( - '[sdreresh-' + - (incremental ? 'inc' : 'full') + - '] The model ' + - me.request.model.prototype.modelName + - ' has finished saving in db with a total of ' + - parameters._data.length + - ' records. ' - ); - - OB.App.MasterdataController.updateModelLastUpdatedTimestamp( - me.request.model.prototype.modelName, - lastUpdated_, - parameters._data, - totalRows - ); - me.trigger('ready'); - }; - functionSave(parameters, success, errorCallback); - }; - - handleIncrementalRequest = function( - limit, - offset, - params, - incremental, - lastId, - background - ) { - params = params || {}; - params._limit = limit; - params._offset = offset; - params._count = OB.UTIL.localStorage.getItem( - 'recordsFromBackendFor' + me.request.model.prototype.modelName - ) - ? parseInt( - OB.UTIL.localStorage.getItem( - 'recordsFromBackendFor' + me.request.model.prototype.modelName - ), - 10 - ) - : 0; - params._isMasterdata = true; - params.overrideDefaultTimeout = true; - params.lastId = lastId; - params.incremental = incremental; - - if (background === undefined) { - // foreground - doModelRequest( - params, - function(params, successCallback, errorCallback) { - doModelDataSave(params, successCallback, errorCallback); - }, - handleError - ); - } else if (background === 'background-request') { - doModelRequest( - params, - function(params, successCallback, errorCallback) { - doModelDataSaveInRAM(params, successCallback, errorCallback); - }, - handleError - ); - } else if (background === 'background-save') { - doModelReadFromRAM( - params, - function(params, successCallback, errorCallback) { - doModelDataSave(params, successCallback, errorCallback); - }, - handleError - ); - } - }; - - this.cache = null; - var lastId = null; // First request don't have lastId - handleIncrementalRequest( - OB.MobileApp.model.hasPermission('OBMOBC_MasterdataBatchSize', true) - ? OB.DEC.abs( - OB.MobileApp.model.hasPermission('OBMOBC_MasterdataBatchSize', true) - ) - : 10000, - 0, - params, - incremental, - lastId, - background - ); - }; - - OB.DS.DataSource.prototype.find = function(filter, callback) { - if (this.cache) { - callback(findInData(this.cache, filter)); - } else { - this.on( - 'ready', - function() { - callback(findInData(this.cache, filter)); - }, - this - ); - } - }; - - OB.DS.DataSource.prototype.exec = function(filter, callback) { - if (this.cache) { - var result1 = execInData(this.cache, filter); - callback(result1.data, result1.info); - } else { - this.on( - 'ready', - function() { - var result2 = execInData(this.cache, filter); - callback(result2.data, result2.info); - }, - this - ); - } - }; })(); diff --git a/web/org.openbravo.mobile.core/source/data/ob-requestrouter.js b/web/org.openbravo.mobile.core/source/data/ob-requestrouter.js index 1d793f27..07e2dc60 100644 --- a/web/org.openbravo.mobile.core/source/data/ob-requestrouter.js +++ b/web/org.openbravo.mobile.core/source/data/ob-requestrouter.js @@ -1,6 +1,6 @@ /* ************************************************************************************ - * Copyright (C) 2015-2020 Openbravo S.L.U. + * Copyright (C) 2015-2023 Openbravo S.L.U. * Licensed under the Openbravo Commercial License version 1.0 * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html * or in the legal folder of this module distribution. @@ -345,50 +345,41 @@ data: updatedMessageData, success: function(inSender, inResponse) { var callback = function() { - // message was successfull, remove it - OB.Dal.remove( - message, - function() { - OB.UTIL.ProcessController.finish( - 'messageSynchronization', - execution - ); + OB.UTIL.ProcessController.finish( + 'messageSynchronization', + execution + ); - // if the context has changed, lock the terminal - if ( - inResponse.response && - inResponse.response.contextInfo && - OB.MobileApp.model.get('context') - ) { - OB.UTIL.checkContextChange( - OB.MobileApp.model.get('context'), - inResponse.response.contextInfo, - function() { - if ( - pendingMessages.length === 0 && - OB.UTIL.sourceVersionFromResponse - ) { - OB.UTIL.checkSourceVersion( - OB.UTIL.sourceVersionFromResponse, - false, - true - ); - } - } - ); - } - //if the message model is a Polling model(has polling url) add it to the list - if (OB.PollingUtils.getPollingUrl(message)) { - OB.Polling.PollingRequestHandler.addPollingRequest(message); + // if the context has changed, lock the terminal + if ( + inResponse.response && + inResponse.response.contextInfo && + OB.MobileApp.model.get('context') + ) { + OB.UTIL.checkContextChange( + OB.MobileApp.model.get('context'), + inResponse.response.contextInfo, + function() { + if ( + pendingMessages.length === 0 && + OB.UTIL.sourceVersionFromResponse + ) { + OB.UTIL.checkSourceVersion( + OB.UTIL.sourceVersionFromResponse, + false, + true + ); + } } + ); + } + //if the message model is a Polling model(has polling url) add it to the list + if (OB.PollingUtils.getPollingUrl(message)) { + OB.Polling.PollingRequestHandler.addPollingRequest(message); + } - // process the remaining messages - me.processMessages(pendingMessages, fcallback, errorCallback); - }, - function(error) { - OB.error(arguments); - } - ); + // process the remaining messages + me.processMessages(pendingMessages, fcallback, errorCallback); }; if ( @@ -442,33 +433,20 @@ } }, fail: function(inSender, inResponse) { - // save the message in error status - message.set('status', 'failure'); - OB.Dal.save( - message, - function() { - OB.UTIL.ProcessController.finish( - 'messageSynchronization', - execution - ); - me.updateSyncIcon(); + OB.UTIL.ProcessController.finish('messageSynchronization', execution); + me.updateSyncIcon(); - // in multi server online/offline notification is based on presence of messages to sync - if ( - OB.MobileApp.model.get('connectedToERP') && - OB.RR.RequestRouter.isMultiServer() - ) { - OB.MobileApp.model.triggerOffLine(); - } + // in multi server online/offline notification is based on presence of messages to sync + if ( + OB.MobileApp.model.get('connectedToERP') && + OB.RR.RequestRouter.isMultiServer() + ) { + OB.MobileApp.model.triggerOffLine(); + } - if (errorCallback) { - errorCallback(); - } - }, - function() { - OB.error(arguments); - } - ); + if (errorCallback) { + errorCallback(); + } } }; }, diff --git a/web/org.openbravo.mobile.core/source/data/ob-windowmodel.js b/web/org.openbravo.mobile.core/source/data/ob-windowmodel.js index 29348d77..87e767ba 100644 --- a/web/org.openbravo.mobile.core/source/data/ob-windowmodel.js +++ b/web/org.openbravo.mobile.core/source/data/ob-windowmodel.js @@ -1,6 +1,6 @@ /* ************************************************************************************ - * Copyright (C) 2012-2020 Openbravo S.L.U. + * Copyright (C) 2012-2023 Openbravo S.L.U. * Licensed under the Openbravo Commercial License version 1.0 * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html * or in the legal folder of this module distribution. @@ -62,13 +62,7 @@ OB.Model.WindowModel = Backbone.Model.extend({ }); } - if (!OB.MobileApp.model.get('loggedOffline')) { - OB.Dal.loadModels(true, me.models, me.data, undefined, function() { - loadTheWindow(); - }); - } else { - loadTheWindow(); - } + loadTheWindow(); }, load: function() { @@ -86,21 +80,11 @@ OB.Model.WindowModel = Backbone.Model.extend({ _.extend(this.models, Backbone.Events); - if (!OB.MobileApp.model.get('loggedOffline')) { - OB.Dal.loadModels(true, me.models, me.data, undefined, function() { - initIfInit(); - me.trigger('windowReady'); - OB.MobileApp.view.currentWindowState = 'renderUI'; - OB.MobileApp.model.set('currentWindowState', 'renderUI'); - OB.MobileApp.model.set('isLoggingIn', false); - }); - } else { - initIfInit(); - this.trigger('windowReady'); - OB.MobileApp.view.currentWindowState = 'renderUI'; - OB.MobileApp.model.set('currentWindowState', 'renderUI'); - OB.MobileApp.model.set('isLoggingIn', false); - } + initIfInit(); + this.trigger('windowReady'); + OB.MobileApp.view.currentWindowState = 'renderUI'; + OB.MobileApp.model.set('currentWindowState', 'renderUI'); + OB.MobileApp.model.set('isLoggingIn', false); }, setAllOff: function(model) { diff --git a/web/org.openbravo.mobile.core/source/main.js b/web/org.openbravo.mobile.core/source/main.js index 4a358719..242509c5 100644 --- a/web/org.openbravo.mobile.core/source/main.js +++ b/web/org.openbravo.mobile.core/source/main.js @@ -48,9 +48,9 @@ /** * Global versions for mobile.core */ - // Add WebSQL database version for mobile.core + // Add database version for mobile.core OB.UTIL.VersionManagement.current.mobileCore = { - WebSQLDatabase: { + database: { name: 'OBMOBCDB', size: 50 * 1024 * 1024, displayName: 'Mobile DB' diff --git a/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js b/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js index 1ecb4fe6..e0b95bff 100644 --- a/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js +++ b/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js @@ -1,6 +1,6 @@ /* ************************************************************************************ - * Copyright (C) 2012-2021 Openbravo S.L.U. + * Copyright (C) 2012-2023 Openbravo S.L.U. * Licensed under the Openbravo Commercial License version 1.0 * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html * or in the legal folder of this module distribution. @@ -111,10 +111,10 @@ OB.Model.Terminal = Backbone.Model.extend({ } }, localDB: { - size: OB.UTIL.VersionManagement.current.mobileCore.WebSQLDatabase.size, - name: OB.UTIL.VersionManagement.current.mobileCore.WebSQLDatabase.name, + size: OB.UTIL.VersionManagement.current.mobileCore.database.size, + name: OB.UTIL.VersionManagement.current.mobileCore.database.name, displayName: - OB.UTIL.VersionManagement.current.mobileCore.WebSQLDatabase.displayName + OB.UTIL.VersionManagement.current.mobileCore.database.displayName }, shouldExecuteBenchmark: false, propertiesLoaders: [], @@ -635,155 +635,22 @@ OB.Model.Terminal = Backbone.Model.extend({ }, openLocalDB: async function() { - if (OB.Data.localDB) { - OB.Data.localDB.transaction( - function() {}, - function() { - OB.Dal.openWebSQL(); - }, - null - ); - } else { - OB.Dal.openWebSQL(); - } - await OB.App.MasterdataController.openDatabase(); await OB.App.MessageModelController.openDatabase(); await OB.App.OfflineSessionController.openDatabase(); }, - initLocalDB: function() { - function dropTable(modelObj) { - return new Promise(function(resolve, reject) { - function dropTableFunction(modelObj) { - OB.Dal.dropTable( - modelObj, - function() { - var modelName = modelObj.prototype.modelName; - var modelChecksum = OB.Data.getModelStructureChecksum(modelObj); - //If this table belongs to a masterdata model, the masterdata needs to be fully loaded - if ( - OB.UTIL.localStorage.getItem('lastUpdatedTimestamp' + modelName) - ) { - OB.UTIL.localStorage.removeItem( - 'lastUpdatedTimestamp' + modelName - ); - OB.UTIL.localStorage.removeItem('POSLastTotalRefresh'); - OB.UTIL.localStorage.removeItem('POSLastIncRefresh'); - } - OB.Dal.initCache( - modelObj, - [], - function() { - //Set checksum after the model has been created to prevent inconsistent states (e.g. checksum set but missing model) - OB.debug( - 'Set model ' + modelName + ' checksum to ' + modelChecksum - ); - OB.UTIL.localStorage.setItem( - 'structureChecksum-' + modelName, - modelChecksum - ); - resolve(); - }, - function() { - OB.error("Couldn't initialize table for model: " + modelName); - resolve(); - } - ); - }, - function() { - OB.error(OB.UTIL.argumentsToStringifyed('dropTable', arguments)); - reject(); - } - ); - } - - var syncModel = OB.MobileApp.model.getSyncModel(modelObj); - if (syncModel) { - OB.MobileApp.model.syncModelHasData( - syncModel, - function() { - //Sync model has data. We will try to synchronize, and if we fail then the databaseCannotBeReset action will be executed - OB.MobileApp.model.syncAllModels(function() { - dropTableFunction(modelObj); - }, OB.MobileApp.model.databaseCannotBeResetAction); - }, - function() { - dropTableFunction(modelObj); - } - ); - } else { - dropTableFunction(modelObj); - } - }); - } - - function checkChangedInModels() { - var tablesToDrop = []; - _.each(OB.Model, function(model) { - if ( - !model.prototype || - !model.prototype.modelName || - model.prototype.legacyModel - ) { - return; - } - var modelName = model.prototype.modelName; - var modelChecksum = OB.Data.getModelStructureChecksum(model); - if (modelChecksum === '') { - return; - } - if ( - OB.UTIL.localStorage.getItem('structureChecksum-' + modelName) !== - modelChecksum - ) { - if (!OB.UTIL.localStorage.getItem('structureChecksum-' + modelName)) { - OB.debug( - "Model '" + - modelName + - "' should not exists because there isn't a paired entry in the localStorage. Performning preemptive table dropping..." - ); - } else { - OB.info("Model '" + modelName + "' changed. Rebuilding..."); - } - - tablesToDrop.push(dropTable(model)); - OB.MobileApp.model.get('modelsRebuilded').push(model); - } - }); - - OB.info('Checking database models...'); - - if (tablesToDrop.length === 0) { - OB.info('No models changed.'); - OB.MobileApp.model.loadTerminalInfo(); - return; - } - - Promise.all(tablesToDrop).then( - function() { - OB.MobileApp.model.loadTerminalInfo(); - }, - function() { - OB.MobileApp.model.loadingErrorsActions('initLocalDB.dropTalbles'); - } - ); - } + initLocalDB: async function() { + const finalCallback = () => { + OB.MobileApp.model.loadTerminalInfo(); + return; + }; // check if terminal id has changed if ( OB.UTIL.localStorage.getItem('loggedTerminalName') && OB.UTIL.localStorage.getItem('loggedTerminalName') !== OB.MobileApp.model.get('terminalName') ) { - OB.warn( - OB.UTIL.argumentsToStringifyed( - 'terminal changed (' + - OB.UTIL.localStorage.getItem('loggedTerminalName') + - ' -> ' + - OB.MobileApp.model.get('terminalName') + - ')' - ) - ); OB.info( 'Terminal has been changed. Resetting database and local storage information.' ); @@ -793,12 +660,24 @@ OB.Model.Terminal = Backbone.Model.extend({ OB.MobileApp.model.get('terminalName') ); OB.MobileApp.model.logout(); - return; }); - } else { - OB.MobileApp.model.set('modelsRebuilded', []); - checkChangedInModels(); + return; } + await OB.App.MasterdataController.openDatabase({ + checkModelChanges: + OB.MobileApp.model && OB.MobileApp.model.get('isLoggingIn'), + statusCallback: message => { + if (message.deleteDatabase) { + OB.UTIL.showLoadingMessage( + OB.I18N.getLabel('OBMOBC_DeleteLocalDatabase') + ); + } else if (message.openDatabase) { + finalCallback(); + } else { + finalCallback(); + } + } + }); }, /** @@ -1323,329 +1202,6 @@ OB.Model.Terminal = Backbone.Model.extend({ } return; } - - var modelObj = me.syncModelQueue.shift(); - var model = modelObj.model; - var criteria; - if (modelObj.getCriteria) { - criteria = modelObj.getCriteria(); - } else if (modelObj.criteria) { - criteria = modelObj.criteria; - } else { - criteria = { - hasBeenProcessed: 'Y' - }; - } - criteria._limit = -1; - OB.Dal.find( - model, - criteria, - function(dataToSync) { - me.skipSyncModel = dataToSync.length === 0; - - if (modelObj.preSendModel) { - // preSendModel is like a hook which can be used by custom code - // to influence the logic, for example setting me.skipSyncModel - modelObj.preSendModel(me, dataToSync); - } - - if (me.skipSyncModel) { - me.skipSyncModel = false; - me.syncModel(); - return; - } - - var className = modelObj.className; - - if (model === OB.Model.Order && OB.UTIL.processOrderClass) { - className = OB.UTIL.processOrderClass; - } - - var mdl, - modelIndex = 0, - modelNotFullySynced = false, - dataCorruption = false, - newDataToSync = new Backbone.Collection(); - while (modelIndex < dataToSync.length) { - mdl = dataToSync.at(modelIndex); - if ( - !_.isUndefined(mdl.get('json')) && - (_.isEmpty(mdl.get('json')) || _.isNull(mdl.get('json'))) - ) { - OB.error( - '[syncModel] Wrong model to Synchronize in backend: ' + - mdl.modelName + - ' because json column is undefined.' - ); - dataCorruption = true; - } else { - newDataToSync.add(dataToSync.at(modelIndex)); - } - - modelIndex++; - // partition the data in chunks - if (modelIndex >= 100 && modelIndex < dataToSync.length) { - modelNotFullySynced = true; - // add the model again to the beginning of the queue - me.syncModelQueue.unshift(modelObj); - break; - } - } - if (dataCorruption) { - var criteria = { - whereClause: ' WHERE json is null OR json= "" ' - }; - OB.Dal.removeAll(model, criteria); - } - - var dataToSend = []; - newDataToSync.each(function(record) { - if (record.get('json')) { - dataToSend.push(JSON.parse(record.get('json'))); - } else if (!_.isUndefined(record.get('objToSend'))) { - if (!_.isNull(record.get('objToSend'))) { - dataToSend.push(JSON.parse(record.get('objToSend'))); - } - } else { - dataToSend.push(record); - } - }); - - var timeout = modelObj.timeout || 20000; - var timePerRecord = modelObj.timePerRecord || 1000; - var data = { - messageId: OB.UTIL.get_UUID(), - modelName: modelObj.name, - data: dataToSend, - isSyncModel: true - }; - - // add an additional pre-sync action, remove any non-persistent data - // before really going to the server - if (OB.MobileApp.model.hasPermission('OBMOBC_SynchronizedMode', true)) { - newDataToSync.each(function(record) { - me.preSyncPromises.push( - new Promise(function(resolve, reject) { - if (!modelObj.isPersistent) { - OB.Dal.remove( - record, - function() { - resolve(); - }, - function(tx, err) { - OB.UTIL.showError(err); - reject(); - } - ); - } else { - resolve(); - } - }) - ); - }); - } - - var procErrorCallBack = function() { - // proc.exec mcallbackerror - OB.warn( - "Error while synchronizing model '" + - OB.Dal.getTableName(model) + - "'" - ); - - me.syncModelExecuteErrorCallbacks(); - }; - - var procSuccessCallBack = function( - data, - message, - lastUpdated, - endRow, - tx, - requestCallback - ) { - // error - if (data && data.exception) { - OB.warn( - "The model '" + - OB.Dal.getTableName(model) + - "'' has not been synchronized with the server" - ); - if ( - data.exception.invalidPermission && - !me.get('displayedInvalidPermission') - ) { - // invalid permission message only will be displayed once time - me.set('displayedInvalidPermission', true); - OB.UTIL.showConfirmation.display( - 'Info', - OB.I18N.getLabel('OBMOBC_NoPermissionToSyncModel', [ - OB.Dal.getTableName(model), - OB.Dal.getTableName(model) - ]), - [ - { - label: OB.I18N.getLabel('OBMOBC_LblOk'), - isConfirmButton: true, - action: function() {} - } - ] - ); - } - me.syncModelExecuteErrorCallbacks(); - return; - } - // success. Elements can be now deleted from the database - var removeSyncedElemsCallback = function(tx) { - OB.info("Purging the '" + OB.Dal.getTableName(model) + "' table"); - - var promises = []; - - if (modelObj.successSendModel) { - promises.push( - new Promise(function(resolve, reject) { - modelObj.successSendModel(); - resolve(); - }) - ); - } - - newDataToSync.each(function(record) { - promises.push( - new Promise(function(resolve, reject) { - if (modelObj.isPersistent) { - // Persistent model. Do not delete, just mark it as processed. - OB.Dal.updateRecordColumn( - record, - 'isbeingprocessed', - 'Y', - function() { - if (requestCallback) { - requestCallback(); - } - resolve(); - }, - function(tx, err) { - reject(); - }, - tx - ); - } else { - // no persistent model (Default). - OB.Dal.removeInTransaction( - tx, - record, - function() { - if (requestCallback) { - requestCallback(); - } - resolve(); - }, - function(tx, err) { - OB.UTIL.showError(err); - reject(); - } - ); - } - }) - ); - }); - - Promise.all(promises).then( - function() { - // if the model has been partitioned - if (modelNotFullySynced) { - OB.info( - newDataToSync.length + - " records of the table '" + - OB.Dal.getTableName(model) + - "' have been successfully synchronized with the server. " + - (dataToSync.length - newDataToSync.length) + - ' records remaining to be synchronized.' - ); - me.syncModel(); - return; - } - - OB.info( - "The table '" + - OB.Dal.getTableName(model) + - "' has been fully synchronized with the server" - ); - }, - function(err) { - OB.error( - "Could not purge the '" + - OB.Dal.getTableName(model) + - "' table. Error message: " + - err - ); - } - ); - // not synchronized mode do the next in the success callback - // with synchronized mode the recall syncmodel is below in the code - if ( - !OB.MobileApp.model.hasPermission('OBMOBC_SynchronizedMode', true) - ) { - me.syncModel(); - } - }; - if (modelObj.removeSyncedElemsCallback) { - modelObj.removeSyncedElemsCallback( - newDataToSync, - tx, - requestCallback - ); - } else { - removeSyncedElemsCallback(tx); - } - if (modelObj.postProcessingFunction) { - modelObj.postProcessingFunction( - newDataToSync, - removeSyncedElemsCallback - ); - } - }; - - if (OB.MobileApp.model.hasPermission('OBMOBC_SynchronizedMode', true)) { - me.collectSyncData( - className, - data, - timeout + timePerRecord * newDataToSync.length - ); - me.syncModelSuccessCallbacks.push(procSuccessCallBack); - me.syncModel(); - } else { - var proc = new OB.DS.Process(className); - //if the model of the message requires polling, add it to the list - var tmpMsg = OB.PollingUtils.createMessage(data, proc.source); - data.messageId = tmpMsg.id; - if (OB.PollingUtils.getPollingUrl(tmpMsg)) { - OB.Polling.PollingRequestHandler.planedToSendPollingRequest.add( - new OB.Model.PollingRequest({ - message: tmpMsg - }) - ); - } - proc.exec( - data, - procSuccessCallBack, - procErrorCallBack, - null, - timeout + timePerRecord * newDataToSync.length - ); - } - }, - - function() { - // there is no model in the local database. this is ok. move to the next model - me.syncModel(); - }, - { - // do not show an error when the table is not present in the local database because it could happen when the cache is still clean - doNotShowErrors: true - } - ); }, syncModelSuccessCallbacks: [], syncModelErrorCallbacks: [], @@ -1802,39 +1358,6 @@ OB.Model.Terminal = Backbone.Model.extend({ } return; } - // flow note: this line must be located before the queues are reset. Check models queue and callbacks queues, the process finishes when the callback are called - var isCurrentlySynchronizing = - (me.syncModelQueue && me.syncModelQueue.length > 0) || - (me.syncModelSuccessCallbacks && - me.syncModelSuccessCallbacks.length > 0) || - (me.syncModelErrorCallbacks && me.syncModelErrorCallbacks.length > 0); - // start the synchronization if it was not already in progress - if (!isCurrentlySynchronizing) { - me.syncModelSuccessCallbacks = []; - me.syncModelErrorCallbacks = []; - - // remember the callbacks in the callbacks queue - me.syncModelSuccessCallbacks.push(successCallback); - me.syncModelErrorCallbacks.push(errorCallback); - - // all models must restart the synchronization when syncAllModels is called. this is attained reseting the queue - me.syncModelQueue = []; - // add all the models to the queue - var i; - for (i = 0; i < this.get('dataSyncModels').length; i++) { - var modelObj = this.get('dataSyncModels')[i]; - me.syncModelQueue.push(modelObj); - } - - // reset some members used in synchronized comms - me.synchronizedData = []; - me.synchronizedTimeOut = 0; - - me.syncModel( - this.syncModelExecuteSuccessCallbacks, - this.syncModelExecuteErrorCallbacks - ); - } }, /** @@ -2326,16 +1849,7 @@ OB.Model.Terminal = Backbone.Model.extend({ windowName + (background ? '. (' + background + ' )' : '') ); - - OB.Dal.loadModels( - false, - datasources, - null, - incremental, - callback, - background - ); - + callback(); this.postLoadModels(); }, postLoadModels: function() {}, issue51841_21Q1_core.diff [^] (113,773 bytes) 2023-06-29 16:59 [Show Content] [Hide Content] diff --git a/web/org.openbravo.mobile.core/app/model/masterdata/MasterdataController.js b/web/org.openbravo.mobile.core/app/model/masterdata/MasterdataController.js index af7251ab..70a14ccb 100644 --- a/web/org.openbravo.mobile.core/app/model/masterdata/MasterdataController.js +++ b/web/org.openbravo.mobile.core/app/model/masterdata/MasterdataController.js @@ -82,15 +82,16 @@ * Opens the master data IndexedDB database, creating it if it does not exist * @throws {Error} Database can not be opened */ - async openDatabase() { - // do not check model changes if the db was already opened - if (databaseController.getDatabase()) { - return; - } - const existModelChanges = this.recomputeModelHash(); + async openDatabase( + { checkModelChanges = true, statusCallback } = { checkModelChanges: true } + ) { + const existModelChanges = checkModelChanges && this.recomputeModelHash(); if (existModelChanges) { // there are changes in the master data models, db should be recreated OB.info(`Deleting IndexedDB master data database`); + if (statusCallback) { + statusCallback({ deleteDatabase: true }); + } await databaseController .deleteDatabase() .catch(error => OB.error(error)); @@ -107,6 +108,9 @@ OB.UTIL.localStorage.removeItem('POSLastIncRefresh'); } await databaseController.openDatabase(); + if (statusCallback) { + statusCallback({ openDatabase: true }); + } } /** diff --git a/web/org.openbravo.mobile.core/source/data/ob-dal.js b/web/org.openbravo.mobile.core/source/data/ob-dal.js index d7f330e6..1fd04dd9 100644 --- a/web/org.openbravo.mobile.core/source/data/ob-dal.js +++ b/web/org.openbravo.mobile.core/source/data/ob-dal.js @@ -1,6 +1,6 @@ /* ************************************************************************************ - * Copyright (C) 2012-2020 Openbravo S.L.U. + * Copyright (C) 2012-2023 Openbravo S.L.U. * Licensed under the Openbravo Commercial License version 1.0 * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html * or in the legal folder of this module distribution. @@ -26,45 +26,6 @@ OB.Dal = OB.Dal || {}; OB.Dal.stackSize = 0; OB.Dal.ErrorWritingToDisk = false; - function executeSqlErrorHandler( - logLevel, - header, - objectInvolved, - txError, - e, - caller - ) { - // arguments check - OB.UTIL.Debug.execute(function() { - if (!logLevel) { - throw 'executeSqlErrorHandler: missing logLevel'; - } - if (!header) { - throw 'executeSqlErrorHandler: missing header'; - } - if (!objectInvolved) { - throw 'executeSqlErrorHandler: missing objectInvolved'; - } - if (!e) { - throw 'executeSqlErrorHandler: missing e'; - } - }); - // show an error - var link = OB.UTIL.getStackLink(3); - - var header2 = header + " '" + objectInvolved + "'"; - // log depending on the logLevel - if (logLevel === 'warn') { - OB.warn(OB.UTIL.argumentsToStringifyed(header2, e, link)); - return; - } - if (caller) { - OB.error(OB.UTIL.argumentsToStringifyed(header2, e, caller)); - } else { - OB.error(OB.UTIL.argumentsToStringifyed(header2, e, link)); - } - } - function getCallerInfo() { var message = ''; // Activate this lines to see the caller function @@ -78,89 +39,6 @@ OB.Dal = OB.Dal || {}; return message; } - function silentFunction(f) { - return function() { - if (_.isFunction(f)) { - try { - f(arguments); - } catch (e) { - OB.error( - 'OB.Dal: a success callback threw an exception', - f, - '\n' + e.stack - ); - } - } - }; - } - - /* - * initialize the WebSQL dababase - */ - OB.Dal.openWebSQL = function() { - if (!window.openDatabase) { - return; // Supported browsers check will show browsers supported information. - } - - // do not initialize the db if it was already initialized - if (OB.Data.localDB && OB.Data.localDB.version) { - return OB.Data.localDB; - } - - var dbInfo = OB.MobileApp.model.get('localDB'); - - // arguments check - if (!dbInfo) { - OB.UTIL.Debug.execute(function() { - throw "The database version information must be available before 'OB.Dal.openWebSQL' is called"; - }); - return; - } - - OB.info('OB.Dal.openWebSQL: initializing WebSQL'); - if (OB.I18N.labels) { - OB.UTIL.showLoadingMessage( - OB.I18N.getLabel('OBMOBC_InitializingDatabase') - ); - } - - var undef; - var wsql = window.openDatabase !== undef; - var db; - - if (wsql === false) { - // Support should get this error. Show it in productionn - OB.error('WebSQL error: Unable find the database engine'); - } - - try { - db = - wsql && - window.openDatabase(dbInfo.name, '', dbInfo.displayName, dbInfo.size); - } catch (e) { - // if the database could not be created, logging with OB.error is not available - // Support should get this error. Show it in production - OB.error('Web SQL error: ' + e); - OB.UTIL.Debug.execute(function(e) { - throw 'Web SQL error: ' + e; - }); - return; - } - if (!db) { - // if the database could not be created, logging with OB.error is not available - // Support should get this error. Show it in production - OB.error('Web SQL error'); - OB.UTIL.Debug.execute(function() { - throw 'Web SQL error'; - }); - return; - } - - OB.Data.localDB = db; - - return db; - }; - /** * TODO: localStorage * This is a function to centralize TODO Dal code related to localstorage @@ -212,85 +90,6 @@ OB.Dal = OB.Dal || {}; return new model(tmp); }; - OB.Dal.getWhereClause = function(criteria, propertyMap) { - var appendWhere = true, - firstParam = true, - sql = '', - params = [], - res = {}, - orAnd = ' AND '; - if (criteria && !_.isEmpty(criteria)) { - if (criteria.obdalcriteriaType) { - orAnd = ' ' + criteria.obdalcriteriaType + ' '; - delete criteria.obdalcriteriaType; - } - _.each(_.keys(criteria), function(k) { - var undef, - colName, - val = criteria[k], - operator = - val !== undef && val !== null && val.operator !== undef - ? val.operator - : '=', - value = - val !== undef && val !== null && val.value !== undef - ? val.value - : val; - if (k !== '_orderByClause' && k !== '_orderBy' && k !== '_limit') { - if (appendWhere) { - sql = sql + ' WHERE '; - params = []; - appendWhere = false; - } - - if (_.isArray(propertyMap)) { - if (k === '_filter') { - colName = '_filter'; - } else { - colName = _.find(propertyMap, function(p) { - return k === p.name; - }).column; - } - } else { - colName = propertyMap[k]; - } - - sql = sql + (firstParam ? '' : orAnd) + ' ' + colName + ' '; - - if (value === null || operator === OB.Dal.ISNULL) { - sql = sql + ' IS null '; - } else if (operator === OB.Dal.ISNOTNULL) { - sql = sql + ' IS NOT null '; - } else { - if (operator === OB.Dal.EQ) { - sql = sql + ' = ? '; - } else if (operator === OB.Dal.NEQ) { - sql = sql + ' != ? '; - } else { - sql = sql + ' like ? '; - } - - if (operator === OB.Dal.CONTAINS) { - value = '%' + value + '%'; - } else if (operator === OB.Dal.STARTSWITH) { - value = value + '%'; - } else if (operator === OB.Dal.ENDSWITH) { - value = value + '%'; - } - params.push(value); - } - - if (firstParam) { - firstParam = false; - } - } - }); - } - res.sql = sql; - res.params = params; - return res; - }; - OB.Dal.getTableName = function(model) { if (model) { if (model.getTableName) { @@ -321,13 +120,6 @@ OB.Dal = OB.Dal || {}; return null; }; - OB.Dal.transaction = function(callback, errorCallback, successCallback) { - OB.warn( - 'WebSQL is no longer supported. OB.Dal.transaction should not be used' - ); - OB.Data.localDB.transaction(callback, errorCallback, successCallback); - }; - OB.Dal.findUsingCache = function( cacheName, model, @@ -382,17 +174,6 @@ OB.Dal = OB.Dal || {}; } }; - OB.Dal.findInTransaction = function( - tx, - model, - whereClause, - success, - error, - args - ) { - OB.Dal.find(model, whereClause, success, error, args, tx); - }; - OB.Dal.find = function( model, whereClause, @@ -402,7 +183,6 @@ OB.Dal = OB.Dal || {}; currentTransaction, forceLocal ) { - var callerInfo = getCallerInfo(); var params = null, undef, colType, @@ -411,7 +191,6 @@ OB.Dal = OB.Dal || {}; i, criteria, j, - orderBy, limit; if (OB.UTIL.isNullOrUndefined(model.prototype)) { OB.error('Model name without prototype: ' + model.getTableName()); @@ -617,1201 +396,44 @@ OB.Dal = OB.Dal || {}; } } ); - } else if (OB.Data.localDB) { - var tableName = OB.Dal.getTableName(model), - propertyMap = OB.Dal.getPropertyMap(model), - sql = 'SELECT * FROM ' + tableName, - processResult, - processError; - - processResult = function(tr, result) { - var i, - collectionType = - OB.Collection[model.prototype.modelName + 'List'] || - Backbone.Collection, - collection = new collectionType(); - const len = result.rows ? result.rows.length : result.length; - if (len === 0) { - success(collection, args); - } else { - for (i = 0; i < len; i++) { - collection.add( - OB.Dal.transform( - model, - result.rows ? result.rows.item(i) : result[i] - ) - ); - } - success(collection, args); - } - }; - - processError = function(txError, e) { - if (!args || !args.doNotShowErrors) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.find: table', - tableName, - txError, - e, - callerInfo - ); - } - if (error) { - error(); - } - }; - - if (model.prototype.indexDBModel) { - const indexDBcriteria = new OB.App.Class.Criteria(); - for (var prop in whereClause) { - if (Object.prototype.hasOwnProperty.call(whereClause, prop)) { - indexDBcriteria.criterion(prop, whereClause[prop]); - } - } - OB.App.MasterdataController.find( - model.prototype.indexDBModel, - indexDBcriteria.build() - ) - .then(result => { - processResult(undefined, result); - }) - .catch(error => { - processError(undefined, error.message); - }); - return; - } - - // websql - // arguments check - if (tableName === null) { - OB.warn('OB.Dal.find: tableName not found'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.find: tableName not found'; - }); - } - if (propertyMap === null) { - OB.warn('OB.Dal.find: propertyMap not found'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.find: propertyMap not found'; - }); - } - - if (whereClause && whereClause._orderByClause) { - orderBy = whereClause._orderByClause; - } - - if (whereClause && whereClause._orderBy) { - _.forEach(whereClause._orderBy, function(elem) { - if (_.isUndefined(orderBy)) { - orderBy = ''; - } else { - orderBy += ', '; - } - orderBy += elem.column; - if (!_.isUndefined(elem.asc)) { - if (elem.asc) { - orderBy += ' asc'; - } else { - orderBy += ' desc'; - } - } - }); - } - - if (whereClause && whereClause._limit) { - //set in the model temporary the limit set by the query - model.prototype.tempDataLimit = whereClause._limit; - // set limit + 1 to see if there are more items to retrieve and in that case show a message to narrow the query in order to less items - limit = whereClause._limit + 1; - } else { - limit = model.prototype.dataLimit; - model.prototype.tempDataLimit = undefined; - } - if (whereClause && whereClause._whereClause) { - whereClause.sql = ' ' + whereClause._whereClause; - } else { - whereClause = OB.Dal.getWhereClause(whereClause, propertyMap); - } - sql = sql + whereClause.sql; - params = _.isEmpty(whereClause.params) ? [] : whereClause.params; - - if (orderBy) { - sql = sql + ' ORDER BY ' + orderBy + ' '; - } else if (model.propertyList || model.prototype.propertyMap._idx) { - sql = sql + ' ORDER BY _idx '; - } - - if (limit) { - sql = sql + ' LIMIT ' + limit; - } - - if (currentTransaction) { - currentTransaction.executeSql(sql, params, processResult, processError); - } else { - OB.Data.localDB.readTransaction(function(tx) { - tx.executeSql(sql, params, processResult, processError); - }); - } } else { this.missingLocalStorageLogic(); } }; - OB.Dal.queryUsingCache = function(model, sql, params, success, error, args) { - if ( - OB.Cache.hasItem(sql, params, args ? args.modelsAffectedByCache : null) - ) { - OB.Dal.stackSize++; - if (OB.Dal.stackSize % 50 === 0) { - setTimeout(function() { - success( - OB.Cache.getItem( - sql, - params, - args ? args.modelsAffectedByCache : null - ), - args, - args ? args.modelsAffectedByCache : null - ); - }, 0); - } else { - success( - OB.Cache.getItem( - sql, - params, - args ? args.modelsAffectedByCache : null - ), - args, - args ? args.modelsAffectedByCache : null - ); - } - } else { - OB.Dal.query( - model, - sql, - params, - function(records) { - OB.Cache.putItem( - sql, - params, - records, - args ? args.modelsAffectedByCache : null - ); - success(records, args); - }, - error, - args - ); - } - }; - - OB.Dal.queryInTransaction = function( - tx, - model, - sql, - params, - success, - error, - args - ) { - OB.Dal.query(model, sql, params, success, error, args, tx); - }; - - OB.Dal.query = function( + OB.Dal.get = function( model, - sql, - params, + id, success, error, - args, + empty, currentTransaction, - limit + local ) { - var processResult, processError; - processResult = function(tr, result) { - var i, - collectionType = - OB.Collection[model.prototype.modelName + 'List'] || - Backbone.Collection, - collection = new collectionType(), - len = result.rows.length; - if (len === 0) { - success(collection, args); - } else { - for (i = 0; i < len; i++) { - collection.add(OB.Dal.transform(model, result.rows.item(i))); - } - success(collection, args); - } - }; - - processError = function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.query: table', - model.prototype.modelName, - txError, - e - ); - if (_.isFunction(error)) { - error(); - } - }; - - if (OB.Data.localDB) { - if (_.isNumber(limit)) { - //set in the model temporary the limit set by the query - model.prototype.tempDataLimit = limit; - // set limit + 1 to see if there are more items to retrieve and in that case show a message to narrow the query in order to less items - sql = sql + ' LIMIT ' + limit + 1; - } else if (model.prototype.dataLimit) { - sql = sql + ' LIMIT ' + model.prototype.dataLimit; - model.prototype.tempDataLimit = undefined; - } - if (currentTransaction) { - currentTransaction.executeSql( - sql, - _.isEmpty(params) ? [] : params, - processResult, - processError + OB.UTIL.Debug.execute(function() { + var caller = OB.UTIL.getStackTrace('get', true); + var callerInfo = getCallerInfo(); + if (!id) { + OB.warn( + '[dberror] OB.Dal.get: id not found. - Caller: ' + + caller + + ' - Caller info: ' + + callerInfo ); - } else { - OB.Data.localDB.transaction(function(tx) { - tx.executeSql( - sql, - _.isEmpty(params) ? [] : params, - processResult, - processError - ); - }); - } - } else { - this.missingLocalStorageLogic(); - } - }; - - OB.Dal.saveInTransaction = function(tx, model, success, error, forceInsert) { - OB.Dal.save(model, success, error, forceInsert, tx); - }; - - OB.Dal.save = function( - model, - success, - error, - forceInsert, - currentTransaction - ) { - var caller = OB.UTIL.getStackTrace('save', true); - var callerInfo = getCallerInfo(); - var modelProto = model.constructor.prototype, - xhr, - rr, - data = {}; - forceInsert = forceInsert || false; - - // Orders should not be saved to WebSQL. Use IndexedDB instead - if (model.modelName === 'Order') { - OB.warn('OB.Dal.save: Attempted to save an Order instance'); - if (_.isFunction(success)) { - success(); } - return; - } - - //Validation to avoid wrong saves - if ( - !_.isUndefined(model.get('json')) && - (_.isEmpty(model.get('json')) || _.isNull(model.get('json'))) - ) { - OB.error( - '[OB.Dal.save] Wrong write in ' + - model.modelName + - ' because json column is undefined.' + - ' - Caller: ' + - caller + - ' - callerInfo: ' + - callerInfo + - '- Model to save is: ' + - JSON.stringify(model.toJSON()) - ); - } - //The id cannot be null + }); if ( - _.isNull(model.get('id')) || - (model.get('json') && - JSON.parse(model.get('json')) && - _.isNull(JSON.parse(model.get('json')).id)) + !local && + model.prototype.remote && + OB.MobileApp.model.hasPermission(model.prototype.remote, true) ) { - OB.error( - '[OB.Dal.save] Wrong model, it has no id. ' + - ' - Caller: ' + - caller + - ' - callerInfo: ' + - callerInfo + - ' Model: ' + - JSON.stringify(model.toJSON()) + - '\n callerInfo: ' + - OB.UTIL.getStackTrace('getCallerInfo', false) - ); - var uuidTmp = OB.UTIL.get_UUID(); - model.set('id', uuidTmp); - model.set('json', JSON.stringify(model.serializeToJSON())); - forceInsert = true; - } - // TODO: properly check model type - if (modelProto && modelProto.online) { - if (!model) { - OB.warn('OB.Dal.save: you need to pass a Model instance to save'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.save: you need to pass a Model instance to save'; - }); - } - data.operationType = 'update'; - data.data = model.toJSON(); - - xhr = new enyo.Ajax({ - url: modelProto.source, - method: 'PUT', - data: JSON.stringify(data), - success: function(inSender, inResponse) { - success(inResponse); - } - }); - rr = new OB.RR.Request({ - ajaxRequest: xhr - }); - rr.exec(xhr.url); - } else if (OB.Data.localDB) { - var modelDefinition = OB.Model[modelProto.modelName], - tableName = OB.Dal.getTableName(modelDefinition), - primaryKey, - primaryKeyProperty = 'id', - sql = '', - params = null, - firstParam = true, - uuid, - propertyName, - filterVal, - processError, - successFunction; - - successFunction = function() { - if (success) { - success(); - } - OB.Cache.resetCacheForModel(modelProto.modelName); - }; - - var updateToBeChecked = false; - - processError = function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.save: table', - tableName, - txError, - e, - callerInfo - ); - if (_.isFunction(error)) { - error(); - } - - if (OB.Dal.ErrorWritingToDisk) { - return false; - } - - OB.UTIL.showConfirmation.display( - OB.I18N.getLabel('OBMOBC_Error'), - //OB.I18N.getLabel('OBMOBC_CriticalErrorObDalSave'), - OB.I18N.getLabel('OBMOBC_CriticalErrorObDalSave') + - '___________ Error: ' + - e.message, - [ - { - label: OB.I18N.getLabel('OBPOS_LblEndSession'), - isConfirmButton: true, - action: function() { - OB.MobileApp.model.logout(); - } - } - ], - { - autoDismiss: false, - onHideFunction: function() { - OB.MobileApp.model.logout(); - }, - classes: 'error' - } - ); - - OB.Dal.ErrorWritingToDisk = true; - return false; - }; - - // websql - // argument checks - if (!tableName) { - OB.warn('OB.Dal.save: tableName not found'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.save: tableName not found'; - }); - } - - if (modelDefinition.getPrimaryKey) { - primaryKey = modelDefinition.getPrimaryKey(); - primaryKeyProperty = primaryKey.name; - } - - if (model.get(primaryKeyProperty) && forceInsert === false) { - if (modelDefinition.getUpdateStatement) { - sql = modelDefinition.getUpdateStatement(); - params = []; - _.each(modelDefinition.getPropertiesForUpdate(), function(property) { - //filter doen't have name and always is the last one - if (property.name) { - params.push(model.get(property.name)); - } - }); - //filter param - if (modelDefinition.hasFilter()) { - filterVal = ''; - _.each(modelDefinition.getFilterProperties(), function( - filterProperty - ) { - filterVal = - OB.UTIL.unAccent(filterVal) + - (model.get(filterProperty) - ? model.get(filterProperty) + '###' - : ''); - }); - params.push(filterVal); - } - //Where param - params.push(model.get(primaryKeyProperty)); - } else { - // UPDATE - if (tableName === 'c_order' || tableName === 'cashmanagement') { - updateToBeChecked = true; - } - sql = 'UPDATE ' + tableName + ' SET '; - - _.each(_.keys(modelProto.properties), function(attr) { - propertyName = modelProto.properties[attr]; - if (attr === 'id') { - return; - } - - if (firstParam) { - firstParam = false; - params = []; - } else { - sql = sql + ', '; - } - - sql = sql + modelProto.propertyMap[propertyName] + ' = ? '; - params.push(model.get(propertyName)); - }); - - if (modelProto.propertiesFilter) { - filterVal = ''; - _.each(modelProto.propertiesFilter, function(prop) { - filterVal = - filterVal + (model.get(prop) ? model.get(prop) + '###' : ''); - }); - sql = sql + ', _filter = ? '; - params.push(filterVal); - } - sql = sql + ' WHERE ' + tableName + '_id = ?'; - params.push(model.get('id')); - } - } else { - params = []; - // INSERT - sql = modelDefinition.getInsertStatement - ? modelDefinition.getInsertStatement() - : modelProto.insertStatement; - if (forceInsert === false) { - uuid = OB.UTIL.get_UUID(); - params.push(uuid); - if (model.getPrimaryKey) { - primaryKey = model.getPrimaryKey(); - model.set(primaryKey.name, uuid); - } else { - model.set('id', uuid); - } - } - //Set params - if (modelDefinition.getProperties) { - _.each(modelDefinition.getProperties(), function(property) { - if (forceInsert === false) { - if (property.primaryKey) { - return; - } - } - //_filter property doesn't have name. - //don't set the filter column. We will do it in the next step - if (property.name === '_filter') { - return; - } - if (property.name) { - params.push( - model.get(property.name) === undefined - ? null - : model.get(property.name) - ); - } - }); - } else { - _.each(modelProto.properties, function(property) { - if (forceInsert === false) { - if ('id' === property) { - return; - } - } - if (model.get(property) === '_filter') { - return; - } - params.push( - model.get(property) === undefined ? null : model.get(property) - ); - }); - } - //set filter column - if (modelDefinition.hasFilter) { - if (modelDefinition.hasFilter()) { - filterVal = ''; - _.each(modelDefinition.getFilterProperties(), function(filterProp) { - filterVal = - OB.UTIL.unAccent(filterVal) + - (model.get(filterProp) ? model.get(filterProp) + '###' : ''); - }); - //Include in the last position but before _idx - params.splice(params.length - 1, 0, filterVal); - } - } else { - if (modelProto.propertiesFilter) { - filterVal = ''; - _.each(modelProto.propertiesFilter, function(prop) { - filterVal = - filterVal + (model.get(prop) ? model.get(prop) + '###' : ''); - }); - //Include in the last position but before _idx - params.splice(params.length - 1, 0, filterVal); - } - } - } - - if (currentTransaction) { - try { - if (updateToBeChecked) { - currentTransaction.executeSql( - sql + - (tableName === 'c_order' - ? " AND hasbeenpaid = 'N'" - : " AND isbeingprocessed = 'N'"), - params, - function(trx, result) { - if (result.rowsAffected !== 1) { - if (tableName === 'c_order') { - OB.error( - '[checkBlocked][transaction]The order does not exists or is frozen. Wrong write in c_order avoided [' + - model.get('id') + - '][' + - model.get('documentNo') + - '] - Caller: ' + - caller + - ' - callerInfo: ' + - callerInfo - ); - } else { - OB.error( - '[checkBlocked][transaction]The cash management does not exists or is frozen. Wrong write in cashmanagement avoided [' + - model.get('id') + - '][' + - model.get('description') + - '] - Caller: ' + - caller + - ' - callerInfo: ' + - callerInfo - ); - } - OB.UTIL.showConfirmation.display( - OB.I18N.getLabel('OBMOBC_WrongUpdate_header'), - OB.I18N.getLabel('OBMOBC_WrongUpdate_body'), - [ - { - label: OB.I18N.getLabel('OBMOBC_Reload'), - classes: 'error', - action: function() { - window.location.reload(); - } - } - ], - { - classes: 'error', - onHideFunction: function() { - window.location.reload(); - } - } - ); - return; - } - if (successFunction) { - successFunction(); - } - }, - processError - ); - } else { - currentTransaction.executeSql( - sql, - params, - silentFunction(successFunction), - processError - ); - } - } catch (e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.save: table', - tableName, - null, - e, - callerInfo - ); - } - } else { - OB.Data.localDB.transaction(function(tx) { - try { - if (updateToBeChecked) { - tx.executeSql( - sql + - (tableName === 'c_order' - ? " AND hasbeenpaid = 'N'" - : " AND isbeingprocessed = 'N'"), - params, - function(trx, result) { - if (result.rowsAffected !== 1) { - if (tableName === 'c_order') { - OB.error( - '[checkBlocked][transaction]The order does not exists or is frozen. Wrong write in c_order avoided [' + - model.get('id') + - '][' + - model.get('documentNo') + - '] - Caller: ' + - caller + - ' - callerInfo: ' + - callerInfo - ); - } else { - OB.error( - '[checkBlocked][transaction]The cash management does not exists or is frozen. Wrong write in cashmanagement avoided [' + - model.get('id') + - '][' + - model.get('description') + - '] - Caller: ' + - caller + - ' - callerInfo: ' + - callerInfo - ); - } - OB.UTIL.showConfirmation.display( - OB.I18N.getLabel('OBMOBC_WrongUpdate_header'), - OB.I18N.getLabel('OBMOBC_WrongUpdate_body'), - [ - { - label: OB.I18N.getLabel('OBMOBC_Reload'), - classes: 'error', - action: function() { - window.location.reload(); - } - } - ], - { - classes: 'error', - onHideFunction: function() { - window.location.reload(); - } - } - ); - return; - } - if (successFunction) { - successFunction(); - } - }, - processError - ); - } else { - tx.executeSql( - sql, - params, - silentFunction(successFunction), - processError - ); - } - } catch (e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.save: table', - tableName, - null, - e, - callerInfo - ); - } - }); - } - } else { - this.missingLocalStorageLogic(); - } - }; - - OB.Dal.removeInTransaction = function(tx, model, success, error) { - OB.Dal.remove(model, success, error, tx); - }; - - /* - * This method checks if model to save is present in the database before saving it. - * If the model is there it does nothing, if not it does an insert. - */ - OB.Dal.saveIfNew = function(model, success, error) { - OB.Dal.transaction(function(tx) { - OB.Dal.getInTransaction( - tx, - OB.Model[model.modelName], - model.get('id'), - success, - error, - function() { - OB.Dal.saveInTransaction(tx, model, success, error, true); - }, - true - ); - }); - }; - - /* - * This method checks if model to save is present in the database before saving it. - * If the model is there it will update, else it will insert. - */ - OB.Dal.saveOrUpdate = function(model, success, error) { - OB.Dal.transaction(function(tx) { - OB.Dal.getInTransaction( - tx, - OB.Model[model.modelName], - model.get('id'), - function() { - OB.Dal.save(model, success, error, false, tx); - }, - error, - function() { - OB.Dal.saveInTransaction(tx, model, success, error, true); - }, - true - ); - }); - }; - - OB.Dal.updateRecordColumn = function( - record, - columnName, - newValue, - successCallback, - errorCallback, - currentTransaction - ) { - if (OB.Data.localDB) { - var modelProto = record.constructor.prototype; - var modelDefinition = OB.Model[modelProto.modelName]; - var tableName = OB.Dal.getTableName(modelDefinition); - var sql = - 'UPDATE ' + - tableName + - ' SET ' + - columnName + - ' = ? WHERE ' + - tableName + - '_id = ?'; - var params = [newValue, record.get('id')]; - if (currentTransaction) { - try { - currentTransaction.executeSql( - sql, - params, - function() { - // success - OB.info( - "'isbeingprocessed' has been set to 'Y' in the '" + - tableName + - "' table, record id: " + - record.get('id') - ); - successCallback(); - }, - function(txError, e) { - // error - OB.error( - "'isbeingprocessed' has NOT been set to 'Y' in the '" + - tableName + - "' table, record id: " + - record.get('id') + - '. Error message: ' + - e.message - ); - errorCallback(txError, e); - } - ); - } catch (e) { - OB.error( - "cannot create a transaction for the '" + - tableName + - "' table, record id: " + - record.get('id') + - '. Error message: ' + - e - ); - errorCallback(null, e); - } - } else { - OB.Data.localDB.transaction(function(tx) { - try { - tx.executeSql( - sql, - params, - function() { - // success - OB.info( - "'isbeingprocessed' has been set to 'Y' in the '" + - tableName + - "' table, record id: " + - record.get('id') - ); - successCallback(); - }, - function(txError, e) { - // error - OB.error( - "'isbeingprocessed' has NOT been set to 'Y' in the '" + - tableName + - "' table, record id: " + - record.get('id') + - '. Error message: ' + - e.message - ); - errorCallback(txError, e); - } - ); - } catch (e) { - OB.error( - "cannot create a transaction for the '" + - tableName + - "' table, record id: " + - record.get('id') + - '. Error message: ' + - e - ); - errorCallback(null, e); - } - }); - } - } - }; - - OB.Dal.createDataDump = function(models, callback) { - var result = [], - cnt = 0, - promises = []; - - if (models.length === 0) { - if (callback) { - callback(); - } - return; - } - - _.each(models, function(model) { - promises.push( - new Promise(function(resolve, reject) { - OB.Dal.find( - model, - null, - function(data) { - cnt++; - // arbitrary high number we can't load more in memory - if (cnt > 5000) { - var msg = - 'Creating backup of more 5000 records, this it probably not supported, last record ' + - JSON.stringify(data); - OB.UTIL.showError(msg); - OB.error(msg); - throw msg; - } - result.push({ - model: model, - data: data.models - }); - resolve(); - }, - function() { - reject(); - } - ); - }) - ); - }); - - Promise.all(promises).then(function() { - if (callback) { - callback(result); - } - }); - }; - - OB.Dal.restoreDataDump = function(dataDump, callback) { - if (!dataDump) { - if (callback) { - callback(); - } - return; - } - - OB.Dal.transaction( - function(tx) { - _.each(dataDump, function(dataDumpEntry) { - OB.Dal.removeAllInTransaction(tx, dataDumpEntry.model); - _.each(dataDumpEntry.data, function(dataEntry) { - OB.Dal.saveInTransaction(tx, dataEntry, null, null, true); - }); - }); - }, - function() { - OB.error( - 'The restore dump failed failed to be commited. data: ' + - JSON.stringify(dataDump) - ); - }, - function() { - if (callback) { - callback(); - } - } - ); - }; - - OB.Dal.remove = function(model, success, error, currentTransaction) { - if (OB.Data.localDB) { - var modelDefinition = OB.Model[model.constructor.prototype.modelName], - modelProto = model.constructor.prototype, - tableName = OB.Dal.getTableName(modelDefinition), - pk, - pkProperty = 'id', - sql = '', - params = [], - processError; - - processError = function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.remove: table', - tableName, - txError, - e - ); - if (_.isFunction(error)) { - error(); - } - }; - - // websql - if (!tableName) { - OB.warn('OB.Dal.remove: tableName not found'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.remove: tableName not found'; - }); - } - if (modelDefinition.getPrimaryKey) { - pk = modelDefinition.getPrimaryKey() - ? modelDefinition.getPrimaryKey() - : null; - if (pk) { - pkProperty = pk.name; - } - } - if (model.get(pkProperty)) { - if (modelDefinition.getDeleteByIdStatement) { - sql = modelDefinition.getDeleteByIdStatement(); - } else { - sql = - 'DELETE FROM ' + - tableName + - ' WHERE ' + - modelProto.propertyMap[pkProperty] + - ' = ? '; - } - // UPDATE - params.push(model.get(pkProperty)); - } else { - OB.warn( - 'OB.Dal.remove: an object without primary key cannot be deleted' - ); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.remove: an object without primary key cannot be deleted'; - }); - } - - if (currentTransaction) { - currentTransaction.executeSql( - sql, - params, - silentFunction(success), - processError - ); - } else { - OB.Data.localDB.transaction(function(tx) { - tx.executeSql(sql, params, silentFunction(success), processError); - }); - } - } else { - this.missingLocalStorageLogic(); - } - }; - - OB.Dal.removeAllInTransaction = function( - tx, - model, - criteria, - success, - error - ) { - OB.Dal.removeAll(model, criteria, success, error, tx); - }; - - OB.Dal.removeAll = function( - model, - criteria, - success, - error, - currentTransaction - ) { - if (OB.Data.localDB) { - var tableName = OB.Dal.getTableName(model), - propertyMap = OB.Dal.getPropertyMap(model), - sql, - params, - whereClause, - processError; - - processError = function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.removeAll: table', - tableName, - txError, - e - ); - if (_.isFunction(error)) { - error(); - } - }; - - // websql - if (!tableName) { - OB.warn('OB.Dal.removeAll: tableName not found'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.removeAll: tableName not found'; - }); - } - - sql = 'DELETE FROM ' + tableName; - if (criteria && criteria.whereClause) { - whereClause = criteria.whereClause; - sql = sql + whereClause; - } else { - whereClause = OB.Dal.getWhereClause(criteria, propertyMap); - sql = sql + whereClause.sql; - params = _.isEmpty(whereClause.params) ? [] : whereClause.params; - } - - if (currentTransaction) { - currentTransaction.executeSql( - sql, - params, - silentFunction(success), - processError - ); - } else { - OB.Data.localDB.transaction(function(tx) { - tx.executeSql(sql, params, silentFunction(success), processError); - }); - } - } else { - this.missingLocalStorageLogic(); - } - }; - - OB.Dal.removeRemoteModels = function() { - var model; - for (model in OB.Model) { - if ( - Object.prototype.hasOwnProperty.call(OB.Model, model) && - OB.Model[model].prototype && - OB.Model[model].prototype.remote && - OB.Dal.getTableName(OB.Model[model]) && - OB.MobileApp.model.hasPermission(OB.Model[model].prototype.remote, true) - ) { - OB.Dal.removeAll(OB.Model[model]); - } - } - }; - - OB.Dal.getInTransaction = function( - tx, - model, - id, - success, - error, - empty, - local - ) { - OB.Dal.get(model, id, success, error, empty, tx, local); - }; - - OB.Dal.get = function( - model, - id, - success, - error, - empty, - currentTransaction, - local - ) { - OB.UTIL.Debug.execute(function() { - var caller = OB.UTIL.getStackTrace('get', true); - var callerInfo = getCallerInfo(); - if (!id) { - OB.warn( - '[dberror] OB.Dal.get: id not found. - Caller: ' + - caller + - ' - Caller info: ' + - callerInfo - ); - } - }); - if ( - !local && - model.prototype.remote && - OB.MobileApp.model.hasPermission(model.prototype.remote, true) - ) { - var process = new OB.DS.Process(model.prototype.source); - var currentDate = new Date(); - var params = {}; - params.terminalTime = currentDate; - params.terminalTimeOffset = currentDate.getTimezoneOffset(); - var p, i; - var data = {}; + var process = new OB.DS.Process(model.prototype.source); + var currentDate = new Date(); + var params = {}; + params.terminalTime = currentDate; + params.terminalTimeOffset = currentDate.getTimezoneOffset(); + var p, i; + var data = {}; if (params) { p = {}; @@ -1880,633 +502,8 @@ OB.Dal = OB.Dal || {}; } } ); - } else if (OB.Data.localDB) { - var tableName = OB.Dal.getTableName(model), - sql = 'SELECT * FROM ' + tableName + ' WHERE ' + tableName + '_id = ?', - processResult, - processError; - - processResult = function(tr, result) { - const len = result.rows ? result.rows.length : result.length; - if (len === 0) { - if (empty) { - empty(); - } else { - return null; - } - } else { - success( - OB.Dal.transform( - model, - result.rows - ? result.rows.item(0) - : _.isArray(result) - ? result[0] - : result - ) - ); - } - }; - - processError = function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.get: table', - tableName, - txError, - e - ); - if (_.isFunction(error)) { - error(); - } - }; - - if (model.prototype.indexDBModel) { - OB.App.MasterdataController.get(model.prototype.indexDBModel, id) - .then(result => { - processResult(undefined, result); - }) - .catch(error => { - processError(undefined, error.message); - }); - return; - } - - // websql - if (currentTransaction) { - currentTransaction.executeSql(sql, [id], processResult, processError); - } else { - OB.Data.localDB.readTransaction(function(tx) { - tx.executeSql(sql, [id], processResult, processError); - }); - } } else { this.missingLocalStorageLogic(); } }; - - OB.Dal.dropTable = function(model, successCallback, errorCallback) { - if (OB.Data.localDB) { - var sql = model.getDropStatement - ? model.getDropStatement() - : model.prototype.dropStatement; - OB.Data.localDB.transaction(function(tx) { - tx.executeSql( - sql, - [], - function() { - OB.debug('succesfully dropped table: ' + sql); - successCallback(); - }, - errorCallback - ); - }); - } else { - this.missingLocalStorageLogic(); - } - }; - - OB.Dal.initCache = function(model, initialData, success, error, incremental) { - if (OB.Data.localDB) { - // error must be defined, if not it fails in some android versions - error = error || function() {}; - - if ( - !model.propertyList && - (!model.prototype.createStatement || !model.prototype.dropStatement) - ) { - OB.warn('OB.Dal.initCache: model requires a create and drop statement'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.initCache: model requires a create and drop statement'; - }); - } - - if (!initialData) { - OB.warn('OB.Dal.initCache: initialData must be passed as parameter'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.initCache: initialData must be passed as parameter'; - }); - } - - if (!model.prototype.local && !incremental) { - OB.Data.localDB.transaction(function(tx) { - var st = model.getDropStatement - ? model.getDropStatement() - : model.prototype.dropStatement; - tx.executeSql(st, [], null, function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.initCache: table', - model.prototype.modelName, - txError, - e - ); - if (_.isFunction(error)) { - error(); - } - }); - }, error); - } - - OB.Data.localDB.transaction(function(tx) { - var createStatement = model.getCreateStatement - ? model.getCreateStatement() - : model.prototype.createStatement; - - // Issue 30939: Do not allow nulls in the primary key - if (createStatement.indexOf('PRIMARY KEY NOT NULL') === -1) { - createStatement = createStatement.replace( - 'PRIMARY KEY', - 'PRIMARY KEY NOT NULL' - ); - } - OB.UTIL.Debug.execute(function() { - if (createStatement.indexOf('PRIMARY KEY NOT NULL') === -1) { - throw "The create statement must contain a 'PRIMARY KEY NOT NULL' (createStatement: '" + - createStatement + - "'"; - } - }); - - var createIndexStatement; - tx.executeSql( - createStatement, - [], - function() { - //Create Index - if (model.hasIndex && model.hasIndex()) { - _.each(model.getIndexes(), function(indexDefinition) { - createIndexStatement = model.getCreateIndexStatement( - indexDefinition - ); - tx.executeSql(createIndexStatement, [], null, function( - txError, - e - ) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.initCache: index for table', - model.prototype.modelName, - txError, - e - ); - }); - }); - } - - model.areTablesCreated = true; - }, - function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.initCache: table', - model.prototype.modelName, - txError, - e - ); - } - ); - }, error); - - if (_.isArray(initialData)) { - OB.Dal.insertData(model, initialData, success, error, incremental, 0); - } else { - // no initial data - OB.warn('OB.Dal.initCache: initialData must be an Array'); - OB.UTIL.Debug.execute(function() { - throw 'OB.Dal.initCache: initialData must be an Array'; - }); - } - } else { - this.missingLocalStorageLogic(); - } - }; - - /** - * Inserts data into a local table - * - * - */ - OB.Dal.insertData = function( - model, - data, - success, - error, - incremental, - offset - ) { - OB.Data.localDB.transaction( - function(tx) { - var props = model.getProperties - ? model.getProperties() - : model.prototype.properties, - filterVal, - values, - _idx = offset, - updateRecord, - handleError, - insertStatement, - filterProps; - handleError = function(txError, e) { - executeSqlErrorHandler( - 'error', - 'OB.Dal.insertData: model insert', - model.prototype.modelName, - txError, - e - ); - }; - updateRecord = function(tx, model, values, active) { - var deleteStatement; - deleteStatement = model.getDeleteByIdStatement - ? model.getDeleteByIdStatement() - : 'DELETE FROM ' + - model.prototype.tableName + - ' WHERE ' + - model.prototype.propertyMap.id + - '=?'; - tx.executeSql( - deleteStatement, - [values[0]], - function() { - if (_.isUndefined(active) || active) { - var insertSatement; - insertSatement = model.getInsertStatement - ? model.getInsertStatement() - : model.prototype.insertStatement; - tx.executeSql(insertSatement, values, null, function(tx, e) { - handleError(tx, e); - return true; - }); - } - }, - handleError - ); - }; - insertStatement = model.getInsertStatement - ? model.getInsertStatement() - : model.prototype.insertStatement; - filterProps = model.getFilterProperties - ? model.getFilterProperties() - : model.prototype.propertiesFilter; - _.each(data, function(item) { - values = []; - _.each(props, function(prop) { - var value, - propName = typeof prop === 'string' ? prop : prop.name; - if (!propName || '_idx' === propName || '_filter' === propName) { - return; - } - value = item[propName]; - values.push(value === undefined ? null : value); - }); - if ( - (model.hasFilter && model.hasFilter()) || - model.prototype.propertiesFilter - ) { - filterVal = ''; - _.each(filterProps, function(prop) { - filterVal = - OB.UTIL.unAccent(filterVal) + - (item[prop] ? item[prop] + '###' : ''); - }); - values.push(filterVal); - } - values.push(_idx); - if (incremental) { - updateRecord(tx, model, values, item.active); - } else if ( - OB.UTIL.isNullOrUndefined(item.active) || - (item.active && item.active === true) - ) { - tx.executeSql(insertStatement, values, null, function(tx, e) { - handleError(tx, e); - return true; - }); - } - _idx++; - }); - }, - error, - function() { - if (data.length > 0) { - OB.Cache.resetCacheForModel(model.prototype.modelName); - } - if (_.isFunction(success)) { - success(); - } - } - ); - }; - - /** - * Loads a set of models - * - * - */ - OB.Dal.loadModels = function( - online, - models, - data, - incremental, - callback, - background - ) { - var timestamp = 0; - var key; - - var modelsInLocalDb = []; - - function dalLoadModelsCallback() { - if (callback instanceof Function) { - callback(); - } - } - - function forceLocalDatabaseLoad(models, idx, callback) { - if (idx === models.length) { - if (callback) { - callback(); - } - return; - } - - OB.Dal.find( - models[idx], - {}, - function() { - forceLocalDatabaseLoad(models, idx + 1, callback); - }, - function() { - forceLocalDatabaseLoad(models, idx + 1, callback); - } - ); - } - - function triggerReady(models) { - if ( - incremental && - models._LoadQueue && - OB.UTIL.queueStatus(models._LoadQueue) && - OB.MobileApp.model.get('modelsToLoad').length === 0 - ) { - dalLoadModelsCallback(); - return; - } - if ( - OB.MobileApp.model.get('modelsToLoad').length === 0 && - OB.UTIL.queueStatus(models._LoadQueue || {}) - ) { - // this is only triggered when all models (online and offline) are loaded. - // offline models are loaded first but don't trigger this, it is not till - // windowModel is going to be rendered when online models are loaded and this - // is triggered. - if (!OB.MobileApp.model.get('datasourceLoadFailed')) { - forceLocalDatabaseLoad(modelsInLocalDb, 0, function() { - dalLoadModelsCallback(); - }); - } else { - dalLoadModelsCallback(); - } - } else { - dalLoadModelsCallback(); - } - } - - function buildLoadQueue() { - models._LoadQueue = models._LoadQueue || {}; - _.each(models, function(item) { - if (item && item.generatedModel) { - item = OB.Model[item.modelName]; - } - if ( - item && - ((online && item.prototype.online) || - (!online && !item.prototype.online)) && - !item.prototype.local && - (!item.prototype.remote || - (item.prototype.remote && - !OB.MobileApp.model.hasPermission(item.prototype.remote, true))) - ) { - models._LoadQueue[item.prototype.modelName] = false; - } - }); - } - - function processModelAtIndex(index) { - var ds, - load, - item = models[index]; - var removeLoadedModelsFromArray = function(modelName) { - var position = OB.MobileApp.model - .get('modelsToLoad') - .indexOf(modelName); - //var modelsList = ; - if (position !== -1) { - OB.MobileApp.model.get('modelsToLoad').splice(position, 1); - } - }; - - if (index === models.length) { - triggerReady(models); - return; - } - - if (item && item.generatedModel) { - item = OB.Model[item.modelName]; - } - load = - item && - ((online && item.prototype.online) || - (!online && !item.prototype.online)) && - (!item.prototype.remote || - (item.prototype.remote && - !OB.MobileApp.model.hasPermission(item.prototype.remote, true))); - //TODO: check permissions - if (load) { - models._failedModels = models._failedModels || []; - models._LoadQueue = models._LoadQueue || {}; - if (item.prototype.local) { - OB.Dal.initCache( - item, - [], - function() { - // OB.info('init success: ' + item.prototype.modelName); - processModelAtIndex(index + 1); - }, - function() { - OB.error('init error', arguments); - processModelAtIndex(index + 1); - } - ); - } else { - // OB.info('[sdrefresh] load model ' + item.prototype.modelName + ' ' + (incremental ? 'incrementally' : 'full')); - if ( - incremental && - OB.UTIL.localStorage.getItem( - 'lastUpdatedTimestamp' + item.prototype.modelName - ) - ) { - timestamp = OB.UTIL.localStorage.getItem( - 'lastUpdatedTimestamp' + item.prototype.modelName - ); - } - if (!item.prototype.online) { - modelsInLocalDb.push(item); - } - OB.UTIL.localStorage.removeItem( - 'recordsFromBackendFor' + item.prototype.modelName - ); - ds = new OB.DS.DataSource(new OB.DS.Request(item, timestamp)); - ds.on('ready', function(status) { - var finishTransaction = function() { - models._LoadQueue[item.prototype.modelName] = true; - if (item && item.prototype) { - removeLoadedModelsFromArray(item.prototype.modelName); - } - if (models._failedModels.length > 0) { - OB.MobileApp.model.set('datasourceLoadFailed', { - silent: true - }); - } - processModelAtIndex(index + 1); - }; - if (status === 'failed' || status === 'timeout') { - models._failedModels.push(item.prototype.modelName); - if (!incremental) { - finishTransaction(); - } - } else { - var logMsgForTransaction = function( - isSuccess, - modelName, - totalRecords - ) { - OB.debug( - isSuccess - ? '[sdreresh-' + - (incremental ? 'inc' : 'full') + - '] The model ' + - modelName + - ' has in local db ' + - totalRecords + - ' records' - : '[sdreresh-' + - (incremental ? 'inc' : 'full') + - '] There model ' + - modelName + - ' has an error getting the number of records from local db' - ); - if (data && online) { - data[modelName] = new Backbone.Collection(ds.cache); - } - }; - var checkRecordsWithBackend = function(modelName, totalRecords) { - // If the number of records in websql is not equal to the number of recrods sent by the server, an error is raised - // This shloud only be done during a full refresh - if (!incremental) { - if ( - totalRecords !== - parseInt( - OB.UTIL.localStorage.getItem( - 'recordsFromBackendFor' + modelName - ), - 10 - ) - ) { - models._failedModels.push(modelName); - } - } - }; - if (incremental) { - finishTransaction(); - } else { - OB.Data.localDB.transaction( - function(tx) { - tx.executeSql( - 'select count(1) as totalRecords from ' + - item.prototype.tableName, - [], - function(tx, result) { - logMsgForTransaction( - true, - item.prototype.modelName, - result.rows.item(0).totalRecords - ); - checkRecordsWithBackend( - item.prototype.modelName, - result.rows.item(0).totalRecords - ); - }, - function() { - logMsgForTransaction(false, item.prototype.modelName); - } - ); - }, - function(errorMsg) { - OB.error(errorMsg); - finishTransaction(); - }, - function() { - finishTransaction(); - } - ); - } - } - - // Skip load of models if it's a incremental refresh and the request timeout has been reached - if (incremental && (status === 'timeout' || status === 'failed')) { - dalLoadModelsCallback(); - return; - } - }); - - if (item.prototype.includeTerminalDate) { - var currentDate = new Date(); - item.params = item.params || {}; - item.params.terminalTime = currentDate; - item.params.terminalTimeOffset = currentDate.getTimezoneOffset(); - } - ds.load(item.params, incremental, background); - } - } else if ( - item && - item.prototype.remote && - OB.MobileApp.model.hasPermission(item.prototype.remote, true) - ) { - if (models._LoadQueue) { - models._LoadQueue[item.prototype.modelName] = true; - } - if (item && item.prototype) { - removeLoadedModelsFromArray(item.prototype.modelName); - } - processModelAtIndex(index + 1); - } else { - if (item && item.prototype) { - removeLoadedModelsFromArray(item.prototype.modelName); - } - processModelAtIndex(index + 1); - } - } - - models._LoadOnline = online; - - buildLoadQueue(); - - if (models.length === 0) { - triggerReady(models); - return; - } - - // Create an array of models to load to know when all the models are loaded - for (key in models._LoadQueue) { - if (Object.prototype.hasOwnProperty.call(models._LoadQueue, key)) { - if (OB.MobileApp.model.get('modelsToLoad').indexOf(key) === -1) { - OB.MobileApp.model.get('modelsToLoad').push(key); - } - } - } - - processModelAtIndex(0); - }; })(); diff --git a/web/org.openbravo.mobile.core/source/data/ob-datasource.js b/web/org.openbravo.mobile.core/source/data/ob-datasource.js index 2dc2e58e..e4aa2b15 100644 --- a/web/org.openbravo.mobile.core/source/data/ob-datasource.js +++ b/web/org.openbravo.mobile.core/source/data/ob-datasource.js @@ -7,7 +7,7 @@ ************************************************************************************ */ -/* global enyo, $ */ +/* global enyo */ (function() { OB.DS = window.OB.DS || {}; @@ -574,576 +574,4 @@ ); } }; - - function check(elem, filter) { - var p; - - for (p in filter) { - if (Object.prototype.hasOwnProperty.call(filter, p)) { - if (typeof filter[p] === 'object') { - return check(elem[p], filter[p]); - } else { - if (filter[p].substring(0, 2) === '%i') { - if (!new RegExp(filter[p].substring(2), 'i').test(elem[p])) { - return false; - } - } else if (filter[p].substring(0, 2) === '%') { - if (!new RegExp(filter[p].substring(2)).test(elem[p])) { - return false; - } - } else if (filter[p] !== elem[p]) { - return false; - } - } - } - } - return true; - } - - function findInData(data, filter) { - var i, max; - - if ($.isEmptyObject(filter)) { - return { - exception: 'filter not defined' - }; - } else { - for (i = 0, max = data.length; i < max; i++) { - if (check(data[i], filter)) { - return data[i]; - } - } - return null; - } - } - - function execInData(data, filter, filterfunction) { - var newdata, info, i, max, f, item; - - if ($.isEmptyObject(filter) && !filterfunction) { - return { - data: data.slice(0, OB.DS.MAXSIZE), - info: data.length > OB.DS.MAXSIZE ? 'OBMOBC_DataMaxReached' : null - }; - } else { - f = - filterfunction || - function(item) { - return item; - }; - newdata = []; - info = null; - for (i = 0, max = data.length; i < max; i++) { - if (check(data[i], filter)) { - item = f(data[i]); - if (item) { - if (newdata.length >= OB.DS.MAXSIZE) { - info = 'OBMOBC_DataMaxReached'; - break; - } - newdata.push(data[i]); - } - } - } - return { - data: newdata, - info: info - }; - } - } - - // DataSource objects - // OFFLINE GOES HERE - OB.DS.DataSource = function(request) { - this.request = request; - this.cache = null; - }; - _.extend(OB.DS.DataSource.prototype, Backbone.Events); - - OB.DS.DataSource.prototype.load = function(params, incremental, background) { - this.modelPagination = 1; - var me = this, - handleError, - handleIncrementalRequest, - dataLoaded = 0; - OB.UTIL.localStorage.setItem( - 'recordsFromBackendFor' + me.request.model.prototype.modelName, - 0 - ); - handleError = function() { - var msg = arguments[0] ? arguments[0].message : arguments; - OB.error( - 'Error in table ' + - me.request.model.prototype.modelName + - ' during initCache or insertData: ' + - msg - ); - - me.trigger('ready', 'failed'); - }; - - const doModelRequest = function(params, functionSave, errorCallback) { - var offset = params._offset; - var limit = params._limit; - if (offset === 0) { - OB.UTIL.localStorage.setItem( - 'requestTimestamp' + me.request.model.prototype.modelName, - new Date().getTime() - ); - OB.UTIL.showLoadingMessage( - OB.I18N.getLabel('OBMOBC_LoadingMessageModel', [ - me.request.model.prototype.modelName - ]) - ); - } else { - OB.UTIL.showLoadingMessage( - OB.I18N.getLabel('OBMOBC_LoadingMessageModelPage', [ - me.request.model.prototype.modelName, - offset / limit + 1 - ]) - ); - } - delete params._data; - delete params._model; - delete params._lastUpdated; - delete params._totalRows; - me.request.exec( - params, - function(data, message, lastUpdated, totalRows) { - var newLastId; - - function updateParamsForBackgroundRequestLogs(dataLoaded) { - let alreadyProccesedRecords = Number( - OB.UTIL.localStorage.getItem('totalRecordsBackgroundRequest') - ); - OB.UTIL.localStorage.setItem( - 'totalRecordsBackgroundRequest', - Number(alreadyProccesedRecords) + Number(dataLoaded) - ); - - let startingRequestModel = OB.UTIL.localStorage.getItem( - 'requestTimestamp' + me.request.model.prototype.modelName - ); - let executionTimeBackgroundRequest = - Number(new Date().getTime()) - Number(startingRequestModel); - let alreadyProccessTime = Number( - OB.UTIL.localStorage.getItem('totalTimeBackgroundRequest') - ); - let totalRequestTime = - Number(alreadyProccessTime) + - Number(executionTimeBackgroundRequest); - OB.UTIL.localStorage.setItem( - 'totalTimeBackgroundRequest', - totalRequestTime - ); - } - - function success() { - dataLoaded += data.length; - if (data.length >= limit) { - OB.debug( - '[sdreresh-' + - (incremental ? 'inc' : 'full') + - '] The model ' + - me.request.model.prototype.modelName + - ' has loaded from ' + - offset + - ' to ' + - (offset + limit + 1) + - ' with a ' + - data.length + - ' records in the pagination ' + - me.modelPagination - ); - me.modelPagination = me.modelPagination + 1; - newLastId = null; - if (me.request.model.prototype.paginationById) { - newLastId = - data[data.length - 1][me.request.model.getPrimaryKey().name]; - } - //remove the lastUpdated timestamp while the paged request is being processed to prevent half loaded models - OB.UTIL.localStorage.removeItem( - 'lastUpdatedTimestamp' + me.request.model.prototype.modelName - ); - OB.UTIL.localStorage.setItem( - 'recordsFromBackendFor' + me.request.model.prototype.modelName, - totalRows - ); - handleIncrementalRequest( - limit, - offset + limit, - params, - incremental, - newLastId, - background - ); - } else { - OB.UTIL.completeLoadingStep(); - OB.debug( - '[sdreresh-' + - (incremental ? 'inc' : 'full') + - '] The model ' + - me.request.model.prototype.modelName + - ' has loaded from ' + - offset + - ' to ' + - (offset + limit + 1) + - ' with a ' + - data.length + - ' records in the pagination ' + - me.modelPagination - ); - if (dataLoaded > 0) { - OB.info( - '[sdreresh-' + - (incremental ? 'inc' : 'full') + - '] The model ' + - me.request.model.prototype.modelName + - ' has finished loading with a total of ' + - dataLoaded + - ' records. ' + - (me.modelPagination === 1 - ? 'There was no pagination.' - : 'The number of paginations created were ' + - me.modelPagination) - ); - updateParamsForBackgroundRequestLogs(dataLoaded); - } - - if (background === undefined) { - OB.App.MasterdataController.updateModelLastUpdatedTimestamp( - me.request.model.prototype.modelName, - lastUpdated, - data, - totalRows - ); - } - - me.trigger('ready'); - } - } - - if (data.exception) { - OB.error('Error in datasource: ' + data.exception); - OB.DS.masterdataBackgroundModels = {}; - me.trigger('ready', 'failed'); - return; - } - if (me.request.model && me.request.model.prototype.online) { - me.cache = me.cache ? me.cache.concat(data) : data; - } - - params._data = data; - params._model = me.request.model; - params._lastUpdated = lastUpdated; - params._totalRows = totalRows; - functionSave(params, success, errorCallback); - }, - function(data) { - OB.UTIL.Debug.execute(function() { - if (data && data.exception && data.exception.message) { - OB.error( - 'OB.DS.DataSource.prototype.exec: ' + data.exception.message - ); - return; - } - }); - OB.DS.masterdataBackgroundModels = {}; - - OB.info( - OB.I18N.getLabel('OBMOBC_MasterdataRequestError') + - '. URL which failed: ' + - me.request.source - ); - OB.UTIL.showI18NWarning('OBMOBC_MasterdataRequestError'); - if ( - data && - data.exception && - data.exception.message && - data.exception.message === 'Application server is not available.' - ) { - me.trigger('ready', 'timeout'); - } else { - me.trigger('ready', 'failed'); - } - }, - true, - incremental - ? OB.RR.RequestRouter.getServiceByName( - me.request.source - ).getServiceTimeout(5000) - : OB.RR.RequestRouter.getServiceByName( - me.request.source - ).getServiceTimeout(5000) * 20 - ); - }; - - const updateParamsForBackgroundSaveLogs = function(modelName, dataLoaded) { - let alreadySavedRecords = OB.UTIL.localStorage.getItem( - 'totalRecordsBackgroundSave' - ); - let totalSavedRecords = Number(alreadySavedRecords) + Number(dataLoaded); - OB.UTIL.localStorage.setItem( - 'totalRecordsBackgroundSave', - totalSavedRecords - ); - - let alreadySaveTime = OB.UTIL.localStorage.getItem( - 'totalTimeBackgroundSave' - ); - let startingSaveModel = OB.UTIL.localStorage.getItem( - 'startSavingTimestamp' + modelName - ); - let executionTimeBackgroundSave = - Number(new Date().getTime()) - Number(startingSaveModel); - let totalSaveTime = - Number(alreadySaveTime) + Number(executionTimeBackgroundSave); - OB.UTIL.localStorage.setItem('totalTimeBackgroundSave', totalSaveTime); - }; - - const doModelDataSave = function(params, success, handleError) { - const offset = params._offset; - const data = params._data; - const model = params._model; - if (model && !model.prototype.online) { - OB.UTIL.localStorage.setItem( - 'startSavingTimestamp' + model.prototype.modelName, - new Date().getTime() - ); - if (offset === 0) { - OB.Dal.initCache( - model, - data, - function() { - updateParamsForBackgroundSaveLogs( - model.prototype.modelName, - data.length - ); - success(); - }, - handleError, - incremental - ); - } else { - OB.Dal.insertData( - model, - data, - function() { - updateParamsForBackgroundSaveLogs( - model.prototype.modelName, - data.length - ); - success(); - }, - handleError, - incremental, - dataLoaded - ); - } - } else { - success(); - } - }; - - const doModelDataSaveInRAM = function(params, success, handleError) { - const data = params._data; - const limit = params._limit; - const currentLength = data.length; - const backgroundLimit = OB.MobileApp.model.hasPermission( - 'OBMOBC_BackgroundMasterdataMaxSize', - true - ) - ? OB.MobileApp.model.hasPermission( - 'OBMOBC_BackgroundMasterdataMaxSize', - true - ) - : limit; - if ( - OB.DS.masterdataBackgroundModels['totalLength'] + currentLength > - backgroundLimit - ) { - OB.info( - 'Failed to do masterdata refresh in background because exceeds the limit of data. Trying normal refresh.' - ); - OB.UTIL.localStorage.setItem('neededForeGroundMasterDataRefresh'); - OB.UTIL.refreshMasterDataForeground(); - OB.DS.masterdataBackgroundModels = {}; - return; - } - if ( - !Object.prototype.hasOwnProperty.call( - OB.DS.masterdataBackgroundModels, - me.request.source - ) - ) { - OB.DS.masterdataBackgroundModels[me.request.source] = {}; - OB.DS.masterdataBackgroundModels[me.request.source]['data'] = []; - } - - OB.DS.masterdataBackgroundModels[me.request.source]['data'] = [ - ...OB.DS.masterdataBackgroundModels[me.request.source]['data'], - ...params._data - ]; - - OB.DS.masterdataBackgroundModels[me.request.source]['model'] = - params._model; - OB.DS.masterdataBackgroundModels[me.request.source]['lastUpdated'] = - params._lastUpdated; - OB.DS.masterdataBackgroundModels[me.request.source]['totalRows'] = - params._totalRows; - - OB.DS.masterdataBackgroundModels[me.request.source]['lastUpdated'] = - me.request.lastUpdated; - - if ( - !Object.prototype.hasOwnProperty.call( - OB.DS.masterdataBackgroundModels, - 'totalLength' - ) - ) { - OB.DS.masterdataBackgroundModels['totalLength'] = 0; - } - OB.DS.masterdataBackgroundModels['totalLength'] += currentLength; - success(); - }; - - const doModelReadFromRAM = function(params, functionSave, errorCallback) { - if ( - OB.DS.masterdataBackgroundModels[me.request.source]['data'].length === 0 - ) { - me.trigger('ready'); - return; - } - let parameters = {}; - parameters._data = - OB.DS.masterdataBackgroundModels[me.request.source]['data']; - parameters._model = - OB.DS.masterdataBackgroundModels[me.request.source]['model']; - const lastUpdated_ = - OB.DS.masterdataBackgroundModels[me.request.source]['lastUpdated']; - const totalRows = - OB.DS.masterdataBackgroundModels[me.request.source]['totalRows']; - parameters._offset = 0; // in background all the pages are concatenated into one - - const success = function() { - OB.info( - '[sdreresh-' + - (incremental ? 'inc' : 'full') + - '] The model ' + - me.request.model.prototype.modelName + - ' has finished saving in db with a total of ' + - parameters._data.length + - ' records. ' - ); - - OB.App.MasterdataController.updateModelLastUpdatedTimestamp( - me.request.model.prototype.modelName, - lastUpdated_, - parameters._data, - totalRows - ); - me.trigger('ready'); - }; - functionSave(parameters, success, errorCallback); - }; - - handleIncrementalRequest = function( - limit, - offset, - params, - incremental, - lastId, - background - ) { - params = params || {}; - params._limit = limit; - params._offset = offset; - params._count = OB.UTIL.localStorage.getItem( - 'recordsFromBackendFor' + me.request.model.prototype.modelName - ) - ? parseInt( - OB.UTIL.localStorage.getItem( - 'recordsFromBackendFor' + me.request.model.prototype.modelName - ), - 10 - ) - : 0; - params._isMasterdata = true; - params.overrideDefaultTimeout = true; - params.lastId = lastId; - params.incremental = incremental; - - if (background === undefined) { - // foreground - doModelRequest( - params, - function(params, successCallback, errorCallback) { - doModelDataSave(params, successCallback, errorCallback); - }, - handleError - ); - } else if (background === 'background-request') { - doModelRequest( - params, - function(params, successCallback, errorCallback) { - doModelDataSaveInRAM(params, successCallback, errorCallback); - }, - handleError - ); - } else if (background === 'background-save') { - doModelReadFromRAM( - params, - function(params, successCallback, errorCallback) { - doModelDataSave(params, successCallback, errorCallback); - }, - handleError - ); - } - }; - - this.cache = null; - var lastId = null; // First request don't have lastId - handleIncrementalRequest( - OB.MobileApp.model.hasPermission('OBMOBC_MasterdataBatchSize', true) - ? OB.DEC.abs( - OB.MobileApp.model.hasPermission('OBMOBC_MasterdataBatchSize', true) - ) - : 10000, - 0, - params, - incremental, - lastId, - background - ); - }; - - OB.DS.DataSource.prototype.find = function(filter, callback) { - if (this.cache) { - callback(findInData(this.cache, filter)); - } else { - this.on( - 'ready', - function() { - callback(findInData(this.cache, filter)); - }, - this - ); - } - }; - - OB.DS.DataSource.prototype.exec = function(filter, callback) { - if (this.cache) { - var result1 = execInData(this.cache, filter); - callback(result1.data, result1.info); - } else { - this.on( - 'ready', - function() { - var result2 = execInData(this.cache, filter); - callback(result2.data, result2.info); - }, - this - ); - } - }; })(); diff --git a/web/org.openbravo.mobile.core/source/data/ob-requestrouter.js b/web/org.openbravo.mobile.core/source/data/ob-requestrouter.js index 1ff5ac4a..722d3dd9 100644 --- a/web/org.openbravo.mobile.core/source/data/ob-requestrouter.js +++ b/web/org.openbravo.mobile.core/source/data/ob-requestrouter.js @@ -1,6 +1,6 @@ /* ************************************************************************************ - * Copyright (C) 2015-2020 Openbravo S.L.U. + * Copyright (C) 2015-2023 Openbravo S.L.U. * Licensed under the Openbravo Commercial License version 1.0 * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html * or in the legal folder of this module distribution. @@ -345,50 +345,41 @@ data: updatedMessageData, success: function(inSender, inResponse) { var callback = function() { - // message was successfull, remove it - OB.Dal.remove( - message, - function() { - OB.UTIL.ProcessController.finish( - 'messageSynchronization', - execution - ); + OB.UTIL.ProcessController.finish( + 'messageSynchronization', + execution + ); - // if the context has changed, lock the terminal - if ( - inResponse.response && - inResponse.response.contextInfo && - OB.MobileApp.model.get('context') - ) { - OB.UTIL.checkContextChange( - OB.MobileApp.model.get('context'), - inResponse.response.contextInfo, - function() { - if ( - pendingMessages.length === 0 && - OB.UTIL.sourceVersionFromResponse - ) { - OB.UTIL.checkSourceVersion( - OB.UTIL.sourceVersionFromResponse, - false, - true - ); - } - } - ); - } - //if the message model is a Polling model(has polling url) add it to the list - if (OB.PollingUtils.getPollingUrl(message)) { - OB.Polling.PollingRequestHandler.addPollingRequest(message); + // if the context has changed, lock the terminal + if ( + inResponse.response && + inResponse.response.contextInfo && + OB.MobileApp.model.get('context') + ) { + OB.UTIL.checkContextChange( + OB.MobileApp.model.get('context'), + inResponse.response.contextInfo, + function() { + if ( + pendingMessages.length === 0 && + OB.UTIL.sourceVersionFromResponse + ) { + OB.UTIL.checkSourceVersion( + OB.UTIL.sourceVersionFromResponse, + false, + true + ); + } } + ); + } + //if the message model is a Polling model(has polling url) add it to the list + if (OB.PollingUtils.getPollingUrl(message)) { + OB.Polling.PollingRequestHandler.addPollingRequest(message); + } - // process the remaining messages - me.processMessages(pendingMessages, fcallback, errorCallback); - }, - function(error) { - OB.error(arguments); - } - ); + // process the remaining messages + me.processMessages(pendingMessages, fcallback, errorCallback); }; if ( @@ -442,33 +433,20 @@ } }, fail: function(inSender, inResponse) { - // save the message in error status - message.set('status', 'failure'); - OB.Dal.save( - message, - function() { - OB.UTIL.ProcessController.finish( - 'messageSynchronization', - execution - ); - me.updateSyncIcon(); + OB.UTIL.ProcessController.finish('messageSynchronization', execution); + me.updateSyncIcon(); - // in multi server online/offline notification is based on presence of messages to sync - if ( - OB.MobileApp.model.get('connectedToERP') && - OB.RR.RequestRouter.isMultiServer() - ) { - OB.MobileApp.model.triggerOffLine(); - } + // in multi server online/offline notification is based on presence of messages to sync + if ( + OB.MobileApp.model.get('connectedToERP') && + OB.RR.RequestRouter.isMultiServer() + ) { + OB.MobileApp.model.triggerOffLine(); + } - if (errorCallback) { - errorCallback(); - } - }, - function() { - OB.error(arguments); - } - ); + if (errorCallback) { + errorCallback(); + } } }; }, diff --git a/web/org.openbravo.mobile.core/source/data/ob-windowmodel.js b/web/org.openbravo.mobile.core/source/data/ob-windowmodel.js index 0087eb48..37496c39 100644 --- a/web/org.openbravo.mobile.core/source/data/ob-windowmodel.js +++ b/web/org.openbravo.mobile.core/source/data/ob-windowmodel.js @@ -1,6 +1,6 @@ /* ************************************************************************************ - * Copyright (C) 2012-2020 Openbravo S.L.U. + * Copyright (C) 2012-2023 Openbravo S.L.U. * Licensed under the Openbravo Commercial License version 1.0 * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html * or in the legal folder of this module distribution. @@ -60,13 +60,7 @@ OB.Model.WindowModel = Backbone.Model.extend({ }); } - if (!OB.MobileApp.model.get('loggedOffline')) { - OB.Dal.loadModels(true, me.models, me.data, undefined, function() { - loadTheWindow(); - }); - } else { - loadTheWindow(); - } + loadTheWindow(); }, load: function() { @@ -84,21 +78,11 @@ OB.Model.WindowModel = Backbone.Model.extend({ _.extend(this.models, Backbone.Events); - if (!OB.MobileApp.model.get('loggedOffline')) { - OB.Dal.loadModels(true, me.models, me.data, undefined, function() { - initIfInit(); - me.trigger('windowReady'); - OB.MobileApp.view.currentWindowState = 'renderUI'; - OB.MobileApp.model.set('currentWindowState', 'renderUI'); - OB.MobileApp.model.set('isLoggingIn', false); - }); - } else { - initIfInit(); - this.trigger('windowReady'); - OB.MobileApp.view.currentWindowState = 'renderUI'; - OB.MobileApp.model.set('currentWindowState', 'renderUI'); - OB.MobileApp.model.set('isLoggingIn', false); - } + initIfInit(); + this.trigger('windowReady'); + OB.MobileApp.view.currentWindowState = 'renderUI'; + OB.MobileApp.model.set('currentWindowState', 'renderUI'); + OB.MobileApp.model.set('isLoggingIn', false); }, setAllOff: function(model) { diff --git a/web/org.openbravo.mobile.core/source/main.js b/web/org.openbravo.mobile.core/source/main.js index 59b4728f..38f2c0ee 100644 --- a/web/org.openbravo.mobile.core/source/main.js +++ b/web/org.openbravo.mobile.core/source/main.js @@ -46,9 +46,9 @@ /** * Global versions for mobile.core */ - // Add WebSQL database version for mobile.core + // Add database version for mobile.core OB.UTIL.VersionManagement.current.mobileCore = { - WebSQLDatabase: { + database: { name: 'OBMOBCDB', size: 50 * 1024 * 1024, displayName: 'Mobile DB' diff --git a/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js b/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js index b89e39f2..fa8dc756 100644 --- a/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js +++ b/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js @@ -1,6 +1,6 @@ /* ************************************************************************************ - * Copyright (C) 2012-2021 Openbravo S.L.U. + * Copyright (C) 2012-2023 Openbravo S.L.U. * Licensed under the Openbravo Commercial License version 1.0 * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html * or in the legal folder of this module distribution. @@ -111,10 +111,10 @@ OB.Model.Terminal = Backbone.Model.extend({ } }, localDB: { - size: OB.UTIL.VersionManagement.current.mobileCore.WebSQLDatabase.size, - name: OB.UTIL.VersionManagement.current.mobileCore.WebSQLDatabase.name, + size: OB.UTIL.VersionManagement.current.mobileCore.database.size, + name: OB.UTIL.VersionManagement.current.mobileCore.database.name, displayName: - OB.UTIL.VersionManagement.current.mobileCore.WebSQLDatabase.displayName + OB.UTIL.VersionManagement.current.mobileCore.database.displayName }, shouldExecuteBenchmark: false, propertiesLoaders: [], @@ -638,155 +638,22 @@ OB.Model.Terminal = Backbone.Model.extend({ }, openLocalDB: async function() { - if (OB.Data.localDB) { - OB.Data.localDB.transaction( - function() {}, - function() { - OB.Dal.openWebSQL(); - }, - null - ); - } else { - OB.Dal.openWebSQL(); - } - await OB.App.MasterdataController.openDatabase(); await OB.App.MessageModelController.openDatabase(); await OB.App.OfflineSessionController.openDatabase(); }, - initLocalDB: function() { - function dropTable(modelObj) { - return new Promise(function(resolve, reject) { - function dropTableFunction(modelObj) { - OB.Dal.dropTable( - modelObj, - function() { - var modelName = modelObj.prototype.modelName; - var modelChecksum = OB.Data.getModelStructureChecksum(modelObj); - //If this table belongs to a masterdata model, the masterdata needs to be fully loaded - if ( - OB.UTIL.localStorage.getItem('lastUpdatedTimestamp' + modelName) - ) { - OB.UTIL.localStorage.removeItem( - 'lastUpdatedTimestamp' + modelName - ); - OB.UTIL.localStorage.removeItem('POSLastTotalRefresh'); - OB.UTIL.localStorage.removeItem('POSLastIncRefresh'); - } - OB.Dal.initCache( - modelObj, - [], - function() { - //Set checksum after the model has been created to prevent inconsistent states (e.g. checksum set but missing model) - OB.debug( - 'Set model ' + modelName + ' checksum to ' + modelChecksum - ); - OB.UTIL.localStorage.setItem( - 'structureChecksum-' + modelName, - modelChecksum - ); - resolve(); - }, - function() { - OB.error("Couldn't initialize table for model: " + modelName); - resolve(); - } - ); - }, - function() { - OB.error(OB.UTIL.argumentsToStringifyed('dropTable', arguments)); - reject(); - } - ); - } - - var syncModel = OB.MobileApp.model.getSyncModel(modelObj); - if (syncModel) { - OB.MobileApp.model.syncModelHasData( - syncModel, - function() { - //Sync model has data. We will try to synchronize, and if we fail then the databaseCannotBeReset action will be executed - OB.MobileApp.model.syncAllModels(function() { - dropTableFunction(modelObj); - }, OB.MobileApp.model.databaseCannotBeResetAction); - }, - function() { - dropTableFunction(modelObj); - } - ); - } else { - dropTableFunction(modelObj); - } - }); - } - - function checkChangedInModels() { - var tablesToDrop = []; - _.each(OB.Model, function(model) { - if ( - !model.prototype || - !model.prototype.modelName || - model.prototype.legacyModel - ) { - return; - } - var modelName = model.prototype.modelName; - var modelChecksum = OB.Data.getModelStructureChecksum(model); - if (modelChecksum === '') { - return; - } - if ( - OB.UTIL.localStorage.getItem('structureChecksum-' + modelName) !== - modelChecksum - ) { - if (!OB.UTIL.localStorage.getItem('structureChecksum-' + modelName)) { - OB.debug( - "Model '" + - modelName + - "' should not exists because there isn't a paired entry in the localStorage. Performning preemptive table dropping..." - ); - } else { - OB.info("Model '" + modelName + "' changed. Rebuilding..."); - } - - tablesToDrop.push(dropTable(model)); - OB.MobileApp.model.get('modelsRebuilded').push(model); - } - }); - - OB.info('Checking database models...'); - - if (tablesToDrop.length === 0) { - OB.info('No models changed.'); - OB.MobileApp.model.loadTerminalInfo(); - return; - } - - Promise.all(tablesToDrop).then( - function() { - OB.MobileApp.model.loadTerminalInfo(); - }, - function() { - OB.MobileApp.model.loadingErrorsActions('initLocalDB.dropTalbles'); - } - ); - } + initLocalDB: async function() { + const finalCallback = () => { + OB.MobileApp.model.loadTerminalInfo(); + return; + }; // check if terminal id has changed if ( OB.UTIL.localStorage.getItem('loggedTerminalName') && OB.UTIL.localStorage.getItem('loggedTerminalName') !== OB.MobileApp.model.get('terminalName') ) { - OB.warn( - OB.UTIL.argumentsToStringifyed( - 'terminal changed (' + - OB.UTIL.localStorage.getItem('loggedTerminalName') + - ' -> ' + - OB.MobileApp.model.get('terminalName') + - ')' - ) - ); OB.info( 'Terminal has been changed. Resetting database and local storage information.' ); @@ -796,12 +663,24 @@ OB.Model.Terminal = Backbone.Model.extend({ OB.MobileApp.model.get('terminalName') ); OB.MobileApp.model.logout(); - return; }); - } else { - OB.MobileApp.model.set('modelsRebuilded', []); - checkChangedInModels(); + return; } + await OB.App.MasterdataController.openDatabase({ + checkModelChanges: + OB.MobileApp.model && OB.MobileApp.model.get('isLoggingIn'), + statusCallback: message => { + if (message.deleteDatabase) { + OB.UTIL.showLoadingMessage( + OB.I18N.getLabel('OBMOBC_DeleteLocalDatabase') + ); + } else if (message.openDatabase) { + finalCallback(); + } else { + finalCallback(); + } + } + }); }, /** @@ -1326,329 +1205,6 @@ OB.Model.Terminal = Backbone.Model.extend({ } return; } - - var modelObj = me.syncModelQueue.shift(); - var model = modelObj.model; - var criteria; - if (modelObj.getCriteria) { - criteria = modelObj.getCriteria(); - } else if (modelObj.criteria) { - criteria = modelObj.criteria; - } else { - criteria = { - hasBeenProcessed: 'Y' - }; - } - criteria._limit = -1; - OB.Dal.find( - model, - criteria, - function(dataToSync) { - me.skipSyncModel = dataToSync.length === 0; - - if (modelObj.preSendModel) { - // preSendModel is like a hook which can be used by custom code - // to influence the logic, for example setting me.skipSyncModel - modelObj.preSendModel(me, dataToSync); - } - - if (me.skipSyncModel) { - me.skipSyncModel = false; - me.syncModel(); - return; - } - - var className = modelObj.className; - - if (model === OB.Model.Order && OB.UTIL.processOrderClass) { - className = OB.UTIL.processOrderClass; - } - - var mdl, - modelIndex = 0, - modelNotFullySynced = false, - dataCorruption = false, - newDataToSync = new Backbone.Collection(); - while (modelIndex < dataToSync.length) { - mdl = dataToSync.at(modelIndex); - if ( - !_.isUndefined(mdl.get('json')) && - (_.isEmpty(mdl.get('json')) || _.isNull(mdl.get('json'))) - ) { - OB.error( - '[syncModel] Wrong model to Synchronize in backend: ' + - mdl.modelName + - ' because json column is undefined.' - ); - dataCorruption = true; - } else { - newDataToSync.add(dataToSync.at(modelIndex)); - } - - modelIndex++; - // partition the data in chunks - if (modelIndex >= 100 && modelIndex < dataToSync.length) { - modelNotFullySynced = true; - // add the model again to the beginning of the queue - me.syncModelQueue.unshift(modelObj); - break; - } - } - if (dataCorruption) { - var criteria = { - whereClause: ' WHERE json is null OR json= "" ' - }; - OB.Dal.removeAll(model, criteria); - } - - var dataToSend = []; - newDataToSync.each(function(record) { - if (record.get('json')) { - dataToSend.push(JSON.parse(record.get('json'))); - } else if (!_.isUndefined(record.get('objToSend'))) { - if (!_.isNull(record.get('objToSend'))) { - dataToSend.push(JSON.parse(record.get('objToSend'))); - } - } else { - dataToSend.push(record); - } - }); - - var timeout = modelObj.timeout || 20000; - var timePerRecord = modelObj.timePerRecord || 1000; - var data = { - messageId: OB.UTIL.get_UUID(), - modelName: modelObj.name, - data: dataToSend, - isSyncModel: true - }; - - // add an additional pre-sync action, remove any non-persistent data - // before really going to the server - if (OB.MobileApp.model.hasPermission('OBMOBC_SynchronizedMode', true)) { - newDataToSync.each(function(record) { - me.preSyncPromises.push( - new Promise(function(resolve, reject) { - if (!modelObj.isPersistent) { - OB.Dal.remove( - record, - function() { - resolve(); - }, - function(tx, err) { - OB.UTIL.showError(err); - reject(); - } - ); - } else { - resolve(); - } - }) - ); - }); - } - - var procErrorCallBack = function() { - // proc.exec mcallbackerror - OB.warn( - "Error while synchronizing model '" + - OB.Dal.getTableName(model) + - "'" - ); - - me.syncModelExecuteErrorCallbacks(); - }; - - var procSuccessCallBack = function( - data, - message, - lastUpdated, - endRow, - tx, - requestCallback - ) { - // error - if (data && data.exception) { - OB.warn( - "The model '" + - OB.Dal.getTableName(model) + - "'' has not been synchronized with the server" - ); - if ( - data.exception.invalidPermission && - !me.get('displayedInvalidPermission') - ) { - // invalid permission message only will be displayed once time - me.set('displayedInvalidPermission', true); - OB.UTIL.showConfirmation.display( - 'Info', - OB.I18N.getLabel('OBMOBC_NoPermissionToSyncModel', [ - OB.Dal.getTableName(model), - OB.Dal.getTableName(model) - ]), - [ - { - label: OB.I18N.getLabel('OBMOBC_LblOk'), - isConfirmButton: true, - action: function() {} - } - ] - ); - } - me.syncModelExecuteErrorCallbacks(); - return; - } - // success. Elements can be now deleted from the database - var removeSyncedElemsCallback = function(tx) { - OB.info("Purging the '" + OB.Dal.getTableName(model) + "' table"); - - var promises = []; - - if (modelObj.successSendModel) { - promises.push( - new Promise(function(resolve, reject) { - modelObj.successSendModel(); - resolve(); - }) - ); - } - - newDataToSync.each(function(record) { - promises.push( - new Promise(function(resolve, reject) { - if (modelObj.isPersistent) { - // Persistent model. Do not delete, just mark it as processed. - OB.Dal.updateRecordColumn( - record, - 'isbeingprocessed', - 'Y', - function() { - if (requestCallback) { - requestCallback(); - } - resolve(); - }, - function(tx, err) { - reject(); - }, - tx - ); - } else { - // no persistent model (Default). - OB.Dal.removeInTransaction( - tx, - record, - function() { - if (requestCallback) { - requestCallback(); - } - resolve(); - }, - function(tx, err) { - OB.UTIL.showError(err); - reject(); - } - ); - } - }) - ); - }); - - Promise.all(promises).then( - function() { - // if the model has been partitioned - if (modelNotFullySynced) { - OB.info( - newDataToSync.length + - " records of the table '" + - OB.Dal.getTableName(model) + - "' have been successfully synchronized with the server. " + - (dataToSync.length - newDataToSync.length) + - ' records remaining to be synchronized.' - ); - me.syncModel(); - return; - } - - OB.info( - "The table '" + - OB.Dal.getTableName(model) + - "' has been fully synchronized with the server" - ); - }, - function(err) { - OB.error( - "Could not purge the '" + - OB.Dal.getTableName(model) + - "' table. Error message: " + - err - ); - } - ); - // not synchronized mode do the next in the success callback - // with synchronized mode the recall syncmodel is below in the code - if ( - !OB.MobileApp.model.hasPermission('OBMOBC_SynchronizedMode', true) - ) { - me.syncModel(); - } - }; - if (modelObj.removeSyncedElemsCallback) { - modelObj.removeSyncedElemsCallback( - newDataToSync, - tx, - requestCallback - ); - } else { - removeSyncedElemsCallback(tx); - } - if (modelObj.postProcessingFunction) { - modelObj.postProcessingFunction( - newDataToSync, - removeSyncedElemsCallback - ); - } - }; - - if (OB.MobileApp.model.hasPermission('OBMOBC_SynchronizedMode', true)) { - me.collectSyncData( - className, - data, - timeout + timePerRecord * newDataToSync.length - ); - me.syncModelSuccessCallbacks.push(procSuccessCallBack); - me.syncModel(); - } else { - var proc = new OB.DS.Process(className); - //if the model of the message requires polling, add it to the list - var tmpMsg = OB.PollingUtils.createMessage(data, proc.source); - data.messageId = tmpMsg.id; - if (OB.PollingUtils.getPollingUrl(tmpMsg)) { - OB.Polling.PollingRequestHandler.planedToSendPollingRequest.add( - new OB.Model.PollingRequest({ - message: tmpMsg - }) - ); - } - proc.exec( - data, - procSuccessCallBack, - procErrorCallBack, - null, - timeout + timePerRecord * newDataToSync.length - ); - } - }, - - function() { - // there is no model in the local database. this is ok. move to the next model - me.syncModel(); - }, - { - // do not show an error when the table is not present in the local database because it could happen when the cache is still clean - doNotShowErrors: true - } - ); }, syncModelSuccessCallbacks: [], syncModelErrorCallbacks: [], @@ -1805,39 +1361,6 @@ OB.Model.Terminal = Backbone.Model.extend({ } return; } - // flow note: this line must be located before the queues are reset. Check models queue and callbacks queues, the process finishes when the callback are called - var isCurrentlySynchronizing = - (me.syncModelQueue && me.syncModelQueue.length > 0) || - (me.syncModelSuccessCallbacks && - me.syncModelSuccessCallbacks.length > 0) || - (me.syncModelErrorCallbacks && me.syncModelErrorCallbacks.length > 0); - // start the synchronization if it was not already in progress - if (!isCurrentlySynchronizing) { - me.syncModelSuccessCallbacks = []; - me.syncModelErrorCallbacks = []; - - // remember the callbacks in the callbacks queue - me.syncModelSuccessCallbacks.push(successCallback); - me.syncModelErrorCallbacks.push(errorCallback); - - // all models must restart the synchronization when syncAllModels is called. this is attained reseting the queue - me.syncModelQueue = []; - // add all the models to the queue - var i; - for (i = 0; i < this.get('dataSyncModels').length; i++) { - var modelObj = this.get('dataSyncModels')[i]; - me.syncModelQueue.push(modelObj); - } - - // reset some members used in synchronized comms - me.synchronizedData = []; - me.synchronizedTimeOut = 0; - - me.syncModel( - this.syncModelExecuteSuccessCallbacks, - this.syncModelExecuteErrorCallbacks - ); - } }, /** @@ -2329,16 +1852,7 @@ OB.Model.Terminal = Backbone.Model.extend({ windowName + (background ? '. (' + background + ' )' : '') ); - - OB.Dal.loadModels( - false, - datasources, - null, - incremental, - callback, - background - ); - + callback(); this.postLoadModels(); }, postLoadModels: function() {}, issue51841_21Q1_posterminal.diff [^] (9,384 bytes) 2023-06-29 16:59 [Show Content] [Hide Content] diff --git a/src/org/openbravo/retail/posterminal/OBPOSComponentProvider.java b/src/org/openbravo/retail/posterminal/OBPOSComponentProvider.java index 6f23ba704..dfab4c632 100644 --- a/src/org/openbravo/retail/posterminal/OBPOSComponentProvider.java +++ b/src/org/openbravo/retail/posterminal/OBPOSComponentProvider.java @@ -399,6 +399,7 @@ public class OBPOSComponentProvider extends BaseComponentProvider { businesslogic( "app/model/business-object/ticket-list/actions/MarkIgnoreCheckIfIsActiveToPendingTickets"), // businesslogic("app/model/business-object/ticket-list/actions/UpdateBPInAllTickets"), // + businesslogic("app/model/business-object/ticket-list/actions/DeleteTicket"), // businesslogic("app/model/business-object/ticket-list/actions/SaveTicket"), // // Synchronization Buffer diff --git a/web/org.openbravo.retail.posterminal/app/model/business-object/ticket-list/actions/DeleteTicket.js b/web/org.openbravo.retail.posterminal/app/model/business-object/ticket-list/actions/DeleteTicket.js new file mode 100644 index 000000000..d7e6a66f0 --- /dev/null +++ b/web/org.openbravo.retail.posterminal/app/model/business-object/ticket-list/actions/DeleteTicket.js @@ -0,0 +1,27 @@ +/* + ************************************************************************************ + * Copyright (C) 2023 Openbravo S.L.U. + * Licensed under the Openbravo Commercial License version 1.0 + * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html + * or in the legal folder of this module distribution. + ************************************************************************************ + */ + +/** + * @fileoverview Declares an action that delete the tickets from the state.TicketList + */ +OB.App.StateAPI.TicketList.registerAction( + 'deleteTicket', + (ticketList, payload) => { + const newTicketList = [...ticketList]; + payload.ticketIdList.forEach(ticketIdToDelete => { + const index = newTicketList.findIndex( + ticket => ticket.id === ticketIdToDelete + ); + if (index >= 0) { + newTicketList.splice(index, 1); + } + }); + return newTicketList; + } +); diff --git a/web/org.openbravo.retail.posterminal/js/components/modal-pay-open-tickets.js b/web/org.openbravo.retail.posterminal/js/components/modal-pay-open-tickets.js index 08840a2f6..a2d648490 100644 --- a/web/org.openbravo.retail.posterminal/js/components/modal-pay-open-tickets.js +++ b/web/org.openbravo.retail.posterminal/js/components/modal-pay-open-tickets.js @@ -410,6 +410,7 @@ enyo.kind({ j, wrongOrder, firstCheck = true, + currentTicket = OB.App.State.getState().Ticket, cancellingOrdersToCheck = OB.App.State.TicketList.Utils.getAllTickets(), showSomeOrderIsPaidPopup; diff --git a/web/org.openbravo.retail.posterminal/js/data/windowmodel.js b/web/org.openbravo.retail.posterminal/js/data/windowmodel.js index 5d9d7b994..9d36c569b 100644 --- a/web/org.openbravo.retail.posterminal/js/data/windowmodel.js +++ b/web/org.openbravo.retail.posterminal/js/data/windowmodel.js @@ -1,6 +1,6 @@ /* ************************************************************************************ - * Copyright (C) 2012-2020 Openbravo S.L.U. + * Copyright (C) 2012-2023 Openbravo S.L.U. * Licensed under the Openbravo Commercial License version 1.0 * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html * or in the legal folder of this module distribution. @@ -11,27 +11,16 @@ OB.Model.WindowModel = Backbone.Model.extend({ data: {}, load: function() { - var me = this; if (!this.models) { this.models = []; } _.extend(this.models, Backbone.Events); - if (!OB.MobileApp.model.get('loggedOffline')) { - OB.Dal.loadModels(true, this.models, this.data, undefined, function() { - if (me.init) { - me.init(); - } - me.trigger('ready'); - }); - } else { - if (this.init) { - this.init(); - } - this.trigger('ready'); + if (this.init) { + this.init(); } - //TODO: load offline models when registering window + this.trigger('ready'); }, setAllOff: function(model) { diff --git a/web/org.openbravo.retail.posterminal/js/login/model/login-model.js b/web/org.openbravo.retail.posterminal/js/login/model/login-model.js index 08f3f2235..7a6baa27d 100644 --- a/web/org.openbravo.retail.posterminal/js/login/model/login-model.js +++ b/web/org.openbravo.retail.posterminal/js/login/model/login-model.js @@ -68,13 +68,10 @@ }, // setting here the localDB, overrides the OB.MobileApp.model localDB default localDB: { - size: - OB.UTIL.VersionManagement.current.posterminal.WebSQLDatabase.size, - name: - OB.UTIL.VersionManagement.current.posterminal.WebSQLDatabase.name, + size: OB.UTIL.VersionManagement.current.posterminal.database.size, + name: OB.UTIL.VersionManagement.current.posterminal.database.name, displayName: - OB.UTIL.VersionManagement.current.posterminal.WebSQLDatabase - .displayName + OB.UTIL.VersionManagement.current.posterminal.database.displayName }, logDBTrxThreshold: 300, logDBStmtThreshold: 1000, diff --git a/web/org.openbravo.retail.posterminal/js/main.js b/web/org.openbravo.retail.posterminal/js/main.js index a68ad8b5c..deb8d8003 100644 --- a/web/org.openbravo.retail.posterminal/js/main.js +++ b/web/org.openbravo.retail.posterminal/js/main.js @@ -1,6 +1,6 @@ /* ************************************************************************************ - * Copyright (C) 2012-2020 Openbravo S.L.U. + * Copyright (C) 2012-2023 Openbravo S.L.U. * Licensed under the Openbravo Commercial License version 1.0 * You may obtain a copy of the License at http://www.openbravo.com/legal/obcl.html * or in the legal folder of this module distribution. @@ -42,9 +42,9 @@ /** * Global versions for WebPOS */ - // Add the current WebSQL database version for WebPOS + // Add the current database version for WebPOS OB.UTIL.VersionManagement.current.posterminal = { - WebSQLDatabase: { + database: { name: 'WEBPOS', size: 50 * 1024 * 1024, displayName: 'Openbravo Web POS' diff --git a/web/org.openbravo.retail.posterminal/js/utils/ticketListUtils.js b/web/org.openbravo.retail.posterminal/js/utils/ticketListUtils.js index cf65d72cd..43ed1d042 100644 --- a/web/org.openbravo.retail.posterminal/js/utils/ticketListUtils.js +++ b/web/org.openbravo.retail.posterminal/js/utils/ticketListUtils.js @@ -1107,29 +1107,28 @@ ).filter(ticket => ticket.hasbeenpaid === 'N'); if (ordersNotProcessed.length > 0) { - var existingOrder = _.find(ordersNotProcessed.models, function(order) { + const existingOrder = ordersNotProcessed.find(order => { return ( - order.get('id') === model.get('id') || - order.get('oldId') === model.get('id') || - (order.get('canceledorder') && - order.get('canceledorder').get('id') === model.get('id')) + order.id === model.get('id') || + order.oldId === model.get('id') || + (order.canceledorder && order.canceledorder.id === model.get('id')) ); }); if (existingOrder) { orderTypeMsg = OB.I18N.getLabel('OBPOS_ticket'); - if (existingOrder.get('isLayaway')) { + if (existingOrder.isLayaway) { orderTypeMsg = OB.I18N.getLabel('OBPOS_LblLayaway'); - } else if (existingOrder.get('isQuotation')) { + } else if (existingOrder.isQuotation) { orderTypeMsg = OB.I18N.getLabel('OBPOS_Quotation'); } // Getting Other Session User's username - OB.App.OfflineSession.sessionWithId(existingOrder.get('session')) + OB.App.OfflineSession.sessionWithId(existingOrder.session) .then(session => { if (!session) { return null; } - return OB.App.OfflineSession.withId(this.model.get('updatedBy')); + return OB.App.OfflineSession.withId(existingOrder.updatedBy); }) .then(user => { if (!user) { @@ -1139,7 +1138,7 @@ enyo.format( OB.I18N.getLabel('OBPOS_ticketAlreadyOpenedInSession'), orderTypeMsg, - existingOrder.get('documentNo'), + existingOrder.documentNo, user.name ), enyo.format( @@ -1150,14 +1149,11 @@ { label: OB.I18N.getLabel('OBMOBC_LblOk'), action: function() { - //replace for state action that removes ticket in ticketlist - OB.Dal.remove( - existingOrder, - function() { - callback(model); - }, - OB.UTIL.showError - ); + OB.App.State.TicketList.deleteTicket({ + ticketIdList: [existingOrder.id] + }).then(() => { + callback(model); + }); } }, { | |||||||
Relationships [ Relation Graph ] [ Dependency Graph ] | |||||||||||||||||||||||||||||
|
Notes | |
(0147933) marvintm (manager) 2023-03-24 09:11 |
This problem happens because WebSQL has been removed in non-secure contexts. We don't really have any control on this, but we are discussing internally if we should still keep the WebSQL infrastructure as we don't need it anymore for AWO, and chances of customers using it in external modules in an IndexedDB release don't seem to be very high. A decision on this topic will be made soon, and if the infrastructure is finally removed, then this error will no longer happen. However, this should not be taken as an indication that we want to support the execution of the application in non-secure contexts. Usage of the application in non-secure contexts is strongly discouraged, and should never be attempted in general. |
(0148119) sofidossant (developer) 2023-03-30 14:19 |
Any news? |
(0148156) guillermogil (manager) 2023-03-31 11:22 |
It will be needed to remove all the init WebSQL references in mobile.core (init database, init models, delete old tables, etc..), Ob-dal is not needed to be removed. We need to ensure there are no direct references to WebSQL API on POS Code |
(0148444) sofidossant (developer) 2023-04-13 16:46 |
Any news? |
(0149025) sofidossant (developer) 2023-04-27 16:27 |
Any news? |
(0149377) hgbot (developer) 2023-05-06 07:21 |
Merge Request created: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.servicesequence/-/merge_requests/2 [^] |
(0149416) hgbot (developer) 2023-05-08 07:54 |
Merge Request created: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.discounts.discountmatrixmanagement/-/merge_requests/9 [^] |
(0149711) sofidossant (developer) 2023-05-15 17:21 |
Any news? |
(0149917) hgbot (developer) 2023-05-18 08:52 |
Merge Request created: https://gitlab.com/openbravo/product/pmods/org.openbravo.mobile.core/-/merge_requests/523 [^] |
(0149918) hgbot (developer) 2023-05-18 08:52 |
Merge Request created: https://gitlab.com/openbravo/ci/modules/org.openbravo.retail.testsampledata/-/merge_requests/50 [^] |
(0149919) hgbot (developer) 2023-05-18 08:52 |
Merge Request created: https://gitlab.com/openbravo/ci/modules/org.openbravo.test.mobile.sampledata/-/merge_requests/77 [^] |
(0149920) hgbot (developer) 2023-05-18 08:52 |
Merge Request created: https://gitlab.com/openbravo/ci/mobile-test/-/merge_requests/292 [^] |
(0149921) hgbot (developer) 2023-05-18 08:52 |
Merge Request created: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.posterminal/-/merge_requests/1198 [^] |
(0149975) ranjith_qualiantech_com (developer) 2023-05-19 13:01 |
Merge Request created: https://gitlab.com/openbravo/ci/context_definitions/-/merge_requests/49 [^] |
(0151846) sofidossant (developer) 2023-06-29 14:12 |
Any news? |
(0151921) hgbot (developer) 2023-06-30 07:01 |
Merge Request created: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.trainingmode/-/merge_requests/15 [^] |
(0151951) hgbot (developer) 2023-06-30 12:11 |
Merge Request created: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.giftcards/-/merge_requests/250 [^] |
(0152146) sofidossant (developer) 2023-07-05 15:11 |
Any news? |
(0152230) hgbot (developer) 2023-07-10 09:51 |
Merge request merged: https://gitlab.com/openbravo/product/pmods/org.openbravo.mobile.core/-/merge_requests/523 [^] |
(0152231) hgbot (developer) 2023-07-10 09:51 |
Directly closing issue as related merge request is already approved. Repository: https://gitlab.com/openbravo/product/pmods/org.openbravo.mobile.core [^] Changeset: 511ed74e96e4a5ecfca661f1ca4bab6f92fe97ce Author: Ranjith S R <ranjith@qualiantech.com> Date: 10-07-2023 09:42:59 URL: https://gitlab.com/openbravo/product/pmods/org.openbravo.mobile.core/-/commit/511ed74e96e4a5ecfca661f1ca4bab6f92fe97ce [^] Fixed ISSUE-51841: Removed WebSQL Database initialize when loading POS * Removed unused DAL function --- M web/org.openbravo.mobile.core/source/data/ob-dal.js M web/org.openbravo.mobile.core/source/data/ob-datasource.js M web/org.openbravo.mobile.core/source/data/ob-requestrouter.js M web/org.openbravo.mobile.core/source/data/ob-windowmodel.js M web/org.openbravo.mobile.core/source/main.js M web/org.openbravo.mobile.core/source/model/ob-terminal-model.js --- |
(0152232) hgbot (developer) 2023-07-10 09:51 |
Repository: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.posterminal [^] Changeset: bf715451e1e01ab150e2122d73aecc0fe0d98720 Author: Ranjith S R <ranjith@qualiantech.com> Date: 10-07-2023 09:45:15 URL: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.posterminal/-/commit/bf715451e1e01ab150e2122d73aecc0fe0d98720 [^] Related to ISSUE-51841: Removed DAL loadModel reference --- A web/org.openbravo.retail.posterminal/app/model/business-object/ticket-list/actions/DeleteTicket.js M src/org/openbravo/retail/posterminal/OBPOSComponentProvider.java M web/org.openbravo.retail.posterminal/js/components/modal-pay-open-tickets.js M web/org.openbravo.retail.posterminal/js/data/windowmodel.js M web/org.openbravo.retail.posterminal/js/login/model/login-model.js M web/org.openbravo.retail.posterminal/js/main.js M web/org.openbravo.retail.posterminal/js/utils/ticketListUtils.js --- |
(0152233) hgbot (developer) 2023-07-10 09:51 |
Merge request merged: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.posterminal/-/merge_requests/1198 [^] |
(0152234) hgbot (developer) 2023-07-10 09:51 |
Merge request merged: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.discounts.discountmatrixmanagement/-/merge_requests/9 [^] |
(0152235) hgbot (developer) 2023-07-10 09:51 |
Repository: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.discounts.discountmatrixmanagement [^] Changeset: 7cfbcbcfa8d27698e49454aeb9beb314c06e0668 Author: Radhakrishnan Seeman <radhakrishnan@qualiantech.com> Date: 27-06-2023 11:53:01 URL: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.discounts.discountmatrixmanagement/-/commit/7cfbcbcfa8d27698e49454aeb9beb314c06e0668 [^] Related to ISSUE-51841: Added indexedDB support --- A web/org.openbravo.retail.discounts.discountmatrixmanagement/app/model/masterdata/RoleDiscountsModel.js M src/org/openbravo/retail/discounts/discountmatrixmanagement/DiscountsComponentProvider.java M src/org/openbravo/retail/discounts/discountmatrixmanagement/master/RoleDiscounts.java M web/org.openbravo.retail.discounts.discountmatrixmanagement/js/hookRoleDiscounts.js M web/org.openbravo.retail.discounts.discountmatrixmanagement/js/modelRoleDiscounts.js --- |
(0152236) hgbot (developer) 2023-07-10 09:51 |
Repository: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.trainingmode [^] Changeset: 8bb85b8be5c4263c679e0f29aecb2b1a46a8ef5c Author: Ranjith S R <ranjith@qualiantech.com> Date: 28-06-2023 13:36:46 URL: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.trainingmode/-/commit/8bb85b8be5c4263c679e0f29aecb2b1a46a8ef5c [^] Related to ISSUE-51841: Removed Unused DeleteOrder hook --- M src/org/openbravo/retail/trainingmode/OBRTMComponentProvider.java R web/org.openbravo.retail.trainingmode/js/predeleteorder.js --- |
(0152237) hgbot (developer) 2023-07-10 09:51 |
Merge request merged: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.trainingmode/-/merge_requests/15 [^] |
(0152238) hgbot (developer) 2023-07-10 09:51 |
Repository: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.servicesequence [^] Changeset: 1849e28fcdcae686834574642a671b6855f6a7e8 Author: Radhakrishnan Seeman <radhakrishnan@qualiantech.com> Date: 30-06-2023 10:30:45 URL: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.servicesequence/-/commit/1849e28fcdcae686834574642a671b6855f6a7e8 [^] Related to ISSUE-51841: Added indexedDB support --- A src/org/openbravo/retail/servicesequence/master/ServiceSequence.java A web/org.openbravo.retail.servicesequence/app/model/masterdata/ServiceSequenceModel.js A web/org.openbravo.retail.servicesequence/app/model/masterdata/SynchronizeServiceSequence.js M src/org/openbravo/retail/servicesequence/OBRETSSComponentProvider.java M src/org/openbravo/retail/servicesequence/master/OBRETSSSequenceProperties.java M web/org.openbravo.retail.servicesequence/js/model/sequenceModel.js M web/org.openbravo.retail.servicesequence/js/preOrderSaveHook.js R web/org.openbravo.retail.servicesequence/js/model/obretssDataSyncModel.js --- |
(0152239) hgbot (developer) 2023-07-10 09:51 |
Merge request merged: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.servicesequence/-/merge_requests/2 [^] |
(0152240) hgbot (developer) 2023-07-10 09:52 |
Merge request merged: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.giftcards/-/merge_requests/250 [^] |
(0152241) hgbot (developer) 2023-07-10 09:52 |
Repository: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.giftcards [^] Changeset: f70f4ff988ac9e6a1f9e7b9bf0f960db5bd29702 Author: Ranjith S R <ranjith@qualiantech.com> Date: 10-07-2023 08:22:20 URL: https://gitlab.com/openbravo/product/pmods/org.openbravo.retail.giftcards/-/commit/f70f4ff988ac9e6a1f9e7b9bf0f960db5bd29702 [^] Related to ISSUE-51841: MultiOrder payment should be validated in GiftCertificate popup --- M web/org.openbravo.retail.giftcards/js/components/GiftCardDetails.js --- |
(0152242) hgbot (developer) 2023-07-10 09:52 |
Repository: https://gitlab.com/openbravo/ci/mobile-test [^] Changeset: b9f841b58f776c6f565e6e6392a218df82b75f95 Author: Ranjith S R <ranjith@qualiantech.com> Date: 10-07-2023 09:47:31 URL: https://gitlab.com/openbravo/ci/mobile-test/-/commit/b9f841b58f776c6f565e6e6392a218df82b75f95 [^] Related to ISSUE-51841: Updated test TerminalUpdateTestMasterdataChange --- M src-test/org/openbravo/test/mobile/retail/pack/selenium/tests/loginout/TerminalUpdateTestMasterdataChange.java M src-test/org/openbravo/test/mobile/retail/pack/selenium/tests/system/I35778_VerifyPayOpenTicketPayments.java --- |
(0152243) hgbot (developer) 2023-07-10 09:52 |
Merge request merged: https://gitlab.com/openbravo/ci/mobile-test/-/merge_requests/292 [^] |
(0152244) hgbot (developer) 2023-07-10 09:59 |
Repository: https://gitlab.com/openbravo/ci/modules/org.openbravo.test.mobile.sampledata [^] Changeset: 60e81ba7adfeebd03ef3e404173172367692ee0b Author: Ranjith S R <ranjith@qualiantech.com> Date: 02-07-2023 12:42:44 URL: https://gitlab.com/openbravo/ci/modules/org.openbravo.test.mobile.sampledata/-/commit/60e81ba7adfeebd03ef3e404173172367692ee0b [^] Related to ISSUE-51841: Removed sampledata for unused loyalty module --- M referencedata/sampledata/The_White_Valley_Group/AD_PROCESS_ACCESS.xml M referencedata/sampledata/The_White_Valley_Group/AD_WINDOW_ACCESS.xml M referencedata/sampledata/The_White_Valley_Group/OBPOS_APP_PAYMENT_TYPE.xml --- |
(0152245) hgbot (developer) 2023-07-10 09:59 |
Merge request merged: https://gitlab.com/openbravo/ci/modules/org.openbravo.test.mobile.sampledata/-/merge_requests/77 [^] |
(0152246) hgbot (developer) 2023-07-10 09:59 |
Merge request merged: https://gitlab.com/openbravo/ci/modules/org.openbravo.retail.testsampledata/-/merge_requests/50 [^] |
(0152247) hgbot (developer) 2023-07-10 09:59 |
Repository: https://gitlab.com/openbravo/ci/modules/org.openbravo.retail.testsampledata [^] Changeset: 24ea8cfcd13546d8b36c9989d7b2ef303d9dfb28 Author: Ranjith S R <ranjith@qualiantech.com> Date: 02-07-2023 12:42:36 URL: https://gitlab.com/openbravo/ci/modules/org.openbravo.retail.testsampledata/-/commit/24ea8cfcd13546d8b36c9989d7b2ef303d9dfb28 [^] Related to ISSUE-51841: Removed sampledata for unused loyalty module --- M referencedata/sampledata/Retail_Test/AD_PROCESS_ACCESS.xml M referencedata/sampledata/Retail_Test/AD_WINDOW_ACCESS.xml M referencedata/sampledata/Retail_Test/OBPOS_APP_PAYMENT_TYPE.xml --- |
(0152265) ranjith_qualiantech_com (developer) 2023-07-10 11:10 |
Reopening issue for creating backports |
Issue History | |||
Date Modified | Username | Field | Change |
2023-03-13 12:33 | sofidossant | New Issue | |
2023-03-13 12:33 | sofidossant | Assigned To | => Retail |
2023-03-13 12:33 | sofidossant | File Added: image.png | |
2023-03-13 12:33 | sofidossant | Triggers an Emergency Pack | => No |
2023-03-13 12:33 | sofidossant | Priority | urgent => high |
2023-03-13 13:15 | Practics | Issue Monitored: Practics | |
2023-03-24 09:11 | marvintm | Note Added: 0147933 | |
2023-03-30 14:19 | sofidossant | Note Added: 0148119 | |
2023-03-31 11:22 | guillermogil | Note Added: 0148156 | |
2023-03-31 11:31 | radhakrishnan | Assigned To | Retail => radhakrishnan |
2023-03-31 11:32 | radhakrishnan | Status | new => scheduled |
2023-04-13 16:46 | sofidossant | Note Added: 0148444 | |
2023-04-27 16:27 | sofidossant | Note Added: 0149025 | |
2023-05-06 07:21 | hgbot | Note Added: 0149377 | |
2023-05-08 07:54 | hgbot | Note Added: 0149416 | |
2023-05-10 08:52 | ranjith_qualiantech_com | Assigned To | radhakrishnan => ranjith_qualiantech_com |
2023-05-15 08:28 | marvintm | Severity | critical => major |
2023-05-15 17:21 | sofidossant | Note Added: 0149711 | |
2023-05-18 08:52 | hgbot | Note Added: 0149917 | |
2023-05-18 08:52 | hgbot | Note Added: 0149918 | |
2023-05-18 08:52 | hgbot | Note Added: 0149919 | |
2023-05-18 08:52 | hgbot | Note Added: 0149920 | |
2023-05-18 08:52 | hgbot | Note Added: 0149921 | |
2023-05-19 13:01 | ranjith_qualiantech_com | Note Added: 0149975 | |
2023-06-29 14:02 | migueldejuana | File Added: issue51841_20Q4_core.diff | |
2023-06-29 14:02 | migueldejuana | File Added: issue51841_20Q4_posterminal.diff | |
2023-06-29 14:12 | sofidossant | Note Added: 0151846 | |
2023-06-29 16:36 | migueldejuana | File Deleted: issue51841_20Q4_core.diff | |
2023-06-29 16:36 | migueldejuana | File Added: issue51841_20Q4_core.diff | |
2023-06-29 16:59 | migueldejuana | File Added: issue51841_21Q1_core.diff | |
2023-06-29 16:59 | migueldejuana | File Added: issue51841_21Q1_posterminal.diff | |
2023-06-30 07:01 | hgbot | Note Added: 0151921 | |
2023-06-30 12:11 | hgbot | Note Added: 0151951 | |
2023-07-05 15:11 | sofidossant | Note Added: 0152146 | |
2023-07-10 09:51 | hgbot | Note Added: 0152230 | |
2023-07-10 09:51 | hgbot | Resolution | open => fixed |
2023-07-10 09:51 | hgbot | Status | scheduled => closed |
2023-07-10 09:51 | hgbot | Fixed in Version | => RR23Q4 |
2023-07-10 09:51 | hgbot | Note Added: 0152231 | |
2023-07-10 09:51 | hgbot | Note Added: 0152232 | |
2023-07-10 09:51 | hgbot | Note Added: 0152233 | |
2023-07-10 09:51 | hgbot | Note Added: 0152234 | |
2023-07-10 09:51 | hgbot | Note Added: 0152235 | |
2023-07-10 09:51 | hgbot | Note Added: 0152236 | |
2023-07-10 09:51 | hgbot | Note Added: 0152237 | |
2023-07-10 09:51 | hgbot | Note Added: 0152238 | |
2023-07-10 09:51 | hgbot | Note Added: 0152239 | |
2023-07-10 09:52 | hgbot | Note Added: 0152240 | |
2023-07-10 09:52 | hgbot | Note Added: 0152241 | |
2023-07-10 09:52 | hgbot | Note Added: 0152242 | |
2023-07-10 09:52 | hgbot | Note Added: 0152243 | |
2023-07-10 09:59 | hgbot | Note Added: 0152244 | |
2023-07-10 09:59 | hgbot | Note Added: 0152245 | |
2023-07-10 09:59 | hgbot | Note Added: 0152246 | |
2023-07-10 09:59 | hgbot | Note Added: 0152247 | |
2023-07-10 11:10 | ranjith_qualiantech_com | Note Added: 0152265 | |
2023-07-10 11:10 | ranjith_qualiantech_com | Status | closed => new |
2023-07-10 11:10 | ranjith_qualiantech_com | Resolution | fixed => open |
2023-07-10 11:10 | ranjith_qualiantech_com | Fixed in Version | RR23Q4 => |
2023-07-10 11:10 | ranjith_qualiantech_com | Status | new => scheduled |
2023-07-10 11:11 | ranjith_qualiantech_com | Status | scheduled => closed |
2023-07-10 11:11 | ranjith_qualiantech_com | Resolution | open => no change required |
2024-02-21 14:12 | ranjith_qualiantech_com | Relationship added | related to 0054593 |
2024-02-23 07:29 | ranjith_qualiantech_com | Relationship deleted | related to 0054593 |
2024-02-23 07:30 | ranjith_qualiantech_com | Relationship added | causes 0054593 |
Copyright © 2000 - 2009 MantisBT Group |