From 0405066f60bc93e2fda987a466d3bd56bd3e59b6 Mon Sep 17 00:00:00 2001 From: Edwin Betancourt Date: Sat, 27 Feb 2021 14:35:19 -0400 Subject: [PATCH] fix: Create/update entity send log columns. (#612) * fix: Create/update entity send log columns. * add user message info to create new recrod. Co-authored-by: EdwinBetanc0urt --- .../ADempiere/DataTable/dataTables-Script.js | 20 ++++++-- src/components/ADempiere/Field/index.vue | 14 +++++- .../ADempiere/Panel/mainPanelMixin.js | 5 +- src/store/modules/ADempiere/panel/getters.js | 48 ++++++++++++++++--- src/store/modules/ADempiere/persistence.js | 27 ++++++++--- .../ADempiere/windowControl/actions.js | 9 +++- src/utils/ADempiere/dataUtils.js | 39 +++++++++++++++ 7 files changed, 143 insertions(+), 19 deletions(-) diff --git a/src/components/ADempiere/DataTable/dataTables-Script.js b/src/components/ADempiere/DataTable/dataTables-Script.js index f80c69d9..c608b99b 100644 --- a/src/components/ADempiere/DataTable/dataTables-Script.js +++ b/src/components/ADempiere/DataTable/dataTables-Script.js @@ -9,6 +9,7 @@ import { formatField } from '@/utils/ADempiere/valueFormat' import MainPanel from '@/components/ADempiere/Panel' import { sortFields } from '@/utils/ADempiere/dictionaryUtils' import { FIELDS_DECIMALS, FIELDS_QUANTITY, FIELDS_READ_ONLY_FORM } from '@/utils/ADempiere/references' +import { LOG_COLUMNS_NAME_LIST } from '@/utils/ADempiere/dataUtils.js' import { fieldIsDisplayed } from '@/utils/ADempiere' import evaluator from '@/utils/ADempiere/evaluator' import TableMixin from './mixin/tableMixin.js' @@ -388,7 +389,8 @@ export default { return false } } - // if isReadOnly, isReadOnlyFromLogic + + // if isReadOnly, isReadOnlyFromLogic, or columns log if (this.isReadOnlyCell(record, fieldAttributes)) { return false } @@ -420,14 +422,25 @@ export default { } return false }, + /** + * Idicate if cell is read only + * TODO: Create common method to evaluate isReadOnly + */ isReadOnlyCell(row, field) { // TODO: Add support to its type fields if (['FieldImage', 'FieldBinary'].includes(field.componentPath)) { return true } + // records in columns manage by backend + const isLogColumns = LOG_COLUMNS_NAME_LIST.includes(field.columnName) + const isUpdateableAllFields = field.isReadOnly || field.isReadOnlyFromLogic if (this.isPanelWindow) { + if (isLogColumns) { + return true + } + const panelMetadata = this.panelMetadata if (field.columnName === panelMetadata.linkColumnName || field.columnName === panelMetadata.fieldLinkColumnName) { @@ -438,10 +451,11 @@ export default { return (!field.isUpdateable && editMode) || (isUpdateableAllFields || field.isReadOnlyFromForm) } else if (this.panelType === 'browser') { // browser result - return field.isReadOnly + return field.isReadOnly || isLogColumns } + // other type of panels (process/reports/forms) - return isUpdateableAllFields + return Boolean(isUpdateableAllFields) }, callOffNewRecord() { this.recordsData.shift() diff --git a/src/components/ADempiere/Field/index.vue b/src/components/ADempiere/Field/index.vue index fdf25216..743104b8 100644 --- a/src/components/ADempiere/Field/index.vue +++ b/src/components/ADempiere/Field/index.vue @@ -80,6 +80,7 @@ import translated from '@/components/ADempiere/Field/popover/translated' import calculator from '@/components/ADempiere/Field/popover/calculator' import { DEFAULT_SIZE } from '@/utils/ADempiere/references' import { evalutateTypeField, fieldIsDisplayed } from '@/utils/ADempiere/dictionaryUtils' +import { LOG_COLUMNS_NAME_LIST } from '@/utils/ADempiere/dataUtils.js' /** * This is the base component for linking the components according to the @@ -206,6 +207,10 @@ export default { } return this.field.isMandatory || this.field.isMandatoryFromLogic }, + /** + * Idicate if field is read only + * TODO: Create common method to evaluate isReadOnly + */ isReadOnly() { if (this.isAdvancedQuery) { if (['NULL', 'NOT_NULL'].includes(this.field.operator)) { @@ -218,9 +223,16 @@ export default { return true } + // records in columns manage by backend + const isLogColumns = LOG_COLUMNS_NAME_LIST.includes(this.field.columnName) + const isUpdateableAllFields = this.field.isReadOnly || this.field.isReadOnlyFromLogic if (this.field.panelType === 'window') { + if (isLogColumns) { + return true + } + if (this.field.isAlwaysUpdateable) { return false } @@ -240,7 +252,7 @@ export default { } else if (this.field.panelType === 'browser') { if (this.inTable) { // browser result - return this.field.isReadOnly + return this.field.isReadOnly || isLogColumns } // query criteria return this.field.isReadOnlyFromLogic diff --git a/src/components/ADempiere/Panel/mainPanelMixin.js b/src/components/ADempiere/Panel/mainPanelMixin.js index 27d53de9..44aa9166 100644 --- a/src/components/ADempiere/Panel/mainPanelMixin.js +++ b/src/components/ADempiere/Panel/mainPanelMixin.js @@ -3,6 +3,7 @@ import FilterFields from '@/components/ADempiere/Panel/filterFields' import { fieldIsDisplayed } from '@/utils/ADempiere/dictionaryUtils.js' import { parsedValueComponent } from '@/utils/ADempiere/valueUtils.js' import { convertObjectToKeyValue } from '@/utils/ADempiere/valueFormat.js' +import { LOG_COLUMNS_NAME_LIST } from '@/utils/ADempiere/dataUtils.js' export default { name: 'MainPanelMixin', @@ -536,7 +537,9 @@ export default { } if (Object.prototype.hasOwnProperty.call(this.$refs, itemField.columnName)) { if (fieldIsDisplayed(itemField) && - !itemField.isReadOnly && + !(itemField.isReadOnly || + // records in columns manage by backend + LOG_COLUMNS_NAME_LIST.includes(itemField.columnName)) && itemField.isUpdateable && itemField.componentPath !== 'FieldSelect') { return true diff --git a/src/store/modules/ADempiere/panel/getters.js b/src/store/modules/ADempiere/panel/getters.js index ade6f6b1..91085534 100644 --- a/src/store/modules/ADempiere/panel/getters.js +++ b/src/store/modules/ADempiere/panel/getters.js @@ -7,6 +7,7 @@ import { fieldIsDisplayed, getDefaultValue } from '@/utils/ADempiere/dictionaryUtils.js' +import { LOG_COLUMNS_NAME_LIST } from '@/utils/ADempiere/dataUtils.js' const getters = { getPanel: (state) => (containerUuid) => { @@ -15,6 +16,7 @@ const getters = { return item.containerUuid === containerUuid }) }, + getFieldsListFromPanel: (state, getters) => (containerUuid) => { const panel = getters.getPanel(containerUuid) if (isEmptyValue(panel)) { @@ -22,11 +24,13 @@ const getters = { } return panel.fieldsList }, + getFieldFromColumnName: (state, getters) => ({ containerUuid, columnName }) => { return getters.getFieldsListFromPanel(containerUuid).find(itemField => { return itemField.columnName === columnName }) }, + /** * Determinate if panel is ready fron send, all fiedls mandatory and displayed with values * @param {string} containerUuid @@ -41,6 +45,12 @@ const getters = { const isDisplayed = fieldIsDisplayed(fieldItem) && (fieldItem.isShowedFromUser || isMandatory) const { columnName } = fieldItem + + // Omit log columns list only created or updated record, this is manage for backend + if (fieldItem.panelType === 'window' && LOG_COLUMNS_NAME_LIST.includes(columnName)) { + return false + } + if (isDisplayed && isMandatory) { let value // used when evaluate data in table @@ -62,37 +72,56 @@ const getters = { return fieldNotReadyToSend }, - // Obtain empty obligatory fields + + /** + * Obtain empty obligatory fields + * @param {string} containerUuid + * @param {array} fieldsList + * @param {string} formatReturn + */ getFieldsListEmptyMandatory: (state, getters) => ({ containerUuid, - fieldsList + fieldsList, + formatReturn = 'name' }) => { if (isEmptyValue(fieldsList)) { fieldsList = getters.getFieldsListFromPanel(containerUuid) } - const fieldsEmpty = [] + // all optionals (not mandatory) fields - fieldsList.forEach(fieldItem => { + const fieldsNameEmpty = fieldsList.filter(fieldItem => { const value = getters.getValueOfField({ parentUuid: fieldItem.parentUuid, containerUuid, columnName: fieldItem.columnName }) + if (isEmptyValue(value)) { const isMandatory = fieldItem.isMandatory || fieldItem.isMandatoryFromLogic if (fieldIsDisplayed(fieldItem) && isMandatory) { - fieldsEmpty.push(fieldItem.name) + return true } } }) - return fieldsEmpty + + if (formatReturn) { + return fieldsList.map(fieldItem => { + return fieldItem[formatReturn] + }) + } + + return fieldsNameEmpty }, + /** * Show all available fields not mandatory to show, used in components panel/filterFields.vue * @param {string} containerUuid * @param {boolean} isEvaluateShowed */ - getFieldsListNotMandatory: (state, getters) => ({ containerUuid, isEvaluateShowed = true }) => { + getFieldsListNotMandatory: (state, getters) => ({ + containerUuid, + isEvaluateShowed = true + }) => { // all optionals (not mandatory) fields return getters.getFieldsListFromPanel(containerUuid).filter(fieldItem => { const isMandatory = fieldItem.isMandatory || fieldItem.isMandatoryFromLogic @@ -104,6 +133,7 @@ const getters = { } }) }, + /** * @param {string} containerUuid, unique identifier of the panel to search your list of fields * @param {string} propertyName, property name to return its value (value, oldValue) @@ -193,6 +223,7 @@ const getters = { } return attributesList }, + getParsedDefaultValues: (state, getters) => ({ parentUuid, containerUuid, @@ -271,6 +302,7 @@ const getters = { } return attributesObject }, + getFieldsIsDisplayed: (state, getters) => (containerUuid) => { const fieldsList = getters.getFieldsListFromPanel(containerUuid) let fieldsIsDisplayed = [] @@ -291,6 +323,7 @@ const getters = { isDisplayed: Boolean(fieldsIsDisplayed.length) } }, + getParametersToShare: (state, getters) => ({ containerUuid, withOut = [], @@ -341,6 +374,7 @@ const getters = { return attributesListLink.slice(0, -1) }, + /** * Getter converter selection params with value format * @param {String} containerUuid diff --git a/src/store/modules/ADempiere/persistence.js b/src/store/modules/ADempiere/persistence.js index c6203a43..607b380c 100644 --- a/src/store/modules/ADempiere/persistence.js +++ b/src/store/modules/ADempiere/persistence.js @@ -3,6 +3,9 @@ import { requestUpdateEntity } from '@/api/ADempiere/persistence.js' import { isEmptyValue } from '@/utils/ADempiere/valueUtils.js' +import { LOG_COLUMNS_NAME_LIST } from '@/utils/ADempiere/dataUtils.js' +import language from '@/lang' +import { showMessage } from '@/utils/ADempiere/notification.js' const persistence = { state: { @@ -38,14 +41,19 @@ const persistence = { recordUuid }) { return new Promise((resolve, reject) => { - let attributes = getters.getPersistenceAttributes(containerUuid) - if (attributes) { + let attributesList = getters.getPersistenceAttributes(containerUuid) + .filter(itemField => { + // omit send to server (to create or update) columns manage by backend + return !LOG_COLUMNS_NAME_LIST.includes(itemField.columnName) + }) + + if (attributesList) { if (recordUuid) { // Update existing entity requestUpdateEntity({ tableName, recordUuid, - attributesList: attributes + attributesList }) .then(response => { dispatch('listRecordLogs', { @@ -57,14 +65,21 @@ const persistence = { }) .catch(error => reject(error)) } else { - attributes = attributes.filter(itemAttribute => !isEmptyValue(itemAttribute.value)) + attributesList = attributesList.filter(itemAttribute => !isEmptyValue(itemAttribute.value)) // Create new entity requestCreateEntity({ tableName, - attributesList: attributes + attributesList }) - .then(response => resolve(response)) + .then(response => { + showMessage({ + message: language.t('data.createRecordSuccessful'), + type: 'success' + }) + + resolve(response) + }) .catch(error => reject(error)) } } diff --git a/src/store/modules/ADempiere/windowControl/actions.js b/src/store/modules/ADempiere/windowControl/actions.js index e14bbae0..3f513b9f 100644 --- a/src/store/modules/ADempiere/windowControl/actions.js +++ b/src/store/modules/ADempiere/windowControl/actions.js @@ -12,6 +12,7 @@ import { showMessage } from '@/utils/ADempiere/notification' import language from '@/lang' import router from '@/router' import { convertObjectToKeyValue } from '@/utils/ADempiere/valueFormat.js' +import { LOG_COLUMNS_NAME_LIST } from '@/utils/ADempiere/dataUtils.js' /** * Window Control Vuex Module @@ -126,8 +127,14 @@ export default { value }) const emptyFields = getters.getFieldsListEmptyMandatory({ - containerUuid: field.containerUuid + containerUuid: field.containerUuid, + formatReturn: false + }).filter(itemField => { + return !LOG_COLUMNS_NAME_LIST.includes(itemField.columnName) + }).map(itemField => { + return itemField.name }) + if (!isEmptyValue(emptyFields)) { showMessage({ message: language.t('notifications.mandatoryFieldMissing') + emptyFields, diff --git a/src/utils/ADempiere/dataUtils.js b/src/utils/ADempiere/dataUtils.js index d084d6d1..2f709095 100644 --- a/src/utils/ADempiere/dataUtils.js +++ b/src/utils/ADempiere/dataUtils.js @@ -192,3 +192,42 @@ export const FIELD_OPERATORS_LIST = [ OPERATORS_FIELD_TIME, OPERATORS_FIELD_YES_NO ] + +/** + * Log columns list into table + * Manages with user session + */ +export const LOG_COLUMNS_NAME_LIST = [ + 'Created', + 'CreatedBy', + 'Updated', + 'UpdatedBy' +] + +/** + * Columns list into standard table + */ +export const STANDARD_COLUMNS_NAME_LIST = [ + ...LOG_COLUMNS_NAME_LIST, + // Table Name '_ID' + 'AD_Client_ID', + 'AD_Org_ID', + 'IsActive', + 'UUID' +] + +/** + * Columns list into document table + */ +export const DOCUMENT_COLUMNS_NAME_LIST = [ + ...STANDARD_COLUMNS_NAME_LIST, + 'C_DocType_ID', + 'DateDoc', + 'Description', + 'DocAction', + 'DocStatus', + 'DocumentNo', + 'IsApproved', + 'Processed', + 'Processing' +]