From 6439dcb2fa43fee4a802206fb4264f9fc81f7604 Mon Sep 17 00:00:00 2001 From: Edwin Betancourt Date: Sat, 27 Feb 2021 12:24:11 -0400 Subject: [PATCH] feat: Refactor window control vuex module. (#611) Co-authored-by: EdwinBetanc0urt --- src/store/modules/ADempiere/window.js | 1137 ----------------- .../ADempiere/windowControl/actions.js | 1080 ++++++++++++++++ .../ADempiere/windowControl/getters.js | 37 + .../modules/ADempiere/windowControl/index.js | 19 + .../ADempiere/windowControl/mutations.js | 48 + .../modules/ADempiere/windowControl/state.js | 20 + 6 files changed, 1204 insertions(+), 1137 deletions(-) delete mode 100644 src/store/modules/ADempiere/window.js create mode 100644 src/store/modules/ADempiere/windowControl/actions.js create mode 100644 src/store/modules/ADempiere/windowControl/getters.js create mode 100644 src/store/modules/ADempiere/windowControl/index.js create mode 100644 src/store/modules/ADempiere/windowControl/mutations.js create mode 100644 src/store/modules/ADempiere/windowControl/state.js diff --git a/src/store/modules/ADempiere/window.js b/src/store/modules/ADempiere/window.js deleted file mode 100644 index 5c3dec4f..00000000 --- a/src/store/modules/ADempiere/window.js +++ /dev/null @@ -1,1137 +0,0 @@ -import { - requestCreateEntity, - requestUpdateEntity, - requestDeleteEntity, - rollbackEntity -} from '@/api/ADempiere/persistence' -import { requestReferencesList } from '@/api/ADempiere/values' -import { isEmptyValue, typeValue } from '@/utils/ADempiere/valueUtils.js' -import { fieldIsDisplayed } from '@/utils/ADempiere/dictionaryUtils' -import { parseContext } from '@/utils/ADempiere/contextUtils' -import { showMessage } from '@/utils/ADempiere/notification' -import language from '@/lang' -import router from '@/router' -import { convertObjectToKeyValue } from '@/utils/ADempiere/valueFormat.js' - -const initStateWindowControl = { - inCreate: [], - references: [], - currentRecord: {}, - windowOldRoute: { - path: '', - fullPath: '', - query: {} - }, - dataLog: {}, // { containerUuid, recordId, tableName, eventType } - tabSequenceRecord: [], - totalResponse: 0, - totalRequest: 0 -} - -const windowControl = { - state: initStateWindowControl, - mutations: { - setCurrentRecord(state, payload) { - state.currentRecord = payload - }, - addInCreate(state, payload) { - state.inCreate.push(payload) - }, - deleteInCreate(state, payload) { - state.inCreate = state.inCreate.filter(item => item.containerUuid !== payload.containerUuid) - }, - addReferencesList(state, payload) { - state.references.push(payload) - }, - setDataLog(state, payload) { - state.dataLog = payload - }, - setWindowOldRoute(state, payload) { - state.windowOldRoute = payload - }, - setTabSequenceRecord(state, payload) { - state.tabSequenceRecord = payload - }, - setTotalResponse(state, payload) { - state.totalResponse = payload - }, - setTotalRequest(state, payload) { - state.totalRequest = payload - }, - resetStateWindowControl(state) { - state = initStateWindowControl - } - }, - actions: { - tableActionPerformed({ dispatch, getters }, { - field, - value - }) { - if (fieldIsDisplayed(field) && field.isShowedFromUser) { - // change action to advanced query on field value is changed in this panel - if (router.currentRoute.query.action !== 'advancedQuery') { - router.push({ - query: { - ...router.currentRoute.query, - action: 'advancedQuery' - } - }, () => {}) - } - const { parentUuid, containerUuid, tabTableName, tabQuery, tabWhereClause } = field - let parsedQuery = tabQuery - if (!isEmptyValue(parsedQuery) && parsedQuery.includes('@')) { - parsedQuery = parseContext({ - parentUuid, - containerUuid, - value: tabQuery, - isBooleanToString: true - }).value - } - - let parsedWhereClause = tabWhereClause - if (!isEmptyValue(parsedWhereClause) && parsedWhereClause.includes('@')) { - parsedWhereClause = parseContext({ - parentUuid, - containerUuid, - value: tabWhereClause, - isBooleanToString: true - }).value - } - - const conditionsList = getters.getParametersToServer({ - containerUuid, - isEvaluateMandatory: false - }) - - dispatch('getObjectListFromCriteria', { - parentUuid, - containerUuid, - tableName: tabTableName, - query: parsedQuery, - whereClause: parsedWhereClause, - conditionsList - }) - .catch(error => { - console.warn('Error getting Advanced Query (notifyFieldChange):', error.message + '. Code: ', error.code) - }) - } - }, - windowActionPerformed({ dispatch, getters }, { - field, - value - }) { - const { parentUuid, containerUuid, columnName } = field - // get value from store - if (isEmptyValue(value)) { - value = getters.getValueOfField({ - parentUuid, - containerUuid, - columnName - }) - } - return new Promise((resolve, reject) => { - // request callouts - dispatch('runCallout', { - parentUuid, - containerUuid, - tableName: field.tableName, - columnName, - callout: field.callout, - oldValue: field.oldValue, - valueType: field.valueType, - value - }) - .then(() => { - // Context Info - dispatch('reloadContextInfo', { - field - }) - // Apply actions for server - dispatch('runServerAction', { - field, - value - }) - .then(response => resolve(response)) - .catch(error => reject(error)) - }) - }) - }, - runServerAction({ dispatch, getters, commit }, { - field, - value - }) { - return new Promise((resolve, reject) => { - // For change options - if (fieldIsDisplayed(field)) { - commit('addChangeToPersistenceQueue', { - ...field, - value - }) - const emptyFields = getters.getFieldsListEmptyMandatory({ - containerUuid: field.containerUuid - }) - if (!isEmptyValue(emptyFields)) { - showMessage({ - message: language.t('notifications.mandatoryFieldMissing') + emptyFields, - type: 'info' - }) - } else { - const recordUuid = getters.getUuidOfContainer(field.containerUuid) - dispatch('flushPersistenceQueue', { - containerUuid: field.containerUuid, - tableName: field.tableName, - recordUuid - }) - .then(response => { - resolve(response) - if (isEmptyValue(recordUuid)) { - const oldRoute = router.app._route - router.push({ - name: oldRoute.name, - params: { - ...oldRoute.params - }, - query: { - ...oldRoute.query, - action: response.uuid - } - }, () => {}) - } - }) - .catch(error => reject(error)) - } - } - }) - }, - reloadContextInfo({ dispatch, getters }, { - field - }) { - // get value from store - const value = getters.getValueOfField({ - parentUuid: field.parentUuid, - containerUuid: field.containerUuid, - columnName: field.columnName - }) - // request context info field - if (!isEmptyValue(value) && !isEmptyValue(field.contextInfo) && !isEmptyValue(field.contextInfo.sqlStatement)) { - let isSQL = false - let sqlStatement = field.contextInfo.sqlStatement - if (sqlStatement.includes('@')) { - if (sqlStatement.includes('@SQL=')) { - isSQL = true - } - sqlStatement = parseContext({ - parentUuid: field.parentUuid, - containerUuid: field.containerUuid, - columnName: field.columnName, - value: sqlStatement, - isSQL - }).value - if (isSQL && typeValue(sqlStatement) === 'OBJECT') { - sqlStatement = sqlStatement.query - } - } - const contextInfo = dispatch('getContextInfoValueFromServer', { - parentUuid: field.parentUuid, - containerUuid: field.containerUuid, - contextInfoId: field.contextInfo.id, - contextInfoUuid: field.contextInfo.uuid, - columnName: field.columnName, - sqlStatement - }) - if (!isEmptyValue(contextInfo) && !isEmptyValue(contextInfo.messageText)) { - field.contextInfo.isActive = true - field.contextInfo.messageText.msgText = contextInfo.messageText - field.contextInfo.messageText.msgTip = contextInfo.messageTip - } - } - }, - undoPanelToNew({ dispatch, rootGetters }, { containerUuid }) { - const oldAttributes = rootGetters.getColumnNamesAndValues({ - containerUuid, - propertyName: 'oldValue', - isObjectReturn: true, - isAddDisplayColumn: true - }) - dispatch('notifyPanelChange', { - containerUuid, - newValues: oldAttributes - }) - }, - // createNewEntity({ commit, dispatch, getters, rootGetters }, { - // parentUuid, - // containerUuid - // }) { - // return new Promise((resolve, reject) => { - // // exists some call to create new record with container uuid - // if (getters.getInCreate(containerUuid)) { - // return reject({ - // error: 0, - // message: `In this panel (${containerUuid}) is a create new record in progress` - // }) - // } - // - // const { tableName, fieldsList } = rootGetters.getPanel(containerUuid) - // // delete key from attributes - // const attributesList = rootGetters.getColumnNamesAndValues({ - // containerUuid, - // propertyName: 'value', - // isEvaluateValues: true, - // isAddDisplayColumn: false - // }) - // commit('addInCreate', { - // containerUuid, - // tableName, - // attributesList - // }) - // requestCreateEntity({ - // tableName, - // attributesList - // }) - // .then(createEntityResponse => { - // const newValues = createEntityResponse.values - // attributesList.forEach(element => { - // if (element.columnName.includes('DisplayColumn')) { - // newValues[element.columnName] = element.value - // } - // }) - // - // showMessage({ - // message: language.t('data.createRecordSuccessful'), - // type: 'success' - // }) - // - // // update fields with new values - // dispatch('notifyPanelChange', { - // parentUuid, - // containerUuid, - // newValues, - // isSendToServer: false - // }) - // dispatch('addNewRow', { - // parentUuid, - // containerUuid, - // isPanelValues: true, - // isEdit: false - // }) - // - // // set data log to undo action - // const fieldId = fieldsList.find(itemField => itemField.isKey) - // dispatch('setDataLog', { - // containerUuid, - // tableName, - // recordId: fieldId.value, // TODO: Verify performance with tableName_ID - // recordUuid: newValues.UUID, - // eventType: 'INSERT' - // }) - // - // const oldRoute = router.app._route - // router.push({ - // name: oldRoute.name, - // params: { - // ...oldRoute.params - // }, - // query: { - // ...oldRoute.query, - // action: createEntityResponse.uuid - // } - // }) - // dispatch('tagsView/delView', oldRoute, true) - // - // resolve({ - // data: newValues, - // recordUuid: createEntityResponse.uuid, - // recordId: createEntityResponse.id, - // tableName: createEntityResponse.tableName - // }) - // }) - // .catch(error => { - // showMessage({ - // message: error.message, - // type: 'error' - // }) - // console.warn(`Create Entity error: ${error.message}.`) - // reject(error) - // }) - // .finally(() => { - // commit('deleteInCreate', { - // containerUuid, - // tableName, - // attributesList - // }) - // }) - // }) - // }, - createEntityFromTable({ commit, dispatch, getters, rootGetters }, { - parentUuid, - containerUuid, - row - }) { - // exists some call to create new record with container uuid - if (getters.getInCreate(containerUuid)) { - return { - error: 0, - message: `In this panel (${containerUuid}) is a create new record in progress.` - } - } - const { tableName, isParentTab } = rootGetters.getPanel(containerUuid) - - // TODO: Add support to Binary columns (BinaryData) - const columnsToDontSend = ['BinaryData', 'isEdit', 'isNew', 'isSendServer'] - - // TODO: Evaluate peformance without filter using delete(prop) before convert object to array - // attributes or fields - const fieldsList = getters.getFieldsListFromPanel(containerUuid) - const attributesList = [] - fieldsList.forEach(itemAttribute => { - if (columnsToDontSend.includes(itemAttribute.columnName) || itemAttribute.columnName.includes('DisplayColumn')) { - return false - } - if (isEmptyValue(row[itemAttribute.columnName])) { - return false - } - - attributesList.push({ - value: row[itemAttribute.columnName], - columnName: itemAttribute.columnName, - valueType: itemAttribute.valueType - }) - }) - - commit('addInCreate', { - containerUuid, - tableName, - attributesList - }) - - let isError = false - return requestCreateEntity({ - tableName, - attributesList - }) - .then(createEntityResponse => { - showMessage({ - message: language.t('data.createRecordSuccessful'), - type: 'success' - }) - if (isParentTab) { - // redirect to create new record - const oldRoute = router.app._route - router.push({ - name: oldRoute.name, - params: { - ...oldRoute.params - }, - query: { - ...oldRoute.query, - action: createEntityResponse.recordUuid - } - }, () => {}) - } - return { - data: createEntityResponse.values, - ...createEntityResponse - } - }) - .catch(error => { - showMessage({ - message: error.message, - type: 'error' - }) - console.warn(`Create Entity Table Error ${error.code}: ${error.message}.`) - isError = true - }) - .finally(() => { - if (isError) { - dispatch('addNewRow', { - containerUuid, - row - }) - } else { - // refresh record list - dispatch('getDataListTab', { - parentUuid, - containerUuid - }) - .catch(error => { - console.warn(`Error getting data list tab. Message: ${error.message}, code ${error.code}.`) - }) - } - commit('deleteInCreate', { - containerUuid, - tableName, - attributesList - }) - }) - }, - // updateCurrentEntity({ dispatch, rootGetters }, { - // containerUuid, - // recordUuid = null - // }) { - // const panel = rootGetters.getPanel(containerUuid) - // if (!recordUuid) { - // recordUuid = rootGetters.getUuidOfContainer(containerUuid) - // } - // - // // TODO: Add support to Binary columns (BinaryData) - // const columnsToDontSend = ['Account_Acct'] - // - // // attributes or fields - // let finalAttributes = rootGetters.getColumnNamesAndValues({ - // containerUuid: containerUuid, - // isEvaluatedChangedValue: true - // }) - // - // finalAttributes = finalAttributes.filter(itemAttribute => { - // if (columnsToDontSend.includes(itemAttribute.columnName) || itemAttribute.columnName.includes('DisplayColumn')) { - // return false - // } - // const field = panel.fieldsList.find(itemField => itemField.columnName === itemAttribute.columnName) - // if (!field || !field.isUpdateable || !field.isDisplayed) { - // return false - // } - // return true - // }) - // return requestUpdateEntity({ - // tableName: panel.tableName, - // recordUuid, - // attributesList: finalAttributes - // }) - // .then(updateEntityResponse => { - // const newValues = updateEntityResponse.values - // // set data log to undo action - // // TODO: Verify performance with tableName_ID - // let recordId = updateEntityResponse.id - // if (isEmptyValue(recordId)) { - // recordId = newValues[`${panel.tableName}_ID`] - // } - // if (isEmptyValue(recordId)) { - // const fieldId = panel.fieldsList.find(itemField => itemField.isKey) - // recordId = fieldId.value - // } - // - // if (isEmptyValue(recordUuid)) { - // recordUuid = updateEntityResponse.uuid - // } - // if (isEmptyValue(recordUuid)) { - // recordUuid = newValues.UUID - // } - // - // dispatch('setDataLog', { - // containerUuid, - // tableName: panel.tableName, - // recordId, - // recordUuid, - // eventType: 'UPDATE' - // }) - // if (rootGetters.getShowContainerInfo) { - // dispatch('listRecordLogs', { - // tableName: panel.tableName, - // recordId - // }) - // } - // return newValues - // }) - // .catch(error => { - // showMessage({ - // message: error.message, - // type: 'error' - // }) - // console.warn(`Update Entity Error ${error.code}: ${error.message}`) - // }) - // }, - updateCurrentEntityFromTable({ rootGetters }, { - containerUuid, - row - }) { - const { tableName, fieldsList } = rootGetters.getPanel(containerUuid) - - // TODO: Add support to Binary columns (BinaryData) - const columnsToDontSend = ['BinaryData', 'isEdit', 'isNew', 'isSendServer'] - columnsToDontSend.forEach(appAttribute => { - delete row[appAttribute] - }) - - // attributes or fields - let finalAttributes = convertObjectToKeyValue({ - object: row - }) - finalAttributes = finalAttributes.filter(itemAttribute => { - const { columnName } = itemAttribute - if (columnName.includes('DisplayColumn')) { - return false - } - - const field = fieldsList.find(itemField => itemField.columnName === columnName) - if (!field || !field.isUpdateable || !field.isDisplayed) { - return false - } - return true - }) - - return requestUpdateEntity({ - tableName, - recordUuid: row.UUID, - attributesList: finalAttributes - }) - .then(response => { - return response - }) - .catch(error => { - showMessage({ - message: error.message, - type: 'error' - }) - console.warn(`Update Entity Table Error ${error.code}: ${error.message}.`) - }) - }, - /** - * Update record after run process associated with window - * @param {string} parentUuid - * @param {string} containerUuid - * @param {object} tab - */ - updateRecordAfterRunProcess({ dispatch, rootGetters }, { - parentUuid, - containerUuid, - tab - }) { - const recordUuid = rootGetters.getUuidOfContainer(containerUuid) - // get new values - dispatch('getEntity', { - parentUuid, - containerUuid, - tableName: tab.tableName, - recordUuid - }) - .then(response => { - // update panel - if (tab.isParentTab) { - dispatch('notifyPanelChange', { - parentUuid, - containerUuid, - newValues: response, - isSendCallout: false, - isSendToServer: false - }) - } - // update row in table - dispatch('notifyRowTableChange', { - parentUuid, - containerUuid, - row: response, - isEdit: false - }) - }) - }, - deleteEntity({ dispatch, rootGetters }, { - parentUuid, - containerUuid, - recordUuid, - recordId, - row - }) { - return new Promise(resolve => { - const panel = rootGetters.getPanel(containerUuid) - if (!isEmptyValue(row)) { - recordUuid = row.UUID - recordId = row[`${panel.tableName}_ID`] - } - - requestDeleteEntity({ - tableName: panel.tableName, - recordUuid, - recordId - }) - .then(responseDeleteEntity => { - // refresh record list - dispatch('getDataListTab', { - parentUuid, - containerUuid - }) - .then(responseDataList => { - if (panel.isParentTab) { - // if response is void, go to new record - if (responseDataList.length <= 0) { - dispatch('setDefaultValues', { - parentUuid, - containerUuid, - panelType: 'window', - isNewRecord: true - }) - } else { - const oldRoute = router.app._route - // else display first record of table in panel - router.push({ - name: oldRoute.name, - params: { - ...oldRoute.params - }, - query: { - ...oldRoute.query, - action: responseDataList[0].UUID - } - }, () => {}) - } - } - }) - .catch(error => { - console.warn(`Error getting data list tab. Message: ${error.message}, code ${error.code}.`) - }) - showMessage({ - message: language.t('data.deleteRecordSuccessful'), - type: 'success' - }) - - if (isEmptyValue(recordId)) { - // TODO: Verify performance with tableName_ID - const fieldId = panel.fieldsList.find(itemField => itemField.isKey) - recordId = fieldId.value - } - // set data log to undo action - dispatch('setDataLog', { - containerUuid, - tableName: panel.tableName, - recordId, - recordUuid, - eventType: 'DELETE' - }) - - resolve(responseDeleteEntity) - }) - .catch(error => { - showMessage({ - message: language.t('data.deleteRecordError'), - type: 'error' - }) - console.warn(`Delete Entity - Error ${error.message}, Code: ${error.code}.`) - }) - }) - }, - /** - * Delete selection records in table - * @param {string} parentUuid - * @param {string} containerUuid - * @param {string} tableName - * @param {boolean} isParentTab - */ - deleteSelectionDataList({ dispatch, rootGetters }, { - parentUuid, - containerUuid, - tableName, - isParentTab - }) { - if (isEmptyValue(tableName) || isEmptyValue(isParentTab)) { - const tab = rootGetters.getTab(parentUuid, containerUuid) - tableName = tab.tableName - isParentTab = tab.isParentTab - } - const allData = rootGetters.getDataRecordAndSelection(containerUuid) - let selectionLength = allData.selection.length - - allData.selection.forEach((record, index) => { - // validate if the registry row has no uuid before sending to the server - if (isEmptyValue(record.UUID)) { - selectionLength = selectionLength - 1 - console.warn(`This row does not contain a record with UUID`, record) - // refresh record list - dispatch('getDataListTab', { - parentUuid, - containerUuid - }) - .catch(error => { - console.warn(`Error getting data list tab. Message: ${error.message}, code ${error.code}.`) - }) - return - } - requestDeleteEntity({ - tableName, - recordUuid: record.UUID - }) - .then(() => { - if (isParentTab) { - // redirect to create new record - const oldRoute = router.app._route - if (record.UUID === oldRoute.query.action) { - router.push({ - name: oldRoute.name, - params: { - ...oldRoute.params - }, - query: { - ...oldRoute.query, - action: 'create-new' - } - }, () => {}) - // clear fields with default values - dispatch('setDefaultValues', { - parentUuid, - containerUuid - }) - // delete view with uuid record delete - dispatch('tagsView/delView', oldRoute, true) - } - } - - if ((index + 1) >= selectionLength) { - // refresh record list - dispatch('getDataListTab', { - parentUuid, - containerUuid - }) - .catch(error => { - console.warn(`Error getting data list tab. Message: ${error.message}, code ${error.code}.`) - }) - showMessage({ - message: language.t('data.deleteRecordSuccessful'), - type: 'success' - }) - } - }) - }) - }, - undoModifyData({ getters }, { - containerUuid, - recordUuid - }) { - return rollbackEntity(getters.getDataLog(containerUuid, recordUuid)) - .then(response => { - return response - }) - .catch(error => { - showMessage({ - message: error.message, - type: 'error' - }) - console.warn(`Rollback Entity error: ${error.message}. Code: ${error.code}.`) - }) - }, - setDataLog({ commit }, { - containerUuid, - tableName, - recordId, - recordUuid, - eventType - }) { - commit('setDataLog', { - containerUuid, - tableName, - recordId, - recordUuid, - eventType - }) - }, - /** - * Get data to table in tab - * @param {string} parentUuid, window to search record data - * @param {string} containerUuid, tab to search record data - * @param {string} recordUuid, uuid to search - * @param {boolean} isRefreshPanel, if main panel is updated with new response data - * @param {boolean} isLoadAllRecords, if main panel is updated with new response data - */ - getDataListTab({ dispatch, rootGetters }, { - parentUuid, - containerUuid, - recordUuid, - referenceWhereClause = '', - columnName, - value, - criteria, - isAddRecord = false, - isLoadAllRecords = false, - isRefreshPanel = false, - isReference = false, - isShowNotification = true - }) { - const tab = rootGetters.getTab(parentUuid, containerUuid) - - let parsedQuery = tab.query - if (!isEmptyValue(parsedQuery) && parsedQuery.includes('@')) { - parsedQuery = parseContext({ - parentUuid, - containerUuid, - value: tab.query, - isBooleanToString: true - }).value - } - - let parsedWhereClause = tab.whereClause - if (!isEmptyValue(parsedWhereClause) && parsedWhereClause.includes('@')) { - parsedWhereClause = parseContext({ - parentUuid, - containerUuid, - value: tab.whereClause, - isBooleanToString: true - }).value - } - - if (isReference) { - if (!isEmptyValue(parsedWhereClause)) { - parsedWhereClause += ` AND ${referenceWhereClause}` - } else { - parsedWhereClause += referenceWhereClause - } - } - - if (!isEmptyValue(criteria)) { - if (!isEmptyValue(parsedWhereClause)) { - parsedWhereClause += ` AND ${criteria.whereClause}` - } else { - parsedWhereClause += criteria.whereClause - } - } - - const conditionsList = [] - // TODO: evaluate if overwrite values to conditions - if (!isLoadAllRecords && tab.isParentTab && !isEmptyValue(tab.tableName) && !isEmptyValue(value)) { - conditionsList.push({ - columnName, - value - }) - } - return dispatch('getObjectListFromCriteria', { - parentUuid, - containerUuid, - tableName: tab.tableName, - query: parsedQuery, - whereClause: parsedWhereClause, - orderByClause: tab.orderByClause, - conditionsList, - isParentTab: tab.isParentTab, - isAddRecord, - isShowNotification - }) - .then(response => { - if (isRefreshPanel && !isEmptyValue(recordUuid) && recordUuid !== 'create-new') { - const newValues = response.find(itemData => itemData.UUID === recordUuid) - if (newValues) { - // update fields with values obtained from the server - dispatch('notifyPanelChange', { - parentUuid, - containerUuid, - newValues, - isSendCallout: false, - isSendToServer: false - }) - } else { - // this record is missing (Deleted or the query does not include it) - dispatch('setDefaultValues', { - parentUuid, - containerUuid - }) - } - } - return response - }) - .catch(error => { - return error - }) - .finally(() => { - const currentData = rootGetters.getDataRecordAndSelection(containerUuid) - const { originalNextPageToken, pageNumber, recordCount } = currentData - let nextPage = pageNumber - const isAdd = isAddRecord - if (originalNextPageToken && isAddRecord) { - const pageInToken = originalNextPageToken.substring(originalNextPageToken.length - 2) - if (pageInToken === '-1') { - isAddRecord = false - } - if (pageNumber === 1 && recordCount > 50) { - nextPage = nextPage + 1 - isAddRecord = true - } - } else { - isAddRecord = false - } - if (recordCount <= 50) { - isAddRecord = false - } - - if (isAddRecord) { - dispatch('setPageNumber', { - parentUuid, - containerUuid, - pageNumber: nextPage, - panelType: 'window', - isAddRecord, - isShowNotification: false - }) - } - if (isAdd && isAdd !== isAddRecord) { - if (tab.isSortTab) { - const record = rootGetters.getDataRecordsList(containerUuid) - const recordToTab = record - .map(itemRecord => { - return { - ...itemRecord - } - }) - .sort((itemA, itemB) => { - return itemA[tab.sortOrderColumnName] - itemB[tab.sortOrderColumnName] - }) - dispatch('setTabSequenceRecord', recordToTab) - } - } - }) - }, - /** - * Get references asociate to record - * @param {string} parentUuid as windowUuid - * @param {string} containerUuid - * @param {string} tableName - * @param {string} recordUuid - */ - getReferencesListFromServer({ commit, rootGetters }, { - parentUuid: windowUuid, - containerUuid, - tableName, - recordUuid - }) { - if (isEmptyValue(tableName)) { - tableName = rootGetters.getTab(windowUuid, containerUuid).tableName - } - return new Promise(resolve => { - requestReferencesList({ - windowUuid, - tableName, - recordUuid - }) - .then(referenceResponse => { - const referencesList = referenceResponse.referencesList.map(item => { - return { - ...item, - recordUuid, - type: 'reference' - } - }) - const references = { - ...referenceResponse, - windowUuid, - recordUuid, - referencesList - } - commit('addReferencesList', references) - resolve(referenceResponse) - }) - .catch(error => { - console.warn(`References Load Error ${error.code}: ${error.message}.`) - }) - }) - }, - setWindowOldRoute({ commit }, oldPath = { path: '', fullPath: '', query: {}}) { - commit('setWindowOldRoute', oldPath) - }, - setTabSequenceRecord({ commit }, record) { - commit('setTabSequenceRecord', record) - }, - /** - * Update records in tab sort - * @param {string} containerUuid - * @param {string} parentUuid - */ - updateSequence({ state, commit, dispatch, getters, rootGetters }, { - parentUuid, - containerUuid - }) { - const { tableName, sortOrderColumnName, sortYesNoColumnName, tabAssociatedUuid } = rootGetters.getTab(parentUuid, containerUuid) - const listSequenceToSet = getters.getTabSequenceRecord - const recordData = rootGetters.getDataRecordsList(containerUuid) - - // scrolls through the logs and checks if there is a change to be sent to server - recordData.forEach(itemData => { - const dataSequence = listSequenceToSet.find(item => item.UUID === itemData.UUID) - if (itemData[sortOrderColumnName] === dataSequence[sortOrderColumnName]) { - return - } - const valuesToSend = [{ - columnName: sortOrderColumnName, - value: dataSequence[sortOrderColumnName] - }] - - if (itemData[sortYesNoColumnName] !== dataSequence[sortYesNoColumnName]) { - valuesToSend.push({ - columnName: sortYesNoColumnName, - value: dataSequence[sortYesNoColumnName] - }) - } - - const countRequest = state.totalRequest + 1 - commit('setTotalRequest', countRequest) - - requestUpdateEntity({ - tableName, - recordUuid: itemData.UUID, - attributesList: valuesToSend - }) - .catch(error => { - showMessage({ - message: error.message, - type: 'error' - }) - console.warn(`Update Entity Table Error ${error.code}: ${error.message}`) - }) - .finally(() => { - const countResponse = state.totalResponse + 1 - commit('setTotalResponse', countResponse) - if (state.totalResponse === state.totalRequest) { - showMessage({ - message: language.t('notifications.updateSuccessfully'), - type: 'success' - }) - dispatch('setShowDialog', { - type: 'window', - action: undefined - }) - commit('setTotalRequest', 0) - commit('setTotalResponse', 0) - - dispatch('setRecordSelection', { - parentUuid, - containerUuid, - isLoaded: false - }) - dispatch('setTabSequenceRecord', []) - - // refresh record list in table source - dispatch('getDataListTab', { - parentUuid, - containerUuid: tabAssociatedUuid - }) - .catch(error => { - console.warn(`Error getting data list tab. Message: ${error.message}, code ${error.code}.`) - }) - } - }) - }) - } - }, - getters: { - getCurrentRecord: (state) => { - return state.currentRecord - }, - getInCreate: (state) => (containerUuid) => { - return state.inCreate.find(item => item.containerUuid === containerUuid) - }, - getReferencesList: (state) => (windowUuid, recordUuid) => { - return state.references.find(item => item.windowUuid === windowUuid && item.recordUuid === recordUuid) - }, - getReferencesInfo: (state, getters) => ({ windowUuid, recordUuid, referenceUuid }) => { - const references = getters.getReferencesList(windowUuid, recordUuid) - return references.referencesList.find(item => item.uuid === referenceUuid) - }, - getTabSequenceRecord: (state) => { - return state.tabSequenceRecord - }, - getDataLog: (state) => (containerUuid, recordUuid) => { - const current = state.dataLog - if (current.containerUuid === containerUuid && - ((current.recordUuid === recordUuid) || - (current.eventType === 'DELETE' && recordUuid === 'create-new'))) { - return current - } - return undefined - } - } -} - -export default windowControl diff --git a/src/store/modules/ADempiere/windowControl/actions.js b/src/store/modules/ADempiere/windowControl/actions.js new file mode 100644 index 00000000..e14bbae0 --- /dev/null +++ b/src/store/modules/ADempiere/windowControl/actions.js @@ -0,0 +1,1080 @@ +import { + requestCreateEntity, + requestUpdateEntity, + requestDeleteEntity, + rollbackEntity +} from '@/api/ADempiere/persistence' +import { requestReferencesList } from '@/api/ADempiere/values' +import { isEmptyValue, typeValue } from '@/utils/ADempiere/valueUtils.js' +import { fieldIsDisplayed } from '@/utils/ADempiere/dictionaryUtils' +import { parseContext } from '@/utils/ADempiere/contextUtils' +import { showMessage } from '@/utils/ADempiere/notification' +import language from '@/lang' +import router from '@/router' +import { convertObjectToKeyValue } from '@/utils/ADempiere/valueFormat.js' + +/** + * Window Control Vuex Module + * Actions to dispatch + * @author Edwin Betancourt + */ +export default { + tableActionPerformed({ dispatch, getters }, { + field, + value + }) { + if (fieldIsDisplayed(field) && field.isShowedFromUser) { + // change action to advanced query on field value is changed in this panel + if (router.currentRoute.query.action !== 'advancedQuery') { + router.push({ + query: { + ...router.currentRoute.query, + action: 'advancedQuery' + } + }, () => {}) + } + const { parentUuid, containerUuid, tabTableName, tabQuery, tabWhereClause } = field + let parsedQuery = tabQuery + if (!isEmptyValue(parsedQuery) && parsedQuery.includes('@')) { + parsedQuery = parseContext({ + parentUuid, + containerUuid, + value: tabQuery, + isBooleanToString: true + }).value + } + + let parsedWhereClause = tabWhereClause + if (!isEmptyValue(parsedWhereClause) && parsedWhereClause.includes('@')) { + parsedWhereClause = parseContext({ + parentUuid, + containerUuid, + value: tabWhereClause, + isBooleanToString: true + }).value + } + + const conditionsList = getters.getParametersToServer({ + containerUuid, + isEvaluateMandatory: false + }) + + dispatch('getObjectListFromCriteria', { + parentUuid, + containerUuid, + tableName: tabTableName, + query: parsedQuery, + whereClause: parsedWhereClause, + conditionsList + }) + .catch(error => { + console.warn('Error getting Advanced Query (notifyFieldChange):', error.message + '. Code: ', error.code) + }) + } + }, + + windowActionPerformed({ dispatch, getters }, { + field, + value + }) { + const { parentUuid, containerUuid, columnName } = field + // get value from store + if (isEmptyValue(value)) { + value = getters.getValueOfField({ + parentUuid, + containerUuid, + columnName + }) + } + return new Promise((resolve, reject) => { + // request callouts + dispatch('runCallout', { + parentUuid, + containerUuid, + tableName: field.tableName, + columnName, + callout: field.callout, + oldValue: field.oldValue, + valueType: field.valueType, + value + }) + .then(() => { + // Context Info + dispatch('reloadContextInfo', { + field + }) + // Apply actions for server + dispatch('runServerAction', { + field, + value + }) + .then(response => resolve(response)) + .catch(error => reject(error)) + }) + }) + }, + + runServerAction({ dispatch, getters, commit }, { + field, + value + }) { + return new Promise((resolve, reject) => { + // For change options + if (fieldIsDisplayed(field)) { + commit('addChangeToPersistenceQueue', { + ...field, + value + }) + const emptyFields = getters.getFieldsListEmptyMandatory({ + containerUuid: field.containerUuid + }) + if (!isEmptyValue(emptyFields)) { + showMessage({ + message: language.t('notifications.mandatoryFieldMissing') + emptyFields, + type: 'info' + }) + } else { + const recordUuid = getters.getUuidOfContainer(field.containerUuid) + dispatch('flushPersistenceQueue', { + containerUuid: field.containerUuid, + tableName: field.tableName, + recordUuid + }) + .then(response => { + resolve(response) + if (isEmptyValue(recordUuid)) { + const oldRoute = router.app._route + router.push({ + name: oldRoute.name, + params: { + ...oldRoute.params + }, + query: { + ...oldRoute.query, + action: response.uuid + } + }, () => {}) + } + }) + .catch(error => reject(error)) + } + } + }) + }, + + reloadContextInfo({ dispatch, getters }, { + field + }) { + // get value from store + const value = getters.getValueOfField({ + parentUuid: field.parentUuid, + containerUuid: field.containerUuid, + columnName: field.columnName + }) + // request context info field + if (!isEmptyValue(value) && !isEmptyValue(field.contextInfo) && !isEmptyValue(field.contextInfo.sqlStatement)) { + let isSQL = false + let sqlStatement = field.contextInfo.sqlStatement + if (sqlStatement.includes('@')) { + if (sqlStatement.includes('@SQL=')) { + isSQL = true + } + sqlStatement = parseContext({ + parentUuid: field.parentUuid, + containerUuid: field.containerUuid, + columnName: field.columnName, + value: sqlStatement, + isSQL + }).value + if (isSQL && typeValue(sqlStatement) === 'OBJECT') { + sqlStatement = sqlStatement.query + } + } + const contextInfo = dispatch('getContextInfoValueFromServer', { + parentUuid: field.parentUuid, + containerUuid: field.containerUuid, + contextInfoId: field.contextInfo.id, + contextInfoUuid: field.contextInfo.uuid, + columnName: field.columnName, + sqlStatement + }) + if (!isEmptyValue(contextInfo) && !isEmptyValue(contextInfo.messageText)) { + field.contextInfo.isActive = true + field.contextInfo.messageText.msgText = contextInfo.messageText + field.contextInfo.messageText.msgTip = contextInfo.messageTip + } + } + }, + + undoPanelToNew({ dispatch, rootGetters }, { containerUuid }) { + const oldAttributes = rootGetters.getColumnNamesAndValues({ + containerUuid, + propertyName: 'oldValue', + isObjectReturn: true, + isAddDisplayColumn: true + }) + dispatch('notifyPanelChange', { + containerUuid, + newValues: oldAttributes + }) + }, + + // createNewEntity({ commit, dispatch, getters, rootGetters }, { + // parentUuid, + // containerUuid + // }) { + // return new Promise((resolve, reject) => { + // // exists some call to create new record with container uuid + // if (getters.getInCreate(containerUuid)) { + // return reject({ + // error: 0, + // message: `In this panel (${containerUuid}) is a create new record in progress` + // }) + // } + // + // const { tableName, fieldsList } = rootGetters.getPanel(containerUuid) + // // delete key from attributes + // const attributesList = rootGetters.getColumnNamesAndValues({ + // containerUuid, + // propertyName: 'value', + // isEvaluateValues: true, + // isAddDisplayColumn: false + // }) + // commit('addInCreate', { + // containerUuid, + // tableName, + // attributesList + // }) + // requestCreateEntity({ + // tableName, + // attributesList + // }) + // .then(createEntityResponse => { + // const newValues = createEntityResponse.values + // attributesList.forEach(element => { + // if (element.columnName.includes('DisplayColumn')) { + // newValues[element.columnName] = element.value + // } + // }) + // + // showMessage({ + // message: language.t('data.createRecordSuccessful'), + // type: 'success' + // }) + // + // // update fields with new values + // dispatch('notifyPanelChange', { + // parentUuid, + // containerUuid, + // newValues, + // isSendToServer: false + // }) + // dispatch('addNewRow', { + // parentUuid, + // containerUuid, + // isPanelValues: true, + // isEdit: false + // }) + // + // // set data log to undo action + // const fieldId = fieldsList.find(itemField => itemField.isKey) + // dispatch('setDataLog', { + // containerUuid, + // tableName, + // recordId: fieldId.value, // TODO: Verify performance with tableName_ID + // recordUuid: newValues.UUID, + // eventType: 'INSERT' + // }) + // + // const oldRoute = router.app._route + // router.push({ + // name: oldRoute.name, + // params: { + // ...oldRoute.params + // }, + // query: { + // ...oldRoute.query, + // action: createEntityResponse.uuid + // } + // }) + // dispatch('tagsView/delView', oldRoute, true) + // + // resolve({ + // data: newValues, + // recordUuid: createEntityResponse.uuid, + // recordId: createEntityResponse.id, + // tableName: createEntityResponse.tableName + // }) + // }) + // .catch(error => { + // showMessage({ + // message: error.message, + // type: 'error' + // }) + // console.warn(`Create Entity error: ${error.message}.`) + // reject(error) + // }) + // .finally(() => { + // commit('deleteInCreate', { + // containerUuid, + // tableName, + // attributesList + // }) + // }) + // }) + // }, + + createEntityFromTable({ commit, dispatch, getters, rootGetters }, { + parentUuid, + containerUuid, + row + }) { + // exists some call to create new record with container uuid + if (getters.getInCreate(containerUuid)) { + return { + error: 0, + message: `In this panel (${containerUuid}) is a create new record in progress.` + } + } + const { tableName, isParentTab } = rootGetters.getPanel(containerUuid) + + // TODO: Add support to Binary columns (BinaryData) + const columnsToDontSend = ['BinaryData', 'isEdit', 'isNew', 'isSendServer'] + + // TODO: Evaluate peformance without filter using delete(prop) before convert object to array + // attributes or fields + const fieldsList = getters.getFieldsListFromPanel(containerUuid) + const attributesList = [] + fieldsList.forEach(itemAttribute => { + if (columnsToDontSend.includes(itemAttribute.columnName) || itemAttribute.columnName.includes('DisplayColumn')) { + return false + } + if (isEmptyValue(row[itemAttribute.columnName])) { + return false + } + + attributesList.push({ + value: row[itemAttribute.columnName], + columnName: itemAttribute.columnName, + valueType: itemAttribute.valueType + }) + }) + + commit('addInCreate', { + containerUuid, + tableName, + attributesList + }) + + let isError = false + return requestCreateEntity({ + tableName, + attributesList + }) + .then(createEntityResponse => { + showMessage({ + message: language.t('data.createRecordSuccessful'), + type: 'success' + }) + if (isParentTab) { + // redirect to create new record + const oldRoute = router.app._route + router.push({ + name: oldRoute.name, + params: { + ...oldRoute.params + }, + query: { + ...oldRoute.query, + action: createEntityResponse.recordUuid + } + }, () => {}) + } + return { + data: createEntityResponse.values, + ...createEntityResponse + } + }) + .catch(error => { + showMessage({ + message: error.message, + type: 'error' + }) + console.warn(`Create Entity Table Error ${error.code}: ${error.message}.`) + isError = true + }) + .finally(() => { + if (isError) { + dispatch('addNewRow', { + containerUuid, + row + }) + } else { + // refresh record list + dispatch('getDataListTab', { + parentUuid, + containerUuid + }) + .catch(error => { + console.warn(`Error getting data list tab. Message: ${error.message}, code ${error.code}.`) + }) + } + commit('deleteInCreate', { + containerUuid, + tableName, + attributesList + }) + }) + }, + + // updateCurrentEntity({ dispatch, rootGetters }, { + // containerUuid, + // recordUuid = null + // }) { + // const panel = rootGetters.getPanel(containerUuid) + // if (!recordUuid) { + // recordUuid = rootGetters.getUuidOfContainer(containerUuid) + // } + // + // // TODO: Add support to Binary columns (BinaryData) + // const columnsToDontSend = ['Account_Acct'] + // + // // attributes or fields + // let finalAttributes = rootGetters.getColumnNamesAndValues({ + // containerUuid: containerUuid, + // isEvaluatedChangedValue: true + // }) + // + // finalAttributes = finalAttributes.filter(itemAttribute => { + // if (columnsToDontSend.includes(itemAttribute.columnName) || itemAttribute.columnName.includes('DisplayColumn')) { + // return false + // } + // const field = panel.fieldsList.find(itemField => itemField.columnName === itemAttribute.columnName) + // if (!field || !field.isUpdateable || !field.isDisplayed) { + // return false + // } + // return true + // }) + // return requestUpdateEntity({ + // tableName: panel.tableName, + // recordUuid, + // attributesList: finalAttributes + // }) + // .then(updateEntityResponse => { + // const newValues = updateEntityResponse.values + // // set data log to undo action + // // TODO: Verify performance with tableName_ID + // let recordId = updateEntityResponse.id + // if (isEmptyValue(recordId)) { + // recordId = newValues[`${panel.tableName}_ID`] + // } + // if (isEmptyValue(recordId)) { + // const fieldId = panel.fieldsList.find(itemField => itemField.isKey) + // recordId = fieldId.value + // } + // + // if (isEmptyValue(recordUuid)) { + // recordUuid = updateEntityResponse.uuid + // } + // if (isEmptyValue(recordUuid)) { + // recordUuid = newValues.UUID + // } + // + // dispatch('setDataLog', { + // containerUuid, + // tableName: panel.tableName, + // recordId, + // recordUuid, + // eventType: 'UPDATE' + // }) + // if (rootGetters.getShowContainerInfo) { + // dispatch('listRecordLogs', { + // tableName: panel.tableName, + // recordId + // }) + // } + // return newValues + // }) + // .catch(error => { + // showMessage({ + // message: error.message, + // type: 'error' + // }) + // console.warn(`Update Entity Error ${error.code}: ${error.message}`) + // }) + // }, + + updateCurrentEntityFromTable({ rootGetters }, { + containerUuid, + row + }) { + const { tableName, fieldsList } = rootGetters.getPanel(containerUuid) + + // TODO: Add support to Binary columns (BinaryData) + const columnsToDontSend = ['BinaryData', 'isEdit', 'isNew', 'isSendServer'] + columnsToDontSend.forEach(appAttribute => { + delete row[appAttribute] + }) + + // attributes or fields + let finalAttributes = convertObjectToKeyValue({ + object: row + }) + finalAttributes = finalAttributes.filter(itemAttribute => { + const { columnName } = itemAttribute + if (columnName.includes('DisplayColumn')) { + return false + } + + const field = fieldsList.find(itemField => itemField.columnName === columnName) + if (!field || !field.isUpdateable || !field.isDisplayed) { + return false + } + return true + }) + + return requestUpdateEntity({ + tableName, + recordUuid: row.UUID, + attributesList: finalAttributes + }) + .then(response => { + return response + }) + .catch(error => { + showMessage({ + message: error.message, + type: 'error' + }) + console.warn(`Update Entity Table Error ${error.code}: ${error.message}.`) + }) + }, + + /** + * Update record after run process associated with window + * @param {string} parentUuid + * @param {string} containerUuid + * @param {object} tab + */ + updateRecordAfterRunProcess({ dispatch, rootGetters }, { + parentUuid, + containerUuid, + tab + }) { + const recordUuid = rootGetters.getUuidOfContainer(containerUuid) + // get new values + dispatch('getEntity', { + parentUuid, + containerUuid, + tableName: tab.tableName, + recordUuid + }) + .then(response => { + // update panel + if (tab.isParentTab) { + dispatch('notifyPanelChange', { + parentUuid, + containerUuid, + newValues: response, + isSendCallout: false, + isSendToServer: false + }) + } + // update row in table + dispatch('notifyRowTableChange', { + parentUuid, + containerUuid, + row: response, + isEdit: false + }) + }) + }, + + deleteEntity({ dispatch, rootGetters }, { + parentUuid, + containerUuid, + recordUuid, + recordId, + row + }) { + return new Promise(resolve => { + const panel = rootGetters.getPanel(containerUuid) + if (!isEmptyValue(row)) { + recordUuid = row.UUID + recordId = row[`${panel.tableName}_ID`] + } + + requestDeleteEntity({ + tableName: panel.tableName, + recordUuid, + recordId + }) + .then(responseDeleteEntity => { + // refresh record list + dispatch('getDataListTab', { + parentUuid, + containerUuid + }) + .then(responseDataList => { + if (panel.isParentTab) { + // if response is void, go to new record + if (responseDataList.length <= 0) { + dispatch('setDefaultValues', { + parentUuid, + containerUuid, + panelType: 'window', + isNewRecord: true + }) + } else { + const oldRoute = router.app._route + // else display first record of table in panel + router.push({ + name: oldRoute.name, + params: { + ...oldRoute.params + }, + query: { + ...oldRoute.query, + action: responseDataList[0].UUID + } + }, () => {}) + } + } + }) + .catch(error => { + console.warn(`Error getting data list tab. Message: ${error.message}, code ${error.code}.`) + }) + showMessage({ + message: language.t('data.deleteRecordSuccessful'), + type: 'success' + }) + + if (isEmptyValue(recordId)) { + // TODO: Verify performance with tableName_ID + const fieldId = panel.fieldsList.find(itemField => itemField.isKey) + recordId = fieldId.value + } + // set data log to undo action + dispatch('setDataLog', { + containerUuid, + tableName: panel.tableName, + recordId, + recordUuid, + eventType: 'DELETE' + }) + + resolve(responseDeleteEntity) + }) + .catch(error => { + showMessage({ + message: language.t('data.deleteRecordError'), + type: 'error' + }) + console.warn(`Delete Entity - Error ${error.message}, Code: ${error.code}.`) + }) + }) + }, + + /** + * Delete selection records in table + * @param {string} parentUuid + * @param {string} containerUuid + * @param {string} tableName + * @param {boolean} isParentTab + */ + deleteSelectionDataList({ dispatch, rootGetters }, { + parentUuid, + containerUuid, + tableName, + isParentTab + }) { + if (isEmptyValue(tableName) || isEmptyValue(isParentTab)) { + const tab = rootGetters.getTab(parentUuid, containerUuid) + tableName = tab.tableName + isParentTab = tab.isParentTab + } + const allData = rootGetters.getDataRecordAndSelection(containerUuid) + let selectionLength = allData.selection.length + + allData.selection.forEach((record, index) => { + // validate if the registry row has no uuid before sending to the server + if (isEmptyValue(record.UUID)) { + selectionLength = selectionLength - 1 + console.warn(`This row does not contain a record with UUID`, record) + // refresh record list + dispatch('getDataListTab', { + parentUuid, + containerUuid + }) + .catch(error => { + console.warn(`Error getting data list tab. Message: ${error.message}, code ${error.code}.`) + }) + return + } + requestDeleteEntity({ + tableName, + recordUuid: record.UUID + }) + .then(() => { + if (isParentTab) { + // redirect to create new record + const oldRoute = router.app._route + if (record.UUID === oldRoute.query.action) { + router.push({ + name: oldRoute.name, + params: { + ...oldRoute.params + }, + query: { + ...oldRoute.query, + action: 'create-new' + } + }, () => {}) + // clear fields with default values + dispatch('setDefaultValues', { + parentUuid, + containerUuid + }) + // delete view with uuid record delete + dispatch('tagsView/delView', oldRoute, true) + } + } + + if ((index + 1) >= selectionLength) { + // refresh record list + dispatch('getDataListTab', { + parentUuid, + containerUuid + }) + .catch(error => { + console.warn(`Error getting data list tab. Message: ${error.message}, code ${error.code}.`) + }) + showMessage({ + message: language.t('data.deleteRecordSuccessful'), + type: 'success' + }) + } + }) + }) + }, + + undoModifyData({ getters }, { + containerUuid, + recordUuid + }) { + return rollbackEntity(getters.getDataLog(containerUuid, recordUuid)) + .then(response => { + return response + }) + .catch(error => { + showMessage({ + message: error.message, + type: 'error' + }) + console.warn(`Rollback Entity error: ${error.message}. Code: ${error.code}.`) + }) + }, + + setDataLog({ commit }, { + containerUuid, + tableName, + recordId, + recordUuid, + eventType + }) { + commit('setDataLog', { + containerUuid, + tableName, + recordId, + recordUuid, + eventType + }) + }, + /** + * Get data to table in tab + * @param {string} parentUuid, window to search record data + * @param {string} containerUuid, tab to search record data + * @param {string} recordUuid, uuid to search + * @param {boolean} isRefreshPanel, if main panel is updated with new response data + * @param {boolean} isLoadAllRecords, if main panel is updated with new response data + */ + getDataListTab({ dispatch, rootGetters }, { + parentUuid, + containerUuid, + recordUuid, + referenceWhereClause = '', + columnName, + value, + criteria, + isAddRecord = false, + isLoadAllRecords = false, + isRefreshPanel = false, + isReference = false, + isShowNotification = true + }) { + const tab = rootGetters.getTab(parentUuid, containerUuid) + + let parsedQuery = tab.query + if (!isEmptyValue(parsedQuery) && parsedQuery.includes('@')) { + parsedQuery = parseContext({ + parentUuid, + containerUuid, + value: tab.query, + isBooleanToString: true + }).value + } + + let parsedWhereClause = tab.whereClause + if (!isEmptyValue(parsedWhereClause) && parsedWhereClause.includes('@')) { + parsedWhereClause = parseContext({ + parentUuid, + containerUuid, + value: tab.whereClause, + isBooleanToString: true + }).value + } + + if (isReference) { + if (!isEmptyValue(parsedWhereClause)) { + parsedWhereClause += ` AND ${referenceWhereClause}` + } else { + parsedWhereClause += referenceWhereClause + } + } + + if (!isEmptyValue(criteria)) { + if (!isEmptyValue(parsedWhereClause)) { + parsedWhereClause += ` AND ${criteria.whereClause}` + } else { + parsedWhereClause += criteria.whereClause + } + } + + const conditionsList = [] + // TODO: evaluate if overwrite values to conditions + if (!isLoadAllRecords && tab.isParentTab && !isEmptyValue(tab.tableName) && !isEmptyValue(value)) { + conditionsList.push({ + columnName, + value + }) + } + return dispatch('getObjectListFromCriteria', { + parentUuid, + containerUuid, + tableName: tab.tableName, + query: parsedQuery, + whereClause: parsedWhereClause, + orderByClause: tab.orderByClause, + conditionsList, + isParentTab: tab.isParentTab, + isAddRecord, + isShowNotification + }) + .then(response => { + if (isRefreshPanel && !isEmptyValue(recordUuid) && recordUuid !== 'create-new') { + const newValues = response.find(itemData => itemData.UUID === recordUuid) + if (newValues) { + // update fields with values obtained from the server + dispatch('notifyPanelChange', { + parentUuid, + containerUuid, + newValues, + isSendCallout: false, + isSendToServer: false + }) + } else { + // this record is missing (Deleted or the query does not include it) + dispatch('setDefaultValues', { + parentUuid, + containerUuid + }) + } + } + return response + }) + .catch(error => { + return error + }) + .finally(() => { + const currentData = rootGetters.getDataRecordAndSelection(containerUuid) + const { originalNextPageToken, pageNumber, recordCount } = currentData + let nextPage = pageNumber + const isAdd = isAddRecord + if (originalNextPageToken && isAddRecord) { + const pageInToken = originalNextPageToken.substring(originalNextPageToken.length - 2) + if (pageInToken === '-1') { + isAddRecord = false + } + if (pageNumber === 1 && recordCount > 50) { + nextPage = nextPage + 1 + isAddRecord = true + } + } else { + isAddRecord = false + } + if (recordCount <= 50) { + isAddRecord = false + } + + if (isAddRecord) { + dispatch('setPageNumber', { + parentUuid, + containerUuid, + pageNumber: nextPage, + panelType: 'window', + isAddRecord, + isShowNotification: false + }) + } + if (isAdd && isAdd !== isAddRecord) { + if (tab.isSortTab) { + const record = rootGetters.getDataRecordsList(containerUuid) + const recordToTab = record + .map(itemRecord => { + return { + ...itemRecord + } + }) + .sort((itemA, itemB) => { + return itemA[tab.sortOrderColumnName] - itemB[tab.sortOrderColumnName] + }) + dispatch('setTabSequenceRecord', recordToTab) + } + } + }) + }, + + /** + * Get references asociate to record + * @param {string} parentUuid as windowUuid + * @param {string} containerUuid + * @param {string} tableName + * @param {string} recordUuid + */ + getReferencesListFromServer({ commit, rootGetters }, { + parentUuid: windowUuid, + containerUuid, + tableName, + recordUuid + }) { + if (isEmptyValue(tableName)) { + tableName = rootGetters.getTab(windowUuid, containerUuid).tableName + } + return new Promise(resolve => { + requestReferencesList({ + windowUuid, + tableName, + recordUuid + }) + .then(referenceResponse => { + const referencesList = referenceResponse.referencesList.map(item => { + return { + ...item, + recordUuid, + type: 'reference' + } + }) + const references = { + ...referenceResponse, + windowUuid, + recordUuid, + referencesList + } + commit('addReferencesList', references) + resolve(referenceResponse) + }) + .catch(error => { + console.warn(`References Load Error ${error.code}: ${error.message}.`) + }) + }) + }, + + setWindowOldRoute({ commit }, oldPath = { path: '', fullPath: '', query: {}}) { + commit('setWindowOldRoute', oldPath) + }, + + setTabSequenceRecord({ commit }, record) { + commit('setTabSequenceRecord', record) + }, + + /** + * Update records in tab sort + * @param {string} containerUuid + * @param {string} parentUuid + */ + updateSequence({ state, commit, dispatch, getters, rootGetters }, { + parentUuid, + containerUuid + }) { + const { tableName, sortOrderColumnName, sortYesNoColumnName, tabAssociatedUuid } = rootGetters.getTab(parentUuid, containerUuid) + const listSequenceToSet = getters.getTabSequenceRecord + const recordData = rootGetters.getDataRecordsList(containerUuid) + + // scrolls through the logs and checks if there is a change to be sent to server + recordData.forEach(itemData => { + const dataSequence = listSequenceToSet.find(item => item.UUID === itemData.UUID) + if (itemData[sortOrderColumnName] === dataSequence[sortOrderColumnName]) { + return + } + const valuesToSend = [{ + columnName: sortOrderColumnName, + value: dataSequence[sortOrderColumnName] + }] + + if (itemData[sortYesNoColumnName] !== dataSequence[sortYesNoColumnName]) { + valuesToSend.push({ + columnName: sortYesNoColumnName, + value: dataSequence[sortYesNoColumnName] + }) + } + + const countRequest = state.totalRequest + 1 + commit('setTotalRequest', countRequest) + + requestUpdateEntity({ + tableName, + recordUuid: itemData.UUID, + attributesList: valuesToSend + }) + .catch(error => { + showMessage({ + message: error.message, + type: 'error' + }) + console.warn(`Update Entity Table Error ${error.code}: ${error.message}`) + }) + .finally(() => { + const countResponse = state.totalResponse + 1 + commit('setTotalResponse', countResponse) + if (state.totalResponse === state.totalRequest) { + showMessage({ + message: language.t('notifications.updateSuccessfully'), + type: 'success' + }) + dispatch('setShowDialog', { + type: 'window', + action: undefined + }) + commit('setTotalRequest', 0) + commit('setTotalResponse', 0) + + dispatch('setRecordSelection', { + parentUuid, + containerUuid, + isLoaded: false + }) + dispatch('setTabSequenceRecord', []) + + // refresh record list in table source + dispatch('getDataListTab', { + parentUuid, + containerUuid: tabAssociatedUuid + }) + .catch(error => { + console.warn(`Error getting data list tab. Message: ${error.message}, code ${error.code}.`) + }) + } + }) + }) + } +} diff --git a/src/store/modules/ADempiere/windowControl/getters.js b/src/store/modules/ADempiere/windowControl/getters.js new file mode 100644 index 00000000..9964ffaf --- /dev/null +++ b/src/store/modules/ADempiere/windowControl/getters.js @@ -0,0 +1,37 @@ +/** + * Vuex Module, Window Control + * Getters + * @author Edwin Betancourt + */ +export default { + getCurrentRecord: (state) => { + return state.currentRecord + }, + + getInCreate: (state) => (containerUuid) => { + return state.inCreate.find(item => item.containerUuid === containerUuid) + }, + + getReferencesList: (state) => (windowUuid, recordUuid) => { + return state.references.find(item => item.windowUuid === windowUuid && item.recordUuid === recordUuid) + }, + + getReferencesInfo: (state, getters) => ({ windowUuid, recordUuid, referenceUuid }) => { + const references = getters.getReferencesList(windowUuid, recordUuid) + return references.referencesList.find(item => item.uuid === referenceUuid) + }, + + getTabSequenceRecord: (state) => { + return state.tabSequenceRecord + }, + + getDataLog: (state) => (containerUuid, recordUuid) => { + const current = state.dataLog + if (current.containerUuid === containerUuid && + ((current.recordUuid === recordUuid) || + (current.eventType === 'DELETE' && recordUuid === 'create-new'))) { + return current + } + return undefined + } +} diff --git a/src/store/modules/ADempiere/windowControl/index.js b/src/store/modules/ADempiere/windowControl/index.js new file mode 100644 index 00000000..e6412b31 --- /dev/null +++ b/src/store/modules/ADempiere/windowControl/index.js @@ -0,0 +1,19 @@ + +import state from './state.js' +import mutations from './mutations.js' +import actions from './actions.js' +import getters from './getters.js' + +/** + * Window Control + * Vuex Module + * @author Edwin Betancourt + */ +const windowControl = { + state, + mutations, + actions, + getters +} + +export default windowControl diff --git a/src/store/modules/ADempiere/windowControl/mutations.js b/src/store/modules/ADempiere/windowControl/mutations.js new file mode 100644 index 00000000..2b6b8fdb --- /dev/null +++ b/src/store/modules/ADempiere/windowControl/mutations.js @@ -0,0 +1,48 @@ +import initStateWindowControl from './state.js' + +/** + * Window Control Vuex Module + * Muttations to commit state + * @author Edwin Betancourt + */ +export default { + setCurrentRecord(state, payload) { + state.currentRecord = payload + }, + + addInCreate(state, payload) { + state.inCreate.push(payload) + }, + + deleteInCreate(state, payload) { + state.inCreate = state.inCreate.filter(item => item.containerUuid !== payload.containerUuid) + }, + + addReferencesList(state, payload) { + state.references.push(payload) + }, + + setDataLog(state, payload) { + state.dataLog = payload + }, + + setWindowOldRoute(state, payload) { + state.windowOldRoute = payload + }, + + setTabSequenceRecord(state, payload) { + state.tabSequenceRecord = payload + }, + + setTotalResponse(state, payload) { + state.totalResponse = payload + }, + + setTotalRequest(state, payload) { + state.totalRequest = payload + }, + + resetStateWindowControl(state) { + state = initStateWindowControl + } +} diff --git a/src/store/modules/ADempiere/windowControl/state.js b/src/store/modules/ADempiere/windowControl/state.js new file mode 100644 index 00000000..4479b575 --- /dev/null +++ b/src/store/modules/ADempiere/windowControl/state.js @@ -0,0 +1,20 @@ + +/** + * Window Control Vuex Module + * State (or initial state) from Window Control + * @author Edwin Betancourt + */ +export default { + inCreate: [], + references: [], + currentRecord: {}, + windowOldRoute: { + path: '', + fullPath: '', + query: {} + }, + dataLog: {}, // { containerUuid, recordId, tableName, eventType } + tabSequenceRecord: [], + totalResponse: 0, + totalRequest: 0 +}