From beaaf31d9aaf680149cfdc599d81b0de0a81a5de Mon Sep 17 00:00:00 2001 From: hengsin Date: Wed, 12 May 2021 19:42:55 +0800 Subject: [PATCH] IDEMPIERE-4771 add Cloud Upload interface to report viewer and scheduler (#679) * IDEMPIERE-4771 add Cloud Upload interface to report viewer and scheduler * IDEMPIERE-4771 add Cloud Upload interface to report viewer and scheduler Fix initial output type selection for csv. Fix handling of binary vs text media type. * IDEMPIERE-4771 add Cloud Upload interface to report viewer and scheduler - Change AD_AuthorizationAccount scope from single value to multiple selection list (AD_AuthorizationScopes replace AD_AuthorizationScope) * IDEMPIERE-4771 add Cloud Upload interface to report viewer and scheduler Fix isIntersectCSV db function * IDEMPIERE-4771 add Cloud Upload interface to report viewer and scheduler add back AD_AuthorizationScope Configured dynamic validation filter --- .../oracle/functions/isIntersectCSV.sql | 11 + .../postgresql/functions/isIntersectCSV.sql | 33 ++ .../oracle/202105091048_IDEMPIERE-4771.sql | 263 +++++++++ .../202105091048_IDEMPIERE-4771.sql | 266 +++++++++ org.adempiere.base/META-INF/MANIFEST.MF | 1 + .../src/org/adempiere/base/Core.java | 37 ++ .../adempiere/base/upload/IUploadHandler.java | 50 ++ .../adempiere/base/upload/IUploadService.java | 41 ++ .../adempiere/base/upload/UploadMedia.java | 90 ++++ .../adempiere/base/upload/UploadResponse.java | 65 +++ .../model/I_AD_AuthorizationAccount.java | 12 +- .../model/I_AD_SchedulerRecipient.java | 33 ++ .../compiere/model/MAuthorizationAccount.java | 21 +- .../model/MAuthorizationCredential.java | 66 ++- .../org/compiere/model/MLookupFactory.java | 13 +- .../src/org/compiere/model/MScheduler.java | 31 +- .../compiere/model/MSchedulerRecipient.java | 16 + .../model/X_AD_AuthorizationAccount.java | 32 +- .../model/X_AD_SchedulerRecipient.java | 67 ++- .../process/AddAuthorizationProcess.java | 10 +- .../src/org/compiere/util/EMail.java | 11 + .../server/org/compiere/server/Scheduler.java | 186 ++++++- .../adempiere/webui/report/LinkWindow.java | 79 +++ .../window/IReportViewerExportSource.java | 115 ++++ .../webui/window/WReportExportDialog.java | 196 +++++++ .../webui/window/WReportUploadDialog.java | 305 +++++++++++ .../adempiere/webui/window/ZkJRViewer.java | 495 +++++++++++------ .../webui/window/ZkReportViewer.java | 505 ++++++++++-------- .../src/org/compiere/db/DB_Oracle.java | 12 +- .../src/org/compiere/db/DB_PostgreSQL.java | 14 +- 30 files changed, 2618 insertions(+), 458 deletions(-) create mode 100644 db/ddlutils/oracle/functions/isIntersectCSV.sql create mode 100644 db/ddlutils/postgresql/functions/isIntersectCSV.sql create mode 100644 migration/i8.2z/oracle/202105091048_IDEMPIERE-4771.sql create mode 100644 migration/i8.2z/postgresql/202105091048_IDEMPIERE-4771.sql create mode 100644 org.adempiere.base/src/org/adempiere/base/upload/IUploadHandler.java create mode 100644 org.adempiere.base/src/org/adempiere/base/upload/IUploadService.java create mode 100644 org.adempiere.base/src/org/adempiere/base/upload/UploadMedia.java create mode 100644 org.adempiere.base/src/org/adempiere/base/upload/UploadResponse.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/report/LinkWindow.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/IReportViewerExportSource.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WReportExportDialog.java create mode 100644 org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WReportUploadDialog.java diff --git a/db/ddlutils/oracle/functions/isIntersectCSV.sql b/db/ddlutils/oracle/functions/isIntersectCSV.sql new file mode 100644 index 0000000000..1d93836fc7 --- /dev/null +++ b/db/ddlutils/oracle/functions/isIntersectCSV.sql @@ -0,0 +1,11 @@ +CREATE or REPLACE FUNCTION isIntersectCSV( p_csv1 IN VARCHAR2 , p_csv2 IN VARCHAR2) +RETURN CHAR AS +BEGIN + IF toTableOfVarchar2(p_csv1) MULTISET INTERSECT toTableOfVarchar2(p_csv2) IS NOT EMPTY + THEN + RETURN 'Y'; + ELSE + RETURN 'N'; + END IF; +END; +/ diff --git a/db/ddlutils/postgresql/functions/isIntersectCSV.sql b/db/ddlutils/postgresql/functions/isIntersectCSV.sql new file mode 100644 index 0000000000..4cb16e8731 --- /dev/null +++ b/db/ddlutils/postgresql/functions/isIntersectCSV.sql @@ -0,0 +1,33 @@ +/* +*This program is free software; you can redistribute it and/or +*modify it under the terms of the GNU General Public License +*as published by the Free Software Foundation; either version 2 +*of the License, or (at your option) any later version. +* +*This program is distributed in the hope that it will be useful, +*but WITHOUT ANY WARRANTY; without even the implied warranty of +*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +*GNU General Public License for more details. +* +*You should have received a copy of the GNU General Public License +*along with this program; if not, write to the Free Software +*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.of +*/ +CREATE OR REPLACE FUNCTION isintersectcsv( + p_csv1 character varying, + p_csv2 character varying) + RETURNS char + LANGUAGE 'plpgsql' + COST 100 + STABLE PARALLEL SAFE +AS $BODY$ +begin + IF string_to_array(p_csv1, ',') && string_to_array(p_csv2, ',') + THEN + RETURN 'Y'; + ELSE + RETURN 'N'; + END IF; +end; +$BODY$; + diff --git a/migration/i8.2z/oracle/202105091048_IDEMPIERE-4771.sql b/migration/i8.2z/oracle/202105091048_IDEMPIERE-4771.sql new file mode 100644 index 0000000000..c6b1a34fa4 --- /dev/null +++ b/migration/i8.2z/oracle/202105091048_IDEMPIERE-4771.sql @@ -0,0 +1,263 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- May 6, 2021, 5:49:33 PM MYT +UPDATE AD_Process SET Name='Add Authorization Account',Updated=TO_DATE('2021-05-06 17:49:33','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200128 +; + +-- May 6, 2021, 5:49:33 PM MYT +UPDATE AD_Menu SET Name='Add Authorization Account', Description=NULL, IsActive='Y',Updated=TO_DATE('2021-05-06 17:49:33','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Menu_ID=200182 +; + +-- May 6, 2021, 8:35:15 PM MYT +UPDATE AD_Process_Para SET ReadOnlyLogic=NULL,Updated=TO_DATE('2021-05-06 20:35:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200335 +; + +-- May 6, 2021, 8:42:25 PM MYT +UPDATE AD_Val_Rule SET Code='AD_Ref_List.Value IN ( +SELECT DISTINCT asp.AD_AuthorizationScope +FROM AD_AuthorizationScopeProv asp +WHERE asp.IsActive=''Y'' + AND asp.AD_Client_ID IN (0,@#AD_Client_ID@) + AND EXISTS (SELECT 1 + FROM AD_AuthorizationCredential ac + JOIN AD_AuthorizationProvider ap ON (ac.AD_AuthorizationProvider_ID=ap.AD_AuthorizationProvider_ID + AND ap.IsActive=''Y'' + AND ap.AD_Client_ID IN (0,@#AD_Client_ID@)) + WHERE ac.AD_AuthorizationProvider_ID=asp.AD_AuthorizationProvider_ID + AND ac.IsActive=''Y'' + AND ac.AD_AuthorizationScopeList LIKE ''%''||asp.AD_AuthorizationScope||''%'' + AND ac.AD_Client_ID IN (0,@#AD_Client_ID@)) +)',Updated=TO_DATE('2021-05-06 20:42:25','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Val_Rule_ID=200145 +; + +-- May 7, 2021, 4:28:29 PM MYT +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203484,0,0,'Y',TO_DATE('2021-05-07 16:28:28','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-07 16:28:28','YYYY-MM-DD HH24:MI:SS'),100,'IsUpload','Upload','Upload','D','80633b80-bba3-461e-82d1-2514d1d6186c') +; + +-- May 7, 2021, 4:29:46 PM MYT +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (214423,0,'Upload',704,'IsUpload','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_DATE('2021-05-07 16:29:45','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-07 16:29:45','YYYY-MM-DD HH24:MI:SS'),100,203484,'Y','N','D','N','N','N','Y','2ee1e970-758a-4a0d-b318-5854fc61e2a0','N',0,'N','N','N','N') +; + +-- May 7, 2021, 4:29:51 PM MYT +ALTER TABLE AD_SchedulerRecipient ADD IsUpload CHAR(1) DEFAULT 'N' CHECK (IsUpload IN ('Y','N')) NOT NULL +; + +-- May 7, 2021, 4:35:11 PM MYT +INSERT INTO AD_Val_Rule (AD_Val_Rule_ID,Name,Type,Code,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Val_Rule_UU) VALUES (200148,'AD_AuthorizationAccount of User (Document Scope)','S','AD_AuthorizationAccount.AD_User_ID=@AD_User_ID@ AND AD_AuthorizationAccount.AD_AuthorizationScope=''Document''',0,0,'Y',TO_DATE('2021-05-07 16:35:10','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-07 16:35:10','YYYY-MM-DD HH24:MI:SS'),100,'D','bd13a10f-26f4-4b2b-9a65-85faf35303e3') +; + +-- May 7, 2021, 4:35:40 PM MYT +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,AD_Val_Rule_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (214424,0,'Authorization Account',704,200148,'AD_AuthorizationAccount_ID',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_DATE('2021-05-07 16:35:39','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-07 16:35:39','YYYY-MM-DD HH24:MI:SS'),100,203467,'N','N','D','N','N','N','Y','5c2d33eb-301d-46c0-a13f-2ad9db1edfb6','N',0,'N','N','N','N') +; + +-- May 7, 2021, 4:35:45 PM MYT +UPDATE AD_Column SET FKConstraintName='ADAuthorizationAccount_ADSched', FKConstraintType='N',Updated=TO_DATE('2021-05-07 16:35:45','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214424 +; + +-- May 7, 2021, 4:35:45 PM MYT +ALTER TABLE AD_SchedulerRecipient ADD AD_AuthorizationAccount_ID NUMBER(10) DEFAULT NULL +; + +-- May 7, 2021, 4:35:45 PM MYT +ALTER TABLE AD_SchedulerRecipient ADD CONSTRAINT ADAuthorizationAccount_ADSched FOREIGN KEY (AD_AuthorizationAccount_ID) REFERENCES ad_authorizationaccount(ad_authorizationaccount_id) DEFERRABLE INITIALLY DEFERRED +; + +-- May 7, 2021, 4:36:35 PM MYT +INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (214425,0,'File Name','Name of the local file or URL','Name of a file in the local directory space - or URL (file://.., http://.., ftp://..)',704,'FileName',255,'N','N','N','N','N',0,'N',10,0,0,'Y',TO_DATE('2021-05-07 16:36:35','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-07 16:36:35','YYYY-MM-DD HH24:MI:SS'),100,2295,'Y','N','D','N','N','N','Y','f1e841ca-64cc-4a76-902c-4dd3b66d96a1','N',0,'N','N','N') +; + +-- May 7, 2021, 4:36:40 PM MYT +ALTER TABLE AD_SchedulerRecipient ADD FileName VARCHAR2(255 CHAR) DEFAULT NULL +; + +-- May 7, 2021, 4:39:09 PM MYT +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLogic,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (206605,'Upload',639,214423,'Y','@AD_User_ID@>0',0,80,0,'N','N','N','N',0,0,'Y',TO_DATE('2021-05-07 16:39:09','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-07 16:39:09','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','46cee751-46b4-42a8-9bc4-b0b3b59c57cb','Y',80,2,1,1,'N','N','N','N') +; + +-- May 7, 2021, 4:40:02 PM MYT +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLogic,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (206606,'Authorization Account',639,214424,'Y','@AD_User_ID@>0 & @IsUpload@=Y',0,90,0,'N','N','N','N',0,0,'Y',TO_DATE('2021-05-07 16:40:02','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-07 16:40:02','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','cb00d48c-7de5-4b12-95a8-39cc402b3eb1','Y',90,1,2,1,'N','N','N','N') +; + +-- May 7, 2021, 4:41:18 PM MYT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLogic,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (206607,'File Name','Name of the local file or URL','Name of a file in the local directory space - or URL (file://.., http://.., ftp://..)',639,214425,'Y','@AD_User_ID@>0 & @IsUpload@=Y',0,100,0,'N','N','N','N',0,0,'Y',TO_DATE('2021-05-07 16:41:17','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-07 16:41:17','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','12be3db7-c8a9-43b0-84a0-3ec1bdbfa517','Y',100,4,2,1,'N','N','N','N') +; + +-- May 8, 2021, 6:12:43 AM MYT +UPDATE AD_Column SET IsIdentifier='Y',Updated=TO_DATE('2021-05-08 06:12:43','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214401 +; + +-- May 8, 2021, 6:12:53 AM MYT +UPDATE AD_Column SET SeqNo=10,Updated=TO_DATE('2021-05-08 06:12:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214401 +; + +-- May 8, 2021, 6:13:07 AM MYT +UPDATE AD_Column SET IsIdentifier='Y', SeqNo=20,Updated=TO_DATE('2021-05-08 06:13:07','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214405 +; + +-- May 9, 2021, 6:36:31 PM MYT +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Cloud Upload',0,0,'Y',TO_DATE('2021-05-09 18:36:30','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-09 18:36:30','YYYY-MM-DD HH24:MI:SS'),100,200677,'CloudUpload','D','a1ecabfa-79fe-47f4-92d9-aad2946a2751') +; + +-- May 9, 2021, 6:37:08 PM MYT +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Upload Failed',0,0,'Y',TO_DATE('2021-05-09 18:37:08','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-09 18:37:08','YYYY-MM-DD HH24:MI:SS'),100,200678,'UploadFailed','D','c7a087f0-7e8d-4896-b99a-d23332a198c0') +; + +-- May 9, 2021, 6:37:42 PM MYT +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Upload Successful',0,0,'Y',TO_DATE('2021-05-09 18:37:41','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-09 18:37:41','YYYY-MM-DD HH24:MI:SS'),100,200679,'UploadSucess','D','2ce61461-c80b-4dae-9c71-a02ea7b749e0') +; + +-- May 9, 2021, 6:39:06 PM MYT +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to send scheduler attachment',0,0,'Y',TO_DATE('2021-05-09 18:39:05','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-09 18:39:05','YYYY-MM-DD HH24:MI:SS'),100,200680,'SchedulerSendAttachmentFailed','D','5216aa31-8089-4500-a580-2afcd5df1916') +; + +-- May 9, 2021, 6:39:44 PM MYT +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to send scheduler notification',0,0,'Y',TO_DATE('2021-05-09 18:39:43','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-09 18:39:43','YYYY-MM-DD HH24:MI:SS'),100,200681,'SchedulerSendNotificationFailed','D','2747dbf7-f04a-479e-b005-d5c9578f46dc') +; + +-- May 9, 2021, 6:40:34 PM MYT +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Upload Action:',0,0,'Y',TO_DATE('2021-05-09 18:40:34','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-09 18:40:34','YYYY-MM-DD HH24:MI:SS'),100,200682,'UploadAction','D','f371db18-d552-47dd-94a5-1622c60eff56') +; + +-- May 10, 2021, 12:29:01 PM CEST +UPDATE AD_Menu SET PredefinedContextVariables='OPEN_POPUP=Y',Updated=TO_DATE('2021-05-10 12:29:01','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Menu_ID=200182 +; + +-- May 10, 2021, 12:29:15 PM CEST +UPDATE AD_Process_Para SET DefaultValue=NULL,Updated=TO_DATE('2021-05-10 12:29:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200335 +; + +-- May 11, 2021, 11:57:58 AM MYT +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203485,0,0,'Y',TO_DATE('2021-05-11 11:57:57','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-11 11:57:57','YYYY-MM-DD HH24:MI:SS'),100,'AD_AuthorizationScopes','Authorization Scopes','Authorization Scopes','D','2a60a4ce-76ce-41ca-b70d-b0b6942d927c') +; + +-- May 11, 2021, 11:59:29 AM MYT +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Reference_Value_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (214426,0,'Authorization Scopes',200272,'AD_AuthorizationScopes',255,'N','N','N','N','N',0,'N',200161,200185,0,0,'Y',TO_DATE('2021-05-11 11:59:29','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-11 11:59:29','YYYY-MM-DD HH24:MI:SS'),100,203485,'Y','N','D','N','N','N','Y','a7c3b27c-e0a7-4a5c-8d39-50f0171faaaa','Y',0,'N','N','N') +; + +-- May 11, 2021, 11:59:39 AM MYT +ALTER TABLE AD_AuthorizationAccount ADD AD_AuthorizationScopes VARCHAR2(255 CHAR) DEFAULT NULL +; + +-- May 11, 2021, 12:00:20 PM MYT +UPDATE AD_Column SET IsActive='N',Updated=TO_DATE('2021-05-11 12:00:20','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214405 +; + +-- May 11, 2021, 12:02:31 PM MYT +UPDATE AD_Val_Rule SET Code='AD_AuthorizationAccount.AD_User_ID=@AD_User_ID@ AND AD_AuthorizationAccount.AD_AuthorizationScope LIKE ''%Document%''',Updated=TO_DATE('2021-05-11 12:02:31','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Val_Rule_ID=200148 +; + +-- May 11, 2021, 12:03:38 PM MYT +UPDATE AD_Field SET IsActive='N', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-05-11 12:03:38','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206584 +; + +-- May 11, 2021, 12:04:27 PM MYT +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (206608,'Authorization Scopes',200287,214426,'Y',0,150,0,'N','N','N','N',0,0,'Y',TO_DATE('2021-05-11 12:04:26','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-05-11 12:04:26','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','46115123-9361-4b50-aa79-19ac62b5bf35','Y',120,1,2,1,'N','N','N','N') +; + +-- May 11, 2021, 12:04:47 PM MYT +UPDATE AD_Field SET SeqNo=0,IsDisplayed='N', Updated=getDate(), UpdatedBy=100 WHERE AD_Field_ID=206584 +; + +-- May 11, 2021, 12:04:47 PM MYT +UPDATE AD_Field SET SeqNo=40,IsDisplayed='Y', Updated=getDate(), UpdatedBy=100 WHERE AD_Field_ID=206608 +; + +-- May 11, 2021, 12:05:01 PM MYT +UPDATE AD_Field SET SeqNoGrid=0,IsDisplayedGrid='N', Updated=getDate(), UpdatedBy=100 WHERE AD_Field_ID=206584 +; + +-- May 11, 2021, 12:05:01 PM MYT +UPDATE AD_Field SET SeqNoGrid=50,IsDisplayedGrid='Y', Updated=getDate(), UpdatedBy=100 WHERE AD_Field_ID=206608 +; + +-- May 11, 2021, 12:08:35 PM MYT +UPDATE AD_Process_Para SET Name='Authorization Scopes', Description=NULL, Help=NULL, AD_Reference_ID=200161, AD_Val_Rule_ID=NULL, FieldLength=255, ColumnName='AD_AuthorizationScopes', AD_Element_ID=203485,Updated=TO_DATE('2021-05-11 12:08:35','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200335 +; + +-- May 11, 2021, 3:15:50 PM MYT +UPDATE AD_Val_Rule SET Code='AD_AuthorizationCredential.AD_Client_ID IN (0,@#AD_Client_ID@) AND +AD_AuthorizationCredential.IsActive=''Y'' AND +isIntersectCSV(AD_AuthorizationCredential.AD_AuthorizationScopeList,''@AD_AuthorizationScopes@'')=''Y'' AND +EXISTS ( + SELECT 1 + FROM AD_AuthorizationScopeProv asp + JOIN AD_AuthorizationProvider ap ON (asp.AD_AuthorizationProvider_ID=ap.AD_AuthorizationProvider_ID + AND ap.IsActive=''Y'' + AND ap.AD_Client_ID IN (0,@#AD_Client_ID@)) + WHERE asp.AD_AuthorizationProvider_ID=AD_AuthorizationCredential.AD_AuthorizationProvider_ID + AND isIntersectCSV(asp.AD_AuthorizationScope,''@AD_AuthorizationScopes@'')=''Y'' + AND asp.IsActive=''Y'' + AND asp.AD_Client_ID IN (0,@#AD_Client_ID@))',Updated=TO_DATE('2021-05-11 15:15:50','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Val_Rule_ID=200146 +; + +UPDATE AD_AuthorizationAccount SET AD_AuthorizationScopes = AD_AuthorizationScope, UPDATED=SYSDATE WHERE AD_AuthorizationScope IS NOT NULL AND AD_AuthorizationScopes IS NULL +; + +-- May 11, 2021, 3:59:13 PM MYT +UPDATE AD_Val_Rule SET Code='AD_AuthorizationAccount.AD_User_ID=@AD_User_ID@ AND isIntersectCSV(AD_AuthorizationAccount.AD_AuthorizationScopes,''Document'')=''Y''',Updated=TO_DATE('2021-05-11 15:59:13','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Val_Rule_ID=200148 +; + +-- May 11, 2021, 4:00:25 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-05-11 16:00:25','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206608 +; + +-- May 11, 2021, 4:00:29 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-05-11 16:00:29','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206585 +; + +-- May 11, 2021, 4:00:37 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-05-11 16:00:37','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206587 +; + +-- May 11, 2021, 4:00:40 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-05-11 16:00:40','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206588 +; + +-- May 11, 2021, 4:00:44 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-05-11 16:00:44','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206590 +; + +-- May 11, 2021, 4:00:47 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-05-11 16:00:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206591 +; + +-- May 11, 2021, 4:00:53 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-05-11 16:00:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206592 +; + +-- May 11, 2021, 4:00:56 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-05-11 16:00:56','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206593 +; + +-- May 11, 2021, 4:01:57 PM MYT +UPDATE AD_Tab SET IsInsertRecord='N',Updated=TO_DATE('2021-05-11 16:01:57','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=200287 +; + +-- May 11, 2021, 4:04:39 PM MYT +UPDATE AD_Column SET IsIdentifier='N', SeqNo=0,Updated=TO_DATE('2021-05-11 16:04:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214405 +; + +-- May 11, 2021, 4:04:54 PM MYT +UPDATE AD_Column SET IsIdentifier='Y', SeqNo=20,Updated=TO_DATE('2021-05-11 16:04:54','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214426 +; + +CREATE or REPLACE FUNCTION isIntersectCSV( p_csv1 IN VARCHAR2 , p_csv2 IN VARCHAR2) +RETURN CHAR AS +BEGIN + IF toTableOfVarchar2(p_csv1) MULTISET INTERSECT toTableOfVarchar2(p_csv2) IS NOT EMPTY + THEN + RETURN 'Y'; + ELSE + RETURN 'N'; + END IF; +END; +/ + +-- May 12, 2021, 2:21:40 PM MYT +UPDATE AD_Process_Para SET AD_Val_Rule_ID=200145,Updated=TO_DATE('2021-05-12 14:21:40','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200335 +; + +SELECT Register_Migration_Script ('202105091048_IDEMPIERE-4771.sql') FROM DUAL +; + diff --git a/migration/i8.2z/postgresql/202105091048_IDEMPIERE-4771.sql b/migration/i8.2z/postgresql/202105091048_IDEMPIERE-4771.sql new file mode 100644 index 0000000000..16abf96505 --- /dev/null +++ b/migration/i8.2z/postgresql/202105091048_IDEMPIERE-4771.sql @@ -0,0 +1,266 @@ +-- May 6, 2021, 5:49:33 PM MYT +UPDATE AD_Process SET Name='Add Authorization Account',Updated=TO_TIMESTAMP('2021-05-06 17:49:33','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200128 +; + +-- May 6, 2021, 5:49:33 PM MYT +UPDATE AD_Menu SET Name='Add Authorization Account', Description=NULL, IsActive='Y',Updated=TO_TIMESTAMP('2021-05-06 17:49:33','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Menu_ID=200182 +; + +-- May 6, 2021, 8:35:15 PM MYT +UPDATE AD_Process_Para SET ReadOnlyLogic=NULL,Updated=TO_TIMESTAMP('2021-05-06 20:35:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200335 +; + +-- May 6, 2021, 8:42:25 PM MYT +UPDATE AD_Val_Rule SET Code='AD_Ref_List.Value IN ( +SELECT DISTINCT asp.AD_AuthorizationScope +FROM AD_AuthorizationScopeProv asp +WHERE asp.IsActive=''Y'' + AND asp.AD_Client_ID IN (0,@#AD_Client_ID@) + AND EXISTS (SELECT 1 + FROM AD_AuthorizationCredential ac + JOIN AD_AuthorizationProvider ap ON (ac.AD_AuthorizationProvider_ID=ap.AD_AuthorizationProvider_ID + AND ap.IsActive=''Y'' + AND ap.AD_Client_ID IN (0,@#AD_Client_ID@)) + WHERE ac.AD_AuthorizationProvider_ID=asp.AD_AuthorizationProvider_ID + AND ac.IsActive=''Y'' + AND ac.AD_AuthorizationScopeList LIKE ''%''||asp.AD_AuthorizationScope||''%'' + AND ac.AD_Client_ID IN (0,@#AD_Client_ID@)) +)',Updated=TO_TIMESTAMP('2021-05-06 20:42:25','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Val_Rule_ID=200145 +; + +-- May 7, 2021, 4:28:29 PM MYT +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203484,0,0,'Y',TO_TIMESTAMP('2021-05-07 16:28:28','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-07 16:28:28','YYYY-MM-DD HH24:MI:SS'),100,'IsUpload','Upload','Upload','D','80633b80-bba3-461e-82d1-2514d1d6186c') +; + +-- May 7, 2021, 4:29:46 PM MYT +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,DefaultValue,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (214423,0,'Upload',704,'IsUpload','N',1,'N','N','Y','N','N',0,'N',20,0,0,'Y',TO_TIMESTAMP('2021-05-07 16:29:45','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-07 16:29:45','YYYY-MM-DD HH24:MI:SS'),100,203484,'Y','N','D','N','N','N','Y','2ee1e970-758a-4a0d-b318-5854fc61e2a0','N',0,'N','N','N','N') +; + +-- May 7, 2021, 4:29:51 PM MYT +ALTER TABLE AD_SchedulerRecipient ADD COLUMN IsUpload CHAR(1) DEFAULT 'N' CHECK (IsUpload IN ('Y','N')) NOT NULL +; + +-- May 7, 2021, 4:35:11 PM MYT +INSERT INTO AD_Val_Rule (AD_Val_Rule_ID,Name,Type,Code,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Val_Rule_UU) VALUES (200148,'AD_AuthorizationAccount of User (Document Scope)','S','AD_AuthorizationAccount.AD_User_ID=@AD_User_ID@ AND AD_AuthorizationAccount.AD_AuthorizationScope=''Document''',0,0,'Y',TO_TIMESTAMP('2021-05-07 16:35:10','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-07 16:35:10','YYYY-MM-DD HH24:MI:SS'),100,'D','bd13a10f-26f4-4b2b-9a65-85faf35303e3') +; + +-- May 7, 2021, 4:35:40 PM MYT +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,AD_Val_Rule_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (214424,0,'Authorization Account',704,200148,'AD_AuthorizationAccount_ID',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_TIMESTAMP('2021-05-07 16:35:39','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-07 16:35:39','YYYY-MM-DD HH24:MI:SS'),100,203467,'N','N','D','N','N','N','Y','5c2d33eb-301d-46c0-a13f-2ad9db1edfb6','N',0,'N','N','N','N') +; + +-- May 7, 2021, 4:35:45 PM MYT +UPDATE AD_Column SET FKConstraintName='ADAuthorizationAccount_ADSched', FKConstraintType='N',Updated=TO_TIMESTAMP('2021-05-07 16:35:45','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214424 +; + +-- May 7, 2021, 4:35:45 PM MYT +ALTER TABLE AD_SchedulerRecipient ADD COLUMN AD_AuthorizationAccount_ID NUMERIC(10) DEFAULT NULL +; + +-- May 7, 2021, 4:35:45 PM MYT +ALTER TABLE AD_SchedulerRecipient ADD CONSTRAINT ADAuthorizationAccount_ADSched FOREIGN KEY (AD_AuthorizationAccount_ID) REFERENCES ad_authorizationaccount(ad_authorizationaccount_id) DEFERRABLE INITIALLY DEFERRED +; + +-- May 7, 2021, 4:36:35 PM MYT +INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (214425,0,'File Name','Name of the local file or URL','Name of a file in the local directory space - or URL (file://.., http://.., ftp://..)',704,'FileName',255,'N','N','N','N','N',0,'N',10,0,0,'Y',TO_TIMESTAMP('2021-05-07 16:36:35','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-07 16:36:35','YYYY-MM-DD HH24:MI:SS'),100,2295,'Y','N','D','N','N','N','Y','f1e841ca-64cc-4a76-902c-4dd3b66d96a1','N',0,'N','N','N') +; + +-- May 7, 2021, 4:36:40 PM MYT +ALTER TABLE AD_SchedulerRecipient ADD COLUMN FileName VARCHAR(255) DEFAULT NULL +; + +-- May 7, 2021, 4:39:09 PM MYT +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLogic,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (206605,'Upload',639,214423,'Y','@AD_User_ID@>0',0,80,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2021-05-07 16:39:09','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-07 16:39:09','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','46cee751-46b4-42a8-9bc4-b0b3b59c57cb','Y',80,2,1,1,'N','N','N','N') +; + +-- May 7, 2021, 4:40:02 PM MYT +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLogic,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (206606,'Authorization Account',639,214424,'Y','@AD_User_ID@>0 & @IsUpload@=Y',0,90,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2021-05-07 16:40:02','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-07 16:40:02','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','cb00d48c-7de5-4b12-95a8-39cc402b3eb1','Y',90,1,2,1,'N','N','N','N') +; + +-- May 7, 2021, 4:41:18 PM MYT +INSERT INTO AD_Field (AD_Field_ID,Name,Description,Help,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLogic,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (206607,'File Name','Name of the local file or URL','Name of a file in the local directory space - or URL (file://.., http://.., ftp://..)',639,214425,'Y','@AD_User_ID@>0 & @IsUpload@=Y',0,100,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2021-05-07 16:41:17','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-07 16:41:17','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','12be3db7-c8a9-43b0-84a0-3ec1bdbfa517','Y',100,4,2,1,'N','N','N','N') +; + +-- May 8, 2021, 6:12:43 AM MYT +UPDATE AD_Column SET IsIdentifier='Y',Updated=TO_TIMESTAMP('2021-05-08 06:12:43','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214401 +; + +-- May 8, 2021, 6:12:53 AM MYT +UPDATE AD_Column SET SeqNo=10,Updated=TO_TIMESTAMP('2021-05-08 06:12:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214401 +; + +-- May 8, 2021, 6:13:07 AM MYT +UPDATE AD_Column SET IsIdentifier='Y', SeqNo=20,Updated=TO_TIMESTAMP('2021-05-08 06:13:07','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214405 +; + +-- May 9, 2021, 6:36:31 PM MYT +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Cloud Upload',0,0,'Y',TO_TIMESTAMP('2021-05-09 18:36:30','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-09 18:36:30','YYYY-MM-DD HH24:MI:SS'),100,200677,'CloudUpload','D','a1ecabfa-79fe-47f4-92d9-aad2946a2751') +; + +-- May 9, 2021, 6:37:08 PM MYT +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Upload Failed',0,0,'Y',TO_TIMESTAMP('2021-05-09 18:37:08','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-09 18:37:08','YYYY-MM-DD HH24:MI:SS'),100,200678,'UploadFailed','D','c7a087f0-7e8d-4896-b99a-d23332a198c0') +; + +-- May 9, 2021, 6:37:42 PM MYT +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Upload Successful',0,0,'Y',TO_TIMESTAMP('2021-05-09 18:37:41','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-09 18:37:41','YYYY-MM-DD HH24:MI:SS'),100,200679,'UploadSucess','D','2ce61461-c80b-4dae-9c71-a02ea7b749e0') +; + +-- May 9, 2021, 6:39:06 PM MYT +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to send scheduler attachment',0,0,'Y',TO_TIMESTAMP('2021-05-09 18:39:05','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-09 18:39:05','YYYY-MM-DD HH24:MI:SS'),100,200680,'SchedulerSendAttachmentFailed','D','5216aa31-8089-4500-a580-2afcd5df1916') +; + +-- May 9, 2021, 6:39:44 PM MYT +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('E','Failed to send scheduler notification',0,0,'Y',TO_TIMESTAMP('2021-05-09 18:39:43','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-09 18:39:43','YYYY-MM-DD HH24:MI:SS'),100,200681,'SchedulerSendNotificationFailed','D','2747dbf7-f04a-479e-b005-d5c9578f46dc') +; + +-- May 9, 2021, 6:40:34 PM MYT +INSERT INTO AD_Message (MsgType,MsgText,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Message_ID,Value,EntityType,AD_Message_UU) VALUES ('I','Upload Action:',0,0,'Y',TO_TIMESTAMP('2021-05-09 18:40:34','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-09 18:40:34','YYYY-MM-DD HH24:MI:SS'),100,200682,'UploadAction','D','f371db18-d552-47dd-94a5-1622c60eff56') +; + +-- May 10, 2021, 12:29:01 PM CEST +UPDATE AD_Menu SET PredefinedContextVariables='OPEN_POPUP=Y',Updated=TO_TIMESTAMP('2021-05-10 12:29:01','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Menu_ID=200182 +; + +-- May 10, 2021, 12:29:15 PM CEST +UPDATE AD_Process_Para SET DefaultValue=NULL,Updated=TO_TIMESTAMP('2021-05-10 12:29:15','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200335 +; + +-- May 11, 2021, 11:57:58 AM MYT +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,PrintName,EntityType,AD_Element_UU) VALUES (203485,0,0,'Y',TO_TIMESTAMP('2021-05-11 11:57:57','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-11 11:57:57','YYYY-MM-DD HH24:MI:SS'),100,'AD_AuthorizationScopes','Authorization Scopes','Authorization Scopes','D','2a60a4ce-76ce-41ca-b70d-b0b6942d927c') +; + +-- May 11, 2021, 11:59:29 AM MYT +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Reference_Value_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (214426,0,'Authorization Scopes',200272,'AD_AuthorizationScopes',255,'N','N','N','N','N',0,'N',200161,200185,0,0,'Y',TO_TIMESTAMP('2021-05-11 11:59:29','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-11 11:59:29','YYYY-MM-DD HH24:MI:SS'),100,203485,'Y','N','D','N','N','N','Y','a7c3b27c-e0a7-4a5c-8d39-50f0171faaaa','Y',0,'N','N','N') +; + +-- May 11, 2021, 11:59:39 AM MYT +ALTER TABLE AD_AuthorizationAccount ADD COLUMN AD_AuthorizationScopes VARCHAR(255) DEFAULT NULL +; + +-- May 11, 2021, 12:00:20 PM MYT +UPDATE AD_Column SET IsActive='N',Updated=TO_TIMESTAMP('2021-05-11 12:00:20','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214405 +; + +-- May 11, 2021, 12:02:31 PM MYT +UPDATE AD_Val_Rule SET Code='AD_AuthorizationAccount.AD_User_ID=@AD_User_ID@ AND AD_AuthorizationAccount.AD_AuthorizationScope LIKE ''%Document%''',Updated=TO_TIMESTAMP('2021-05-11 12:02:31','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Val_Rule_ID=200148 +; + +-- May 11, 2021, 12:03:38 PM MYT +UPDATE AD_Field SET IsActive='N', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-05-11 12:03:38','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206584 +; + +-- May 11, 2021, 12:04:27 PM MYT +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,SortNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,XPosition,ColumnSpan,NumLines,IsQuickEntry,IsDefaultFocus,IsAdvancedField,IsQuickForm) VALUES (206608,'Authorization Scopes',200287,214426,'Y',0,150,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2021-05-11 12:04:26','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-05-11 12:04:26','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','46115123-9361-4b50-aa79-19ac62b5bf35','Y',120,1,2,1,'N','N','N','N') +; + +-- May 11, 2021, 12:04:47 PM MYT +UPDATE AD_Field SET SeqNo=0,IsDisplayed='N', Updated=statement_timestamp(), UpdatedBy=100 WHERE AD_Field_ID=206584 +; + +-- May 11, 2021, 12:04:47 PM MYT +UPDATE AD_Field SET SeqNo=40,IsDisplayed='Y', Updated=statement_timestamp(), UpdatedBy=100 WHERE AD_Field_ID=206608 +; + +-- May 11, 2021, 12:05:01 PM MYT +UPDATE AD_Field SET SeqNoGrid=0,IsDisplayedGrid='N', Updated=statement_timestamp(), UpdatedBy=100 WHERE AD_Field_ID=206584 +; + +-- May 11, 2021, 12:05:01 PM MYT +UPDATE AD_Field SET SeqNoGrid=50,IsDisplayedGrid='Y', Updated=statement_timestamp(), UpdatedBy=100 WHERE AD_Field_ID=206608 +; + +-- May 11, 2021, 12:08:35 PM MYT +UPDATE AD_Process_Para SET Name='Authorization Scopes', Description=NULL, Help=NULL, AD_Reference_ID=200161, AD_Val_Rule_ID=NULL, FieldLength=255, ColumnName='AD_AuthorizationScopes', AD_Element_ID=203485,Updated=TO_TIMESTAMP('2021-05-11 12:08:35','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200335 +; + +-- May 11, 2021, 3:15:50 PM MYT +UPDATE AD_Val_Rule SET Code='AD_AuthorizationCredential.AD_Client_ID IN (0,@#AD_Client_ID@) AND +AD_AuthorizationCredential.IsActive=''Y'' AND +isIntersectCSV(AD_AuthorizationCredential.AD_AuthorizationScopeList,''@AD_AuthorizationScopes@'')=''Y'' AND +EXISTS ( + SELECT 1 + FROM AD_AuthorizationScopeProv asp + JOIN AD_AuthorizationProvider ap ON (asp.AD_AuthorizationProvider_ID=ap.AD_AuthorizationProvider_ID + AND ap.IsActive=''Y'' + AND ap.AD_Client_ID IN (0,@#AD_Client_ID@)) + WHERE asp.AD_AuthorizationProvider_ID=AD_AuthorizationCredential.AD_AuthorizationProvider_ID + AND isIntersectCSV(asp.AD_AuthorizationScope,''@AD_AuthorizationScopes@'')=''Y'' + AND asp.IsActive=''Y'' + AND asp.AD_Client_ID IN (0,@#AD_Client_ID@))',Updated=TO_TIMESTAMP('2021-05-11 15:15:50','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Val_Rule_ID=200146 +; + +CREATE OR REPLACE FUNCTION isintersectcsv( + p_csv1 character varying, + p_csv2 character varying) + RETURNS char + LANGUAGE 'plpgsql' + COST 100 + STABLE PARALLEL SAFE +AS $BODY$ +begin + IF string_to_array(p_csv1, ',') && string_to_array(p_csv2, ',') + THEN + RETURN 'Y'; + ELSE + RETURN 'N'; + END IF; +end; +$BODY$; + +UPDATE AD_AuthorizationAccount SET AD_AuthorizationScopes = AD_AuthorizationScope, UPDATED=Statement_Timestamp() WHERE AD_AuthorizationScope IS NOT NULL AND AD_AuthorizationScopes IS NULL +; + +-- May 11, 2021, 3:59:13 PM MYT +UPDATE AD_Val_Rule SET Code='AD_AuthorizationAccount.AD_User_ID=@AD_User_ID@ AND isIntersectCSV(AD_AuthorizationAccount.AD_AuthorizationScopes,''Document'')=''Y''',Updated=TO_TIMESTAMP('2021-05-11 15:59:13','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Val_Rule_ID=200148 +; + +-- May 11, 2021, 4:00:25 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-05-11 16:00:25','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206608 +; + +-- May 11, 2021, 4:00:29 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-05-11 16:00:29','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206585 +; + +-- May 11, 2021, 4:00:37 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-05-11 16:00:37','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206587 +; + +-- May 11, 2021, 4:00:40 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-05-11 16:00:40','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206588 +; + +-- May 11, 2021, 4:00:44 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-05-11 16:00:44','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206590 +; + +-- May 11, 2021, 4:00:47 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-05-11 16:00:47','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206591 +; + +-- May 11, 2021, 4:00:53 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-05-11 16:00:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206592 +; + +-- May 11, 2021, 4:00:56 PM MYT +UPDATE AD_Field SET IsReadOnly='Y', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-05-11 16:00:56','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206593 +; + +-- May 11, 2021, 4:01:57 PM MYT +UPDATE AD_Tab SET IsInsertRecord='N',Updated=TO_TIMESTAMP('2021-05-11 16:01:57','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Tab_ID=200287 +; + +-- May 11, 2021, 4:04:39 PM MYT +UPDATE AD_Column SET IsIdentifier='N', SeqNo=0,Updated=TO_TIMESTAMP('2021-05-11 16:04:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214405 +; + +-- May 11, 2021, 4:04:54 PM MYT +UPDATE AD_Column SET IsIdentifier='Y', SeqNo=20,Updated=TO_TIMESTAMP('2021-05-11 16:04:54','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214426 +; + +-- May 12, 2021, 2:21:40 PM MYT +UPDATE AD_Process_Para SET AD_Val_Rule_ID=200145,Updated=TO_TIMESTAMP('2021-05-12 14:21:40','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200335 +; + +SELECT Register_Migration_Script ('202105091048_IDEMPIERE-4771.sql') FROM DUAL +; + diff --git a/org.adempiere.base/META-INF/MANIFEST.MF b/org.adempiere.base/META-INF/MANIFEST.MF index d5f295b095..b6d06fcd36 100644 --- a/org.adempiere.base/META-INF/MANIFEST.MF +++ b/org.adempiere.base/META-INF/MANIFEST.MF @@ -29,6 +29,7 @@ Export-Package: bsh, org.adempiere.base.event.annotations.imp, org.adempiere.base.event.annotations.po, org.adempiere.base.event.annotations.process, + org.adempiere.base.upload, org.adempiere.exceptions, org.adempiere.impexp, org.adempiere.model, diff --git a/org.adempiere.base/src/org/adempiere/base/Core.java b/org.adempiere.base/src/org/adempiere/base/Core.java index 1b088f68c7..aefeaf3d7e 100644 --- a/org.adempiere.base/src/org/adempiere/base/Core.java +++ b/org.adempiere.base/src/org/adempiere/base/Core.java @@ -21,6 +21,7 @@ package org.adempiere.base; import java.net.URL; +import java.util.ArrayList; import java.util.List; import java.util.logging.Level; @@ -29,6 +30,7 @@ import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineManager; import org.adempiere.base.event.IEventManager; +import org.adempiere.base.upload.IUploadService; import org.adempiere.model.IAddressValidation; import org.adempiere.model.IShipmentProcessor; import org.adempiere.model.ITaxProvider; @@ -37,6 +39,7 @@ import org.compiere.impexp.BankStatementLoaderInterface; import org.compiere.impexp.BankStatementMatcherInterface; import org.compiere.model.Callout; import org.compiere.model.MAddressValidation; +import org.compiere.model.MAuthorizationAccount; import org.compiere.model.MBankAccountProcessor; import org.compiere.model.MPaymentProcessor; import org.compiere.model.MTaxProvider; @@ -47,6 +50,7 @@ import org.compiere.model.StandardTaxProvider; import org.compiere.process.ProcessCall; import org.compiere.util.CCache; import org.compiere.util.CLogger; +import org.compiere.util.Env; import org.compiere.util.PaymentExport; import org.compiere.util.ReplenishInterface; import org.idempiere.distributed.ICacheService; @@ -969,4 +973,37 @@ public class Core { return eventManager; } + + /** + * + * @return {@link IUploadService} + */ + public static List getUploadServices() { + List services = new ArrayList(); + List accounts = MAuthorizationAccount.getAuthorizedAccouts(Env.getAD_User_ID(Env.getCtx()), MAuthorizationAccount.AD_AUTHORIZATIONSCOPES_Document); + for (MAuthorizationAccount account : accounts) { + IUploadService service = getUploadService(account); + if (service != null) { + services.add(service); + } + } + return services; + } + + /** + * + * @param account + * @return {@link IUploadService} + */ + public static IUploadService getUploadService(MAuthorizationAccount account) { + String provider = account.getAD_AuthorizationCredential().getAD_AuthorizationProvider().getName(); + ServiceQuery query = new ServiceQuery(); + query.put("provider", provider); + IServiceHolder holder = Service.locator().locate(IUploadService.class, query); + if (holder != null) { + return holder.getService(); + } + + return null; + } } diff --git a/org.adempiere.base/src/org/adempiere/base/upload/IUploadHandler.java b/org.adempiere.base/src/org/adempiere/base/upload/IUploadHandler.java new file mode 100644 index 0000000000..c8a94fe062 --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/upload/IUploadHandler.java @@ -0,0 +1,50 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - trekglobal * + * - hengsin * + **********************************************************************/ +package org.adempiere.base.upload; + +import org.compiere.model.MAuthorizationAccount; + +/** + * + * handler interface for upload request + * @author hengsin + * + */ +public interface IUploadHandler { + /** + * + * @return label for handler + */ + public String getLabel(); + + /** + * + * @param media + * @param userExternalAccount + * @return {@link UploadResponse} + */ + public UploadResponse uploadMedia(UploadMedia media, MAuthorizationAccount account); +} diff --git a/org.adempiere.base/src/org/adempiere/base/upload/IUploadService.java b/org.adempiere.base/src/org/adempiere/base/upload/IUploadService.java new file mode 100644 index 0000000000..5a63ac0c61 --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/upload/IUploadService.java @@ -0,0 +1,41 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - trekglobal * + * - hengsin * + **********************************************************************/ +package org.adempiere.base.upload; + +/** + * + * interface for upload service + * @author hengsin + * + */ +public interface IUploadService { + /** + * Get upload handlers by content type + * @param contentType + * @return list of {@link IUploadHandler} + */ + public IUploadHandler[] getUploadHandlers(String contentType); +} diff --git a/org.adempiere.base/src/org/adempiere/base/upload/UploadMedia.java b/org.adempiere.base/src/org/adempiere/base/upload/UploadMedia.java new file mode 100644 index 0000000000..0e7eb16ba0 --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/upload/UploadMedia.java @@ -0,0 +1,90 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - trekglobal * + * - hengsin * + **********************************************************************/ +package org.adempiere.base.upload; + +import java.io.InputStream; + +/** + * + * representation of media + * @author hengsin + * + */ +public class UploadMedia { + + private String contentType; + private String name; + private InputStream inputStream; + private long contentLength; + + /** + * + * @param name + * @param contentType + * @param inputStream + * @param contentLength + */ + public UploadMedia(String name, String contentType, InputStream inputStream, long contentLength) { + super(); + this.name = name; + this.contentType = contentType; + this.inputStream = inputStream; + this.contentLength = contentLength; + } + + /** + * + * @return content type of media + */ + public String getContentType() { + return contentType; + } + + /** + * + * @return name/label of media + */ + public String getName() { + return name; + } + + /** + * + * @return {@link InputStream} for media content + */ + public InputStream getInputStream() { + return inputStream; + } + + /** + * + * @return length of media content + */ + public long getContentLength() { + return contentLength; + } + +} diff --git a/org.adempiere.base/src/org/adempiere/base/upload/UploadResponse.java b/org.adempiere.base/src/org/adempiere/base/upload/UploadResponse.java new file mode 100644 index 0000000000..131aa93f8f --- /dev/null +++ b/org.adempiere.base/src/org/adempiere/base/upload/UploadResponse.java @@ -0,0 +1,65 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - trekglobal * + * - hengsin * + **********************************************************************/ +package org.adempiere.base.upload; + +/** + * + * Response from upload service + * @author hengsin + * + */ +public class UploadResponse { + + private String link; + private String linkLabel; + + /** + * + * @param link + * @param linkLabel + */ + public UploadResponse(String link, String linkLabel) { + super(); + this.link = link; + this.linkLabel = linkLabel; + } + + /** + * + * @return link url to the uploaded file + */ + public String getLink() { + return link; + } + + /** + * + * @return label for the uploaded file + */ + public String getLinkLabel() { + return linkLabel; + } +} diff --git a/org.adempiere.base/src/org/compiere/model/I_AD_AuthorizationAccount.java b/org.adempiere.base/src/org/compiere/model/I_AD_AuthorizationAccount.java index 6864082a13..57784a7e42 100644 --- a/org.adempiere.base/src/org/compiere/model/I_AD_AuthorizationAccount.java +++ b/org.adempiere.base/src/org/compiere/model/I_AD_AuthorizationAccount.java @@ -88,14 +88,14 @@ public interface I_AD_AuthorizationAccount public org.compiere.model.I_AD_AuthorizationCredential getAD_AuthorizationCredential() throws RuntimeException; - /** Column name AD_AuthorizationScope */ - public static final String COLUMNNAME_AD_AuthorizationScope = "AD_AuthorizationScope"; + /** Column name AD_AuthorizationScopes */ + public static final String COLUMNNAME_AD_AuthorizationScopes = "AD_AuthorizationScopes"; - /** Set Authorization Scope */ - public void setAD_AuthorizationScope (String AD_AuthorizationScope); + /** Set Authorization Scopes */ + public void setAD_AuthorizationScopes (String AD_AuthorizationScopes); - /** Get Authorization Scope */ - public String getAD_AuthorizationScope(); + /** Get Authorization Scopes */ + public String getAD_AuthorizationScopes(); /** Column name AD_Client_ID */ public static final String COLUMNNAME_AD_Client_ID = "AD_Client_ID"; diff --git a/org.adempiere.base/src/org/compiere/model/I_AD_SchedulerRecipient.java b/org.adempiere.base/src/org/compiere/model/I_AD_SchedulerRecipient.java index bcc128c837..fbdd99dfcc 100644 --- a/org.adempiere.base/src/org/compiere/model/I_AD_SchedulerRecipient.java +++ b/org.adempiere.base/src/org/compiere/model/I_AD_SchedulerRecipient.java @@ -41,6 +41,17 @@ public interface I_AD_SchedulerRecipient /** Load Meta Data */ + /** Column name AD_AuthorizationAccount_ID */ + public static final String COLUMNNAME_AD_AuthorizationAccount_ID = "AD_AuthorizationAccount_ID"; + + /** Set Authorization Account */ + public void setAD_AuthorizationAccount_ID (int AD_AuthorizationAccount_ID); + + /** Get Authorization Account */ + public int getAD_AuthorizationAccount_ID(); + + public org.compiere.model.I_AD_AuthorizationAccount getAD_AuthorizationAccount() throws RuntimeException; + /** Column name AD_Client_ID */ public static final String COLUMNNAME_AD_Client_ID = "AD_Client_ID"; @@ -145,6 +156,19 @@ public interface I_AD_SchedulerRecipient */ public int getCreatedBy(); + /** Column name FileName */ + public static final String COLUMNNAME_FileName = "FileName"; + + /** Set File Name. + * Name of the local file or URL + */ + public void setFileName (String FileName); + + /** Get File Name. + * Name of the local file or URL + */ + public String getFileName(); + /** Column name IsActive */ public static final String COLUMNNAME_IsActive = "IsActive"; @@ -158,6 +182,15 @@ public interface I_AD_SchedulerRecipient */ public boolean isActive(); + /** Column name IsUpload */ + public static final String COLUMNNAME_IsUpload = "IsUpload"; + + /** Set Upload */ + public void setIsUpload (boolean IsUpload); + + /** Get Upload */ + public boolean isUpload(); + /** Column name Updated */ public static final String COLUMNNAME_Updated = "Updated"; diff --git a/org.adempiere.base/src/org/compiere/model/MAuthorizationAccount.java b/org.adempiere.base/src/org/compiere/model/MAuthorizationAccount.java index 5ff1fa4bab..00b2a02fed 100644 --- a/org.adempiere.base/src/org/compiere/model/MAuthorizationAccount.java +++ b/org.adempiere.base/src/org/compiere/model/MAuthorizationAccount.java @@ -29,6 +29,7 @@ import java.math.BigDecimal; import java.security.GeneralSecurityException; import java.sql.ResultSet; import java.sql.Timestamp; +import java.util.List; import java.util.Properties; import org.compiere.util.DB; @@ -156,15 +157,31 @@ public class MAuthorizationAccount extends X_AD_AuthorizationAccount { * @return */ public static MAuthorizationAccount getEMailAccount(String email) { - String where = "EMail=? AND AD_AuthorizationScope=? AND AD_Client_ID IN (0,?) AND IsAccessRevoked='N' AND IsAuthorized='Y'"; + String where = "EMail=? AND IsIntersectCSV(AD_AuthorizationScopes,"+DB.TO_STRING(AD_AUTHORIZATIONSCOPES_EMail)+")='Y' AND AD_Client_ID IN (0,?) AND IsAccessRevoked='N' AND IsAuthorized='Y'"; MAuthorizationAccount account = new Query(Env.getCtx(), Table_Name, where, null) .setOnlyActiveRecords(true) - .setParameters(email, AD_AUTHORIZATIONSCOPE_EMail, Env.getAD_Client_ID(Env.getCtx())) + .setParameters(email, Env.getAD_Client_ID(Env.getCtx())) .setOrderBy("AD_Client_ID DESC, Updated DESC") .first(); return account; } + /** + * + * @param AD_User_ID + * @param scopes + * @return list of {@link MAuthorizationAccount} + */ + public static List getAuthorizedAccouts(int AD_User_ID, String scopes) { + String where = "AD_User_ID=? AND IsIntersectCSV(AD_AuthorizationScopes,"+DB.TO_STRING(scopes)+")='Y' AND AD_Client_ID IN (0,?) AND IsAccessRevoked='N' AND IsAuthorized='Y'"; + List accounts = new Query(Env.getCtx(), Table_Name, where, null) + .setOnlyActiveRecords(true) + .setParameters(AD_User_ID, Env.getAD_Client_ID(Env.getCtx())) + .setOrderBy("AD_Client_ID DESC, Updated DESC") + .list(); + return accounts; + } + /** * Get an authorization token - refresh it if expired * @return AuthorizationToken diff --git a/org.adempiere.base/src/org/compiere/model/MAuthorizationCredential.java b/org.adempiere.base/src/org/compiere/model/MAuthorizationCredential.java index eb725fa21e..c6714da033 100644 --- a/org.adempiere.base/src/org/compiere/model/MAuthorizationCredential.java +++ b/org.adempiere.base/src/org/compiere/model/MAuthorizationCredential.java @@ -96,14 +96,14 @@ public class MAuthorizationCredential extends X_AD_AuthorizationCredential { // get the scope parameter MPInstancePara paramScope = null; for (MPInstancePara param : pinstance.getParameters()) { - if ("AD_AuthorizationScope".equals(param.getParameterName())) { + if ("AD_AuthorizationScopes".equals(param.getParameterName())) { paramScope = param; break; } } if (paramScope == null) { // this is not expected, just added here for safety - msg = "Process instance parameter for Scope not found"; + msg = "Process instance parameter for Scopes not found"; return msg; } String clientId = getAuthorizationClientId(); @@ -129,17 +129,17 @@ public class MAuthorizationCredential extends X_AD_AuthorizationCredential { boolean newAccount = false; MAuthorizationAccount account = null; - Query query = new Query(Env.getCtx(), MAuthorizationAccount.Table_Name, "AD_Client_ID=? AND AD_User_ID=? AND EMail=? AND AD_AuthorizationCredential_ID=? AND AD_AuthorizationScope=?", get_TrxName()); - query.setParameters(Env.getAD_Client_ID(Env.getCtx()), Env.getAD_User_ID(Env.getCtx()), email, getAD_AuthorizationCredential_ID(), paramScope.getP_String()); - account = query.first(); + Query query = new Query(Env.getCtx(), MAuthorizationAccount.Table_Name, "AD_Client_ID=? AND AD_User_ID=? AND EMail=? AND AD_AuthorizationCredential_ID=?", get_TrxName()); + query.setParameters(Env.getAD_Client_ID(Env.getCtx()), Env.getAD_User_ID(Env.getCtx()), email, getAD_AuthorizationCredential_ID()); + account = query.setOnlyActiveRecords(true).first(); if (account == null) { account = new MAuthorizationAccount(Env.getCtx(), 0, get_TrxName()); account.setEMail(email); account.setAD_AuthorizationCredential_ID(getAD_AuthorizationCredential_ID()); - account.setAD_User_ID(Env.getAD_User_ID(Env.getCtx())); - account.setAD_AuthorizationScope(paramScope.getP_String()); + account.setAD_User_ID(Env.getAD_User_ID(Env.getCtx())); newAccount = true; } + account.setAD_AuthorizationScopes(paramScope.getP_String()); account.setAccessToken(tokenResponse.getAccessToken()); account.setAccessTokenTimestamp(ts); @@ -177,9 +177,9 @@ public class MAuthorizationCredential extends X_AD_AuthorizationCredential { pilog.saveEx(); account.syncOthers(); if (newAccount) - msg = Msg.getMsg(getCtx(), "Authorization_Access_OK", new Object[] {account.getEMail()}); + msg = Msg.getMsg(getCtx(), "Authorization_Access_OK", new Object[] {account.getEMail(), paramScope.getP_String()}); else - msg = Msg.getMsg(getCtx(), "Authorization_Access_Previous", new Object[] {account.getEMail()}); + msg = Msg.getMsg(getCtx(), "Authorization_Access_Previous", new Object[] {account.getEMail(), paramScope.getP_String()}); } catch (Exception ex) { ex.printStackTrace(); msg = Msg.getMsg(getCtx(), "Error") + ex.getLocalizedMessage(); @@ -191,14 +191,14 @@ public class MAuthorizationCredential extends X_AD_AuthorizationCredential { /** * Get a complete Authorization end point URL with all the parameters required - * @param scope + * @param scopes * @param state - * @return + * @return authorization url */ - public String getFullAuthorizationEndpoint(String scope, String state) { - String scopeUrl = findScopeUrl(scope); + public String getFullAuthorizationEndpoint(String scopes, String state) { + String scopeUrl = findScopeUrl(scopes); if (scopeUrl == null) - throw new AdempiereException("Could not find scope " + scope + " for provider " + getAD_AuthorizationProvider_ID()); + throw new AdempiereException("Could not find scope " + scopes + " for provider " + getAD_AuthorizationProvider_ID()); MAuthorizationProvider provider = new MAuthorizationProvider(getCtx(), getAD_AuthorizationProvider_ID(), get_TrxName()); String authEndPoint = provider.getAuthorizationEndpoint(); StringBuilder url = new StringBuilder(authEndPoint).append("?"); @@ -215,18 +215,34 @@ public class MAuthorizationCredential extends X_AD_AuthorizationCredential { /** * Get the scope URL for the authorization provider - * @param scope - * @return + * @param scopes + * @return scope url */ - private String findScopeUrl(String scope) { - String scopeUrl = null; - MAuthorizationScopeProv scpr = new Query(Env.getCtx(), MAuthorizationScopeProv.Table_Name, "AD_AuthorizationProvider_ID=? AND AD_AuthorizationScope=?", get_TrxName()) - .setOnlyActiveRecords(true) - .setParameters(getAD_AuthorizationProvider_ID(), scope) - .first(); - if (scpr != null) - scopeUrl = scpr.getScopeURL(); - return scopeUrl; + private String findScopeUrl(String scopes) { + StringBuilder urlBuilder = new StringBuilder(); + List scopeURLs = new ArrayList(); + String[] scopeList = scopes.split("[,]"); + for(String scope : scopeList) { + scope = scope.trim(); + MAuthorizationScopeProv scpr = new Query(Env.getCtx(), MAuthorizationScopeProv.Table_Name, "AD_AuthorizationProvider_ID=? AND AD_AuthorizationScope=?", get_TrxName()) + .setOnlyActiveRecords(true) + .setParameters(getAD_AuthorizationProvider_ID(), scope) + .first(); + if (scpr != null) { + String[] urls = scpr.getScopeURL().split("\\s+"); + for(String url : urls) { + url = url.trim(); + if (!scopeURLs.contains(url)) + scopeURLs.add(url); + } + } + } + for(String scopeURL : scopeURLs) { + if (urlBuilder.length() > 0) + urlBuilder.append(" "); + urlBuilder.append(scopeURL); + } + return urlBuilder.length() > 0 ? urlBuilder.toString() : null; } } // MAuthorizationCredential diff --git a/org.adempiere.base/src/org/compiere/model/MLookupFactory.java b/org.adempiere.base/src/org/compiere/model/MLookupFactory.java index a7ad9acc7c..39a0712b75 100644 --- a/org.adempiere.base/src/org/compiere/model/MLookupFactory.java +++ b/org.adempiere.base/src/org/compiere/model/MLookupFactory.java @@ -903,9 +903,16 @@ public class MLookupFactory // List else if (DisplayType.isList(ldc.DisplayType)) { - String embeddedSQL = getLookup_ListEmbed(language, ldc.AD_Reference_ID, ldc.ColumnName); - if (embeddedSQL != null) - displayColumn.append("(").append(embeddedSQL).append(")"); + if (ldc.DisplayType == DisplayType.ChosenMultipleSelectionList) + { + displayColumn.append(columnSQL); + } + else + { + String embeddedSQL = getLookup_ListEmbed(language, ldc.AD_Reference_ID, ldc.ColumnName); + if (embeddedSQL != null) + displayColumn.append("(").append(embeddedSQL).append(")"); + } } // ID else if (DisplayType.isID(ldc.DisplayType)) diff --git a/org.adempiere.base/src/org/compiere/model/MScheduler.java b/org.adempiere.base/src/org/compiere/model/MScheduler.java index 82a432808b..7548b49ba0 100644 --- a/org.adempiere.base/src/org/compiere/model/MScheduler.java +++ b/org.adempiere.base/src/org/compiere/model/MScheduler.java @@ -18,6 +18,7 @@ package org.compiere.model; import java.sql.ResultSet; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Properties; @@ -244,6 +245,16 @@ public class MScheduler extends X_AD_Scheduler * @return array of user IDs */ public Integer[] getRecipientAD_User_IDs() + { + return getRecipientAD_User_IDs(false); + } + + /** + * Get Recipient AD_User_IDs + * @param excludeUploadRecipient + * @return array of user IDs + */ + public Integer[] getRecipientAD_User_IDs(boolean excludeUploadRecipient) { TreeSet list = new TreeSet(); MSchedulerRecipient[] recipients = getRecipients(false); @@ -254,7 +265,8 @@ public class MScheduler extends X_AD_Scheduler continue; if (recipient.getAD_User_ID() != 0) { - list.add(recipient.getAD_User_ID()); + if (!excludeUploadRecipient || !recipient.isUpload()) + list.add(recipient.getAD_User_ID()); } if (recipient.getAD_Role_ID() != 0) { @@ -372,4 +384,21 @@ public class MScheduler extends X_AD_Scheduler return this; } + /** + * + * @return list of upload recipients + */ + public MSchedulerRecipient[] getUploadRecipients() { + List list = new ArrayList<>(); + MSchedulerRecipient[] recipients = getRecipients(false); + for (int i = 0; i < recipients.length; i++) { + MSchedulerRecipient recipient = recipients[i]; + if (!recipient.isActive()) + continue; + if (recipient.getAD_User_ID() > 0 && recipient.isUpload() && recipient.getAD_AuthorizationAccount_ID() > 0) { + list.add(recipient); + } + } + return list.toArray(new MSchedulerRecipient[0]); + } } // MScheduler diff --git a/org.adempiere.base/src/org/compiere/model/MSchedulerRecipient.java b/org.adempiere.base/src/org/compiere/model/MSchedulerRecipient.java index cf63d3ef0a..3a7509d52a 100644 --- a/org.adempiere.base/src/org/compiere/model/MSchedulerRecipient.java +++ b/org.adempiere.base/src/org/compiere/model/MSchedulerRecipient.java @@ -98,4 +98,20 @@ public class MSchedulerRecipient extends X_AD_SchedulerRecipient implements Immu return this; } + /** + * String Representation + * @return info + */ + @Override + public String toString() + { + StringBuilder sb = new StringBuilder("MSchedulerRecipient["); + sb.append(get_ID()).append("-") + .append("AD_User_ID").append("=").append(getAD_User_ID()) + .append(",AD_Role_ID").append("=").append(getAD_Role_ID()) + .append(",IsUpload").append("=").append(isUpload()) + .append(",AD_AuthorizationAccount_ID").append("=").append(getAD_AuthorizationAccount_ID()) + .append("]"); + return sb.toString(); + } // toString } // MSchedulerRecipient diff --git a/org.adempiere.base/src/org/compiere/model/X_AD_AuthorizationAccount.java b/org.adempiere.base/src/org/compiere/model/X_AD_AuthorizationAccount.java index 625e5d534c..253f7c8001 100644 --- a/org.adempiere.base/src/org/compiere/model/X_AD_AuthorizationAccount.java +++ b/org.adempiere.base/src/org/compiere/model/X_AD_AuthorizationAccount.java @@ -32,7 +32,7 @@ public class X_AD_AuthorizationAccount extends PO implements I_AD_AuthorizationA /** * */ - private static final long serialVersionUID = 20210224L; + private static final long serialVersionUID = 20210511L; /** Standard Constructor */ public X_AD_AuthorizationAccount (Properties ctx, int AD_AuthorizationAccount_ID, String trxName) @@ -163,31 +163,31 @@ public class X_AD_AuthorizationAccount extends PO implements I_AD_AuthorizationA return ii.intValue(); } - /** AD_AuthorizationScope AD_Reference_ID=200185 */ - public static final int AD_AUTHORIZATIONSCOPE_AD_Reference_ID=200185; + /** AD_AuthorizationScopes AD_Reference_ID=200185 */ + public static final int AD_AUTHORIZATIONSCOPES_AD_Reference_ID=200185; /** Calendar = Calendar */ - public static final String AD_AUTHORIZATIONSCOPE_Calendar = "Calendar"; + public static final String AD_AUTHORIZATIONSCOPES_Calendar = "Calendar"; /** EMail = EMail */ - public static final String AD_AUTHORIZATIONSCOPE_EMail = "EMail"; + public static final String AD_AUTHORIZATIONSCOPES_EMail = "EMail"; /** Document = Document */ - public static final String AD_AUTHORIZATIONSCOPE_Document = "Document"; + public static final String AD_AUTHORIZATIONSCOPES_Document = "Document"; /** Profile = Profile */ - public static final String AD_AUTHORIZATIONSCOPE_Profile = "Profile"; + public static final String AD_AUTHORIZATIONSCOPES_Profile = "Profile"; /** Storage = Storage */ - public static final String AD_AUTHORIZATIONSCOPE_Storage = "Storage"; - /** Set Authorization Scope. - @param AD_AuthorizationScope Authorization Scope */ - public void setAD_AuthorizationScope (String AD_AuthorizationScope) + public static final String AD_AUTHORIZATIONSCOPES_Storage = "Storage"; + /** Set Authorization Scopes. + @param AD_AuthorizationScopes Authorization Scopes */ + public void setAD_AuthorizationScopes (String AD_AuthorizationScopes) { - set_Value (COLUMNNAME_AD_AuthorizationScope, AD_AuthorizationScope); + set_Value (COLUMNNAME_AD_AuthorizationScopes, AD_AuthorizationScopes); } - /** Get Authorization Scope. - @return Authorization Scope */ - public String getAD_AuthorizationScope () + /** Get Authorization Scopes. + @return Authorization Scopes */ + public String getAD_AuthorizationScopes () { - return (String)get_Value(COLUMNNAME_AD_AuthorizationScope); + return (String)get_Value(COLUMNNAME_AD_AuthorizationScopes); } public org.compiere.model.I_AD_User getAD_User() throws RuntimeException diff --git a/org.adempiere.base/src/org/compiere/model/X_AD_SchedulerRecipient.java b/org.adempiere.base/src/org/compiere/model/X_AD_SchedulerRecipient.java index 7fd5ab85ea..de049469ff 100644 --- a/org.adempiere.base/src/org/compiere/model/X_AD_SchedulerRecipient.java +++ b/org.adempiere.base/src/org/compiere/model/X_AD_SchedulerRecipient.java @@ -30,7 +30,7 @@ public class X_AD_SchedulerRecipient extends PO implements I_AD_SchedulerRecipie /** * */ - private static final long serialVersionUID = 20201220L; + private static final long serialVersionUID = 20210507L; /** Standard Constructor */ public X_AD_SchedulerRecipient (Properties ctx, int AD_SchedulerRecipient_ID, String trxName) @@ -40,6 +40,8 @@ public class X_AD_SchedulerRecipient extends PO implements I_AD_SchedulerRecipie { setAD_Scheduler_ID (0); setAD_SchedulerRecipient_ID (0); + setIsUpload (false); +// N } */ } @@ -71,6 +73,31 @@ public class X_AD_SchedulerRecipient extends PO implements I_AD_SchedulerRecipie return sb.toString(); } + public org.compiere.model.I_AD_AuthorizationAccount getAD_AuthorizationAccount() throws RuntimeException + { + return (org.compiere.model.I_AD_AuthorizationAccount)MTable.get(getCtx(), org.compiere.model.I_AD_AuthorizationAccount.Table_Name) + .getPO(getAD_AuthorizationAccount_ID(), get_TrxName()); } + + /** Set Authorization Account. + @param AD_AuthorizationAccount_ID Authorization Account */ + public void setAD_AuthorizationAccount_ID (int AD_AuthorizationAccount_ID) + { + if (AD_AuthorizationAccount_ID < 1) + set_ValueNoCheck (COLUMNNAME_AD_AuthorizationAccount_ID, null); + else + set_ValueNoCheck (COLUMNNAME_AD_AuthorizationAccount_ID, Integer.valueOf(AD_AuthorizationAccount_ID)); + } + + /** Get Authorization Account. + @return Authorization Account */ + public int getAD_AuthorizationAccount_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_AD_AuthorizationAccount_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + public org.compiere.model.I_AD_Role getAD_Role() throws RuntimeException { return (org.compiere.model.I_AD_Role)MTable.get(getCtx(), org.compiere.model.I_AD_Role.Table_Name) @@ -199,4 +226,42 @@ public class X_AD_SchedulerRecipient extends PO implements I_AD_SchedulerRecipie { return new KeyNamePair(get_ID(), String.valueOf(getAD_User_ID())); } + + /** Set File Name. + @param FileName + Name of the local file or URL + */ + public void setFileName (String FileName) + { + set_Value (COLUMNNAME_FileName, FileName); + } + + /** Get File Name. + @return Name of the local file or URL + */ + public String getFileName () + { + return (String)get_Value(COLUMNNAME_FileName); + } + + /** Set Upload. + @param IsUpload Upload */ + public void setIsUpload (boolean IsUpload) + { + set_Value (COLUMNNAME_IsUpload, Boolean.valueOf(IsUpload)); + } + + /** Get Upload. + @return Upload */ + public boolean isUpload () + { + Object oo = get_Value(COLUMNNAME_IsUpload); + if (oo != null) + { + if (oo instanceof Boolean) + return ((Boolean)oo).booleanValue(); + return "Y".equals(oo); + } + return false; + } } \ No newline at end of file diff --git a/org.adempiere.base/src/org/compiere/process/AddAuthorizationProcess.java b/org.adempiere.base/src/org/compiere/process/AddAuthorizationProcess.java index 465d22078d..eff232f529 100644 --- a/org.adempiere.base/src/org/compiere/process/AddAuthorizationProcess.java +++ b/org.adempiere.base/src/org/compiere/process/AddAuthorizationProcess.java @@ -37,8 +37,8 @@ import org.compiere.model.MPInstance; */ public class AddAuthorizationProcess extends SvrProcess { - /* Authorization Scope */ - protected String p_AD_AuthorizationScope = null; + /* Authorization Scopes */ + protected String p_AD_AuthorizationScopes = null; /* Authorization Credential */ protected int p_AD_AuthorizationCredential_ID = 0; /* Open Browser */ @@ -55,7 +55,7 @@ public class AddAuthorizationProcess extends SvrProcess { for (ProcessInfoParameter para : getParameter()) { String name = para.getParameterName(); switch (name) { - case "AD_AuthorizationScope": p_AD_AuthorizationScope = para.getParameterAsString(); break; + case "AD_AuthorizationScopes": p_AD_AuthorizationScopes = para.getParameterAsString(); break; case "AD_AuthorizationCredential_ID": p_AD_AuthorizationCredential_ID = para.getParameterAsInt(); break; case "Auth_OpenPopup": p_Auth_OpenPopup = para.getParameterAsBoolean(); break; case "AD_Language": break; // ignored, is just to save it in AD_Process_Para @@ -75,12 +75,12 @@ public class AddAuthorizationProcess extends SvrProcess { */ protected String doIt() throws Exception { if (log.isLoggable(Level.INFO)) - log.info("AD_AuthorizationScope" + p_AD_AuthorizationScope + log.info("AD_AuthorizationScopes" + p_AD_AuthorizationScopes + ", AD_AuthorizationCredential_ID=" + p_AD_AuthorizationCredential_ID + ", Auth_OpenBrowser=" + p_Auth_OpenPopup); MPInstance pinstance = new MPInstance(getCtx(), getAD_PInstance_ID(), get_TrxName()); MAuthorizationCredential credential = new MAuthorizationCredential(getCtx(), p_AD_AuthorizationCredential_ID, get_TrxName()); - f_authURL = credential.getFullAuthorizationEndpoint(p_AD_AuthorizationScope, pinstance.getAD_PInstance_UU()); + f_authURL = credential.getFullAuthorizationEndpoint(p_AD_AuthorizationScopes, pinstance.getAD_PInstance_UU()); if (! p_Auth_OpenPopup || processUI == null) { addLog(f_authURL); return "@Add_Auth_Copy_Link@"; diff --git a/org.adempiere.base/src/org/compiere/util/EMail.java b/org.adempiere.base/src/org/compiere/util/EMail.java index e0aaed3e75..77b5329243 100644 --- a/org.adempiere.base/src/org/compiere/util/EMail.java +++ b/org.adempiere.base/src/org/compiere/util/EMail.java @@ -78,6 +78,10 @@ public final class EMail implements Serializable //use in server bean public final static String HTML_MAIL_MARKER = "ContentType=text/html;"; + + //log last email send error message in context + public final static String EMAIL_SEND_MSG = "EmailSendMsg"; + /** * Full Constructor * @param client the client @@ -247,10 +251,13 @@ public final class EMail implements Serializable } m_sentMsg = null; + Env.getCtx().remove(EMAIL_SEND_MSG); + // if (!isValid(true)) { m_sentMsg = "Invalid Data"; + Env.getCtx().put(EMAIL_SEND_MSG, m_sentMsg); return m_sentMsg; } // @@ -305,12 +312,14 @@ public final class EMail implements Serializable { log.log(Level.WARNING, "Auth=" + m_auth + " - " + se.toString()); m_sentMsg = se.toString(); + Env.getCtx().put(EMAIL_SEND_MSG, m_sentMsg); return se.toString(); } catch (Exception e) { log.log(Level.SEVERE, "Auth=" + m_auth, e); m_sentMsg = e.toString(); + Env.getCtx().put(EMAIL_SEND_MSG, m_sentMsg); return e.toString(); } @@ -475,12 +484,14 @@ public final class EMail implements Serializable else log.log(Level.WARNING, sb.toString()); m_sentMsg = sb.toString(); + Env.getCtx().put(EMAIL_SEND_MSG, m_sentMsg); return sb.toString(); } catch (Exception e) { log.log(Level.SEVERE, "", e); m_sentMsg = e.getLocalizedMessage(); + Env.getCtx().put(EMAIL_SEND_MSG, m_sentMsg); return e.getLocalizedMessage(); } finally diff --git a/org.adempiere.server/src/main/server/org/compiere/server/Scheduler.java b/org.adempiere.server/src/main/server/org/compiere/server/Scheduler.java index 2ac6a27eb8..7eca77e90c 100644 --- a/org.adempiere.server/src/main/server/org/compiere/server/Scheduler.java +++ b/org.adempiere.server/src/main/server/org/compiere/server/Scheduler.java @@ -17,6 +17,7 @@ package org.compiere.server; import java.io.File; +import java.io.FileInputStream; import java.math.BigDecimal; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -30,7 +31,13 @@ import java.util.List; import java.util.Properties; import java.util.logging.Level; +import org.adempiere.base.Core; +import org.adempiere.base.upload.IUploadHandler; +import org.adempiere.base.upload.IUploadService; +import org.adempiere.base.upload.UploadMedia; +import org.adempiere.base.upload.UploadResponse; import org.compiere.model.MAttachment; +import org.compiere.model.MAuthorizationAccount; import org.compiere.model.MClient; import org.compiere.model.MMailText; import org.compiere.model.MNote; @@ -42,15 +49,19 @@ import org.compiere.model.MRole; import org.compiere.model.MScheduler; import org.compiere.model.MSchedulerLog; import org.compiere.model.MSchedulerPara; +import org.compiere.model.MSchedulerRecipient; import org.compiere.model.MSession; import org.compiere.model.MUser; +import org.compiere.model.PO; import org.compiere.print.MPrintFormat; import org.compiere.process.ProcessInfo; import org.compiere.process.ProcessInfoUtil; import org.compiere.process.ServerProcessCtl; import org.compiere.util.DB; import org.compiere.util.DisplayType; +import org.compiere.util.EMail; import org.compiere.util.Env; +import org.compiere.util.Msg; import org.compiere.util.TimeUtil; import org.compiere.util.Trx; import org.compiere.util.Util; @@ -243,8 +254,9 @@ public class Scheduler extends AdempiereServer } } + List sendErrors = new ArrayList<>(); // always notify recipients - Integer[] userIDs = scheduler.getRecipientAD_User_IDs(); + Integer[] userIDs = scheduler.getRecipientAD_User_IDs(true); if (userIDs.length > 0) { ProcessInfoUtil.setLogFromDB(pi); @@ -320,9 +332,33 @@ public class Scheduler extends AdempiereServer MClient client = MClient.get(scheduler.getCtx(), scheduler.getAD_Client_ID()); if (fileList != null && !fileList.isEmpty()) { - client.sendEMailAttachments(from, user, schedulerName, mailContent, fileList); + if (!client.sendEMailAttachments(from, user, schedulerName, mailContent, fileList)) { + StringBuilder summary = new StringBuilder(Msg.getMsg(Env.getCtx(), "SchedulerSendAttachmentFailed")); + summary.append(user.getName()); + String error = (String) Env.getCtx().remove(EMail.EMAIL_SEND_MSG); + if (!Util.isEmpty(error)) { + summary.append(". Error: ").append(error); + } + sendErrors.add(summary.toString()); + MSchedulerLog pLog = new MSchedulerLog(get(getCtx(), AD_Scheduler_ID), summary.toString()); + pLog.setTextMsg("From: " + from.getName() + " (" + from.getEMail() + ") To: " + user.getName() + " (" + user.getEMail() + ")"); + pLog.setIsError(true); + pLog.saveEx(); + } } else { - client.sendEMail(from, user, schedulerName, mailContent + "\n" + pi.getSummary() + " " + pi.getLogInfo(), null); + if (!client.sendEMail(from, user, schedulerName, mailContent + "\n" + pi.getSummary() + " " + pi.getLogInfo(), null)) { + StringBuilder summary = new StringBuilder(Msg.getMsg(Env.getCtx(), "SchedulerSendNotificationFailed")); + summary.append(user.getName()); + String error = (String) Env.getCtx().remove(EMail.EMAIL_SEND_MSG); + if (!Util.isEmpty(error)) { + summary.append(". Error: ").append(error); + } + sendErrors.add(summary.toString()); + MSchedulerLog pLog = new MSchedulerLog(get(getCtx(), AD_Scheduler_ID), summary.toString()); + pLog.setTextMsg("From: " + from.getName() + " (" + from.getEMail() + ") To: " + user.getName() + " (" + user.getEMail() + ")"); + pLog.setIsError(true); + pLog.saveEx(); + } } } @@ -337,6 +373,111 @@ public class Scheduler extends AdempiereServer } } + //cloud upload + List uploadErrors = new ArrayList<>(); + MSchedulerRecipient[] uploads = scheduler.getUploadRecipients(); + if (uploads.length > 0) { + File file = pi.getPDFReport(); + String contentType = "application/pdf"; + if (file == null) { + file = pi.getExportFile(); + String extension = pi.getExportFileExtension(); + if ("xls".equals(extension)) + contentType = "application/vnd.ms-excel"; + else if ("csv".equals(extension)) + contentType = "text/csv"; + else if ("html".equals(extension)) + contentType = "text/html"; + } + if (file != null) { + for(MSchedulerRecipient upload : uploads) { + MAuthorizationAccount account = new MAuthorizationAccount(Env.getCtx(), upload.getAD_AuthorizationAccount_ID(), null); + IUploadService service = Core.getUploadService(account); + if (service != null) { + try { + IUploadHandler[] handlers = service.getUploadHandlers(contentType); + if (handlers.length > 0) { + String fileName = null; + fileName = upload.getFileName(); + if (fileName != null && fileName.contains("@")) { + fileName = parseFileName(upload, fileName); + } + if (Util.isEmpty(fileName)) + fileName = file.getName(); + + UploadResponse response = handlers[0].uploadMedia(new UploadMedia(fileName, contentType, new FileInputStream(file), file.length()), account); + if (response.getLink() != null) { + MSchedulerLog pLog = new MSchedulerLog(get(getCtx(), AD_Scheduler_ID), Msg.getMsg(Env.getCtx(), "UploadSucess")); + pLog.setTextMsg("User: " + upload.getAD_User().getName() + " Account: " + account.getEMail() + + " Link: " + response.getLink()); + pLog.setIsError(false); + pLog.saveEx(); + } else { + MSchedulerLog pLog = new MSchedulerLog(get(getCtx(), AD_Scheduler_ID), Msg.getMsg(Env.getCtx(), "UploadFailed")); + pLog.setTextMsg("User: " + upload.getAD_User().getName() + " Account: " + account.getEMail()); + pLog.setIsError(true); + pLog.saveEx(); + uploadErrors.add(pLog.getTextMsg()); + } + } + } catch (Throwable e) { + log.log(Level.WARNING, process.toString(), e); + MSchedulerLog pLog = new MSchedulerLog(get(getCtx(), AD_Scheduler_ID), Msg.getMsg(Env.getCtx(), "UploadFailed")); + pLog.setTextMsg("User: " + upload.getAD_User().getName() + " Account: " + account.getEMail() + + " Error: " + e.getMessage()); + pLog.setIsError(true); + pLog.saveEx(); + uploadErrors.add(pLog.getTextMsg()); + } + } + } + } + } + + //notify supervisor if there are errors + int supervisor = get(getCtx(), AD_Scheduler_ID).getSupervisor_ID(); + if (supervisor > 0 && (sendErrors.size()>0 || uploadErrors.size()>0)) { + MUser user = new MUser(getCtx(), supervisor, null); + boolean email = user.isNotificationEMail(); + boolean notice = user.isNotificationNote(); + StringBuilder errors = new StringBuilder(); + for(String error : sendErrors) { + if (errors.length() > 0) + errors.append("\r\n\r\n"); + errors.append(error); + } + for(String error : uploadErrors) { + if (errors.length() > 0) + errors.append("\r\n\r\n"); + errors.append(error); + } + if (email) + { + MClient client = MClient.get(get(getCtx(), AD_Scheduler_ID).getCtx(), get(getCtx(), AD_Scheduler_ID).getAD_Client_ID()); + if (!client.sendEMail(from, user, schedulerName + ": " + Msg.getMsg(Env.getCtx(), "SchedulerSendAttachmentFailed"), errors.toString(), null, false)) + { + StringBuilder summary = new StringBuilder(Msg.getMsg(Env.getCtx(), "SchedulerSendNotificationFailed")); + summary.append(user.getName()); + String error = (String) Env.getCtx().remove(EMail.EMAIL_SEND_MSG); + if (!Util.isEmpty(error)) { + summary.append(". Error: ").append(error); + } + MSchedulerLog pLog = new MSchedulerLog(get(getCtx(), AD_Scheduler_ID), summary.toString()); + pLog.setTextMsg("From: " + from.getName() + " (" + from.getEMail() + ") To: " + user.getName() + " (" + user.getEMail() + ")"); + pLog.setIsError(true); + pLog.saveEx(); + } + } + if (notice) { + int AD_Message_ID = 442; // HARDCODED ProcessRunError + MNote note = new MNote(getCtx(), AD_Message_ID, supervisor, null); + note.setClientOrg(get(getCtx(), AD_Scheduler_ID).getAD_Client_ID(), get(getCtx(), AD_Scheduler_ID).getAD_Org_ID()); + note.setTextMsg(schedulerName+"\n"+errors.toString()); + note.setRecord(MPInstance.Table_ID, pi.getAD_PInstance_ID()); + note.saveEx(); + } + } + return pi.getSummary(); } // runProcess @@ -488,7 +629,34 @@ public class Scheduler extends AdempiereServer return bd; } - private Object parseVariable(MSchedulerPara sPara, String variable) { + private String parseFileName(PO source, String inStr) { + StringBuilder outStr = new StringBuilder(); + int i = inStr.indexOf('@'); + while (i != -1) + { + outStr.append(inStr.substring(0, i)); // up to @ + inStr = inStr.substring(i+1, inStr.length()); // from first @ + + int j = inStr.indexOf('@'); // next @ + if (j < 0) + { + if (log.isLoggable(Level.INFO)) log.log(Level.INFO, "No second tag: " + inStr); + //not context variable, add back @ and break + outStr.append("@"); + break; + } + + String token = inStr.substring(0, j); + Object value = parseVariable(source, "@"+token+"@"); + outStr.append(value != null ? value.toString() : " "); // replace context with Context + + inStr = inStr.substring(j+1, inStr.length()); // from second @ + i = inStr.indexOf('@'); + } + return outStr.toString(); + } + + private Object parseVariable(PO source, String variable) { Object value = variable; if (variable == null || (variable != null && variable.length() == 0)) @@ -500,7 +668,7 @@ public class Scheduler extends AdempiereServer //hengsin, capture unparseable error to avoid subsequent sql exception sql = Env.parseContext(getCtx(), 0, sql, false, false); // replace variables if (sql.equals("")) - log.log(Level.WARNING, "(" + sPara.getColumnName() + ") - Default SQL variable parse failed: " + variable); + log.log(Level.WARNING, "(" + source.toString() + ") - Default SQL variable parse failed: " + variable); else { PreparedStatement stmt = null; ResultSet rs = null; @@ -511,11 +679,11 @@ public class Scheduler extends AdempiereServer defStr = rs.getString(1); else { if (log.isLoggable(Level.INFO)) - log.log(Level.INFO, "(" + sPara.getColumnName() + ") - no Result: " + sql); + log.log(Level.INFO, "(" + source.toString() + ") - no Result: " + sql); } } catch (SQLException e) { - log.log(Level.WARNING, "(" + sPara.getColumnName() + ") " + sql, e); + log.log(Level.WARNING, "(" + source.toString() + ") " + sql, e); } finally{ DB.close(rs, stmt); @@ -535,7 +703,7 @@ public class Scheduler extends AdempiereServer index = columnName.indexOf('@'); if (index == -1) { - log.warning(sPara.getColumnName() + log.warning(source.toString() + " - cannot evaluate=" + variable); return null; } @@ -547,7 +715,7 @@ public class Scheduler extends AdempiereServer env = Env.getContext(getCtx(), columnName); if (env.length() == 0) { - log.warning(sPara.getColumnName() + log.warning(source.toString() + " - not in environment =" + columnName + "(" + variable + ")"); return null; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/report/LinkWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/report/LinkWindow.java new file mode 100644 index 0000000000..349c9acdd7 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/report/LinkWindow.java @@ -0,0 +1,79 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - trek global * + * - hengsin * + **********************************************************************/ +package org.adempiere.webui.report; + +import org.adempiere.webui.component.ToolBarButton; +import org.adempiere.webui.component.Window; +import org.adempiere.webui.theme.ThemeManager; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zul.A; + +/** + * @author hengsin + * + */ +public class LinkWindow extends Window { + + /** + * generated serial id + */ + private static final long serialVersionUID = 3287664745149293281L; + private String link; + private String label; + + /** + * + * @param link + * @param label + */ + public LinkWindow(String link, String label) { + this.link = link; + this.label = label; + layout(); + } + + private void layout() { + A a = new A(); + a.setLabel(label); + a.setHref(link); + a.setTarget("_blank"); + a.setStyle("font-weight: 600"); + appendChild(a); + a.setVflex("min"); + a.setHflex("min"); + a.addEventListener(Events.ON_CLICK, evt->detach()); + ToolBarButton btn = new ToolBarButton(); + btn.setImage(ThemeManager.getThemeResource("images/X8.png")); + btn.setStyle("position: absolute; top: 2px; right: 2px"); + appendChild(btn); + btn.addEventListener(Events.ON_CLICK, evt -> detach()); + setPosition("center, center"); + setStyle("padding: 32px;background-color: white;"); + setBorder(true); + setShadow(true); + } + +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/IReportViewerExportSource.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/IReportViewerExportSource.java new file mode 100644 index 0000000000..91bb654e75 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/IReportViewerExportSource.java @@ -0,0 +1,115 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - trekglobal * + * - hengsin * + **********************************************************************/ +package org.adempiere.webui.window; + +import java.util.Map; + +import org.adempiere.base.upload.IUploadService; +import org.compiere.model.MAuthorizationAccount; +import org.zkoss.util.media.AMedia; + +/** + * + * @author hengsin + * + */ +public interface IReportViewerExportSource { + + public static final String CSV_MIME_TYPE = "text/csv"; + public static final String EXCEL_MIME_TYPE = "application/vnd.ms-excel"; + public static final String EXCEL_XML_MIME_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + public static final String HTML_MIME_TYPE = "text/html"; + public static final String PDF_MIME_TYPE = "application/pdf"; + public static final String POSTSCRIPT_MIME_TYPE = "application/postscript"; + public static final String TEXT_MIME_TYPE = "text/plain"; + public static final String XML_MIME_TYPE = "text/xml"; + + public static final String CSV_FILE_EXT = "csv"; + public static final String SSV_FILE_EXT = "ssv"; + public static final String EXCEL_FILE_EXT = "xls"; + public static final String EXCEL_XML_FILE_EXT = "xlsx"; + public static final String HTML_FILE_EXT = "html"; + public static final String PDF_FILE_EXT = "pdf"; + public static final String POSTSCRIPT_FILE_EXT = "ps"; + public static final String TEXT_FILE_EXT = "txt"; + public static final String XML_FILE_EXT = "xml"; + + /** + * Get media/content by content type and file extension + * @param contentType + * @param fileExtension + * @return {@link AMediae} + */ + public AMedia getMedia(String contentType, String fileExtension); + + /** + * + * @return list of supported export formats + */ + public ExportFormat[] getExportFormats(); + + /** + * + * @return current mime/content type + */ + public String getContentType(); + + /** + * + * @return current file extension/format + */ + public String getFileExtension(); + + /** + * + * @return list of available authorized upload services + */ + public Map getUploadServiceMap(); + + /** + * + * @return name of report + */ + public String getReportName(); + + /** + * + * Model to hold export format properties + * @author hengsin + * + */ + public static final class ExportFormat { + public String label; + public String extension; + public String contentType; + + public ExportFormat(String label, String extension, String contentType) { + this.label = label; + this.extension = extension; + this.contentType = contentType; + } + } +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WReportExportDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WReportExportDialog.java new file mode 100644 index 0000000000..cb24d9786f --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WReportExportDialog.java @@ -0,0 +1,196 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - trekglobal * + * - hengsin * + **********************************************************************/ +package org.adempiere.webui.window; + +import java.util.logging.Level; + +import org.adempiere.webui.LayoutUtils; +import org.adempiere.webui.component.ConfirmPanel; +import org.adempiere.webui.component.Label; +import org.adempiere.webui.component.ListItem; +import org.adempiere.webui.component.Listbox; +import org.adempiere.webui.component.Window; +import org.adempiere.webui.util.ZKUpdateUtil; +import org.compiere.util.CLogger; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.zkoss.util.media.AMedia; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zul.Div; +import org.zkoss.zul.Filedownload; +import org.zkoss.zul.Hbox; +import org.zkoss.zul.Vbox; + +/** + * @author hengsin + * + */ +public class WReportExportDialog extends Window implements EventListener { + + /** + * generated serial id + */ + private static final long serialVersionUID = 8580712975224551032L; + private Listbox cboType = new Listbox(); + private ConfirmPanel confirmPanel = new ConfirmPanel(true); + private IReportViewerExportSource viewer; + + /** Logger */ + private static final CLogger log = CLogger.getCLogger(WReportExportDialog.class); + + /** + * + * @param viewer + */ + public WReportExportDialog(IReportViewerExportSource viewer) { + this.viewer = viewer; + ZKUpdateUtil.setWindowWidthX(this, 450); + ZKUpdateUtil.setWindowHeightX(this, 150); + setClosable(true); + setBorder("normal"); + setSclass("popup-dialog"); + setStyle("position:absolute"); + + cboType.setMold("select"); + + cboType.getItems().clear(); + cboType.appendItem("ps" + " - " + Msg.getMsg(Env.getCtx(), "FilePS"), "ps"); + cboType.appendItem("xml" + " - " + Msg.getMsg(Env.getCtx(), "FileXML"), "xml"); + cboType.appendItem("pdf" + " - " + Msg.getMsg(Env.getCtx(), "FilePDF"), "pdf"); + cboType.appendItem("html" + " - " + Msg.getMsg(Env.getCtx(), "FileHTML"), "html"); + cboType.appendItem("txt" + " - " + Msg.getMsg(Env.getCtx(), "FileTXT"), "txt"); + cboType.appendItem("ssv" + " - " + Msg.getMsg(Env.getCtx(), "FileSSV"), "ssv"); + cboType.appendItem("csv" + " - " + Msg.getMsg(Env.getCtx(), "FileCSV"), "csv"); + cboType.appendItem("xls" + " - " + Msg.getMsg(Env.getCtx(), "FileXLS"), "xls"); + cboType.appendItem("xlsx" + " - " + Msg.getMsg(Env.getCtx(), "FileXLSX"), "xlsx"); + + String contentType = viewer.getContentType(); + if (IReportViewerExportSource.PDF_MIME_TYPE.equals(contentType)) { + cboType.setSelectedIndex(2); + } else if (IReportViewerExportSource.HTML_MIME_TYPE.equals(contentType)) { + cboType.setSelectedIndex(3); + } else if (IReportViewerExportSource.EXCEL_MIME_TYPE.equals(contentType)) { + cboType.setSelectedIndex(7); + } else if (IReportViewerExportSource.CSV_MIME_TYPE.equals(contentType)) { + cboType.setSelectedIndex(6); + } else if (IReportViewerExportSource.EXCEL_XML_MIME_TYPE.equals(contentType)) { + cboType.setSelectedIndex(8); + } + + Hbox hb = new Hbox(); + hb.setSclass("dialog-content"); + hb.setAlign("center"); + hb.setPack("start"); + Div div = new Div(); + div.setStyle("text-align: right;"); + div.appendChild(new Label(Msg.getMsg(Env.getCtx(), "FilesOfType"))); + hb.appendChild(div); + hb.appendChild(cboType); + ZKUpdateUtil.setWidth(cboType, "100%"); + + Vbox vb = new Vbox(); + ZKUpdateUtil.setWidth(vb, "100%"); + appendChild(vb); + vb.appendChild(hb); + vb.appendChild(confirmPanel); + LayoutUtils.addSclass("dialog-footer", confirmPanel); + confirmPanel.addActionListener(this); + } + + @Override + public void onEvent(Event event) throws Exception { + if(event.getTarget().getId().equals(ConfirmPanel.A_CANCEL)) + onClose(); + else if(event.getTarget().getId().equals(ConfirmPanel.A_OK)) + exportFile(); + } + + private void exportFile() + { + try + { + AMedia media = null; + + ListItem li = cboType.getSelectedItem(); + if(li == null || li.getValue() == null) + { + FDialog.error(-1, this, "FileInvalidExtension"); + return; + } + + String ext = li.getValue().toString(); + if (ext.equals(IReportViewerExportSource.PDF_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.PDF_MIME_TYPE, IReportViewerExportSource.PDF_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.POSTSCRIPT_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.POSTSCRIPT_MIME_TYPE, IReportViewerExportSource.POSTSCRIPT_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.XML_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.XML_MIME_TYPE, IReportViewerExportSource.XML_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.CSV_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.CSV_MIME_TYPE, IReportViewerExportSource.CSV_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.SSV_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.CSV_MIME_TYPE, IReportViewerExportSource.SSV_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.TEXT_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.TEXT_MIME_TYPE, IReportViewerExportSource.TEXT_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.HTML_FILE_EXT) || ext.equals("htm")) + { + media = viewer.getMedia(IReportViewerExportSource.HTML_MIME_TYPE, IReportViewerExportSource.HTML_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.EXCEL_XML_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.EXCEL_XML_MIME_TYPE, IReportViewerExportSource.EXCEL_XML_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.EXCEL_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.EXCEL_MIME_TYPE, IReportViewerExportSource.EXCEL_FILE_EXT); + } + else + { + FDialog.error(-1, this, "FileInvalidExtension"); + return; + } + + onClose(); + Filedownload.save(media, viewer.getReportName() + "." + ext); + } + catch (Exception e) + { + log.log(Level.SEVERE, "Failed to export content.", e); + } + } +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WReportUploadDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WReportUploadDialog.java new file mode 100644 index 0000000000..395ff0bb39 --- /dev/null +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/WReportUploadDialog.java @@ -0,0 +1,305 @@ +/*********************************************************************** + * This file is part of iDempiere ERP Open Source * + * http://www.idempiere.org * + * * + * Copyright (C) Contributors * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301, USA. * + * * + * Contributors: * + * - trekglobal * + * - hengsin * + **********************************************************************/ +package org.adempiere.webui.window; + +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.logging.Level; + +import org.adempiere.base.upload.IUploadHandler; +import org.adempiere.base.upload.IUploadService; +import org.adempiere.base.upload.UploadMedia; +import org.adempiere.base.upload.UploadResponse; +import org.adempiere.webui.LayoutUtils; +import org.adempiere.webui.component.ConfirmPanel; +import org.adempiere.webui.component.Label; +import org.adempiere.webui.component.ListItem; +import org.adempiere.webui.component.Listbox; +import org.adempiere.webui.component.Window; +import org.adempiere.webui.report.LinkWindow; +import org.adempiere.webui.util.ReaderInputStream; +import org.adempiere.webui.util.ZKUpdateUtil; +import org.compiere.model.MAuthorizationAccount; +import org.compiere.util.CLogger; +import org.compiere.util.Env; +import org.compiere.util.Msg; +import org.zkoss.util.media.AMedia; +import org.zkoss.zk.ui.Page; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zul.Div; +import org.zkoss.zul.Listitem; +import org.zkoss.zul.Vlayout; + +/** + * @author hengsin + * + */ +public class WReportUploadDialog extends Window implements EventListener { + + /** + * generated serial id + */ + private static final long serialVersionUID = 8580712975224551032L; + private Listbox cboType = new Listbox(); + private Listbox cboActions = new Listbox(); + private ConfirmPanel confirmPanel = new ConfirmPanel(true); + private IReportViewerExportSource viewer; + + /** Logger */ + private static final CLogger log = CLogger.getCLogger(WReportUploadDialog.class); + + /** + * + * @param viewer + */ + public WReportUploadDialog(IReportViewerExportSource viewer) { + this.viewer = viewer; + ZKUpdateUtil.setWindowWidthX(this, 500); + setClosable(true); + setBorder("normal"); + setSclass("popup-dialog"); + + cboType.setMold("select"); + + cboType.getItems().clear(); + cboType.appendItem(IReportViewerExportSource.POSTSCRIPT_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FilePS"), IReportViewerExportSource.POSTSCRIPT_FILE_EXT); + cboType.appendItem(IReportViewerExportSource.XML_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileXML"), IReportViewerExportSource.XML_FILE_EXT); + cboType.appendItem(IReportViewerExportSource.PDF_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FilePDF"), IReportViewerExportSource.PDF_FILE_EXT); + cboType.appendItem(IReportViewerExportSource.HTML_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileHTML"), IReportViewerExportSource.HTML_FILE_EXT); + cboType.appendItem(IReportViewerExportSource.TEXT_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileTXT"), IReportViewerExportSource.TEXT_FILE_EXT); + cboType.appendItem(IReportViewerExportSource.CSV_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileCSV"), IReportViewerExportSource.CSV_FILE_EXT); + cboType.appendItem(IReportViewerExportSource.SSV_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileSSV"), IReportViewerExportSource.SSV_FILE_EXT); + cboType.appendItem(IReportViewerExportSource.EXCEL_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileXLS"), IReportViewerExportSource.EXCEL_FILE_EXT); + cboType.appendItem(IReportViewerExportSource.EXCEL_XML_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileXLSX"), IReportViewerExportSource.EXCEL_XML_FILE_EXT); + + String contentType = viewer.getContentType(); + if (IReportViewerExportSource.PDF_MIME_TYPE.equals(contentType)) { + cboType.setSelectedIndex(2); + } else if (IReportViewerExportSource.HTML_MIME_TYPE.equals(contentType)) { + cboType.setSelectedIndex(3); + } else if (IReportViewerExportSource.CSV_MIME_TYPE.equals(contentType)) { + if (IReportViewerExportSource.CSV_FILE_EXT.equals(viewer.getFileExtension())) { + cboType.setSelectedIndex(5); + } else { + cboType.setSelectedIndex(6); + } + } else if (IReportViewerExportSource.EXCEL_MIME_TYPE.equals(contentType)) { + cboType.setSelectedIndex(7); + } else if (IReportViewerExportSource.EXCEL_XML_MIME_TYPE.equals(contentType)) { + cboType.setSelectedIndex(8); + } + cboType.addActionListener(this); + + Div hb = new Div(); + hb.setSclass("dialog-content"); + hb.setWidth("100%"); + Div div = new Div(); + div.setStyle("text-align: right;display:inline-block;padding-right:5px;"); + div.setWidth("30%"); + div.appendChild(new Label(Msg.getMsg(Env.getCtx(), "FilesOfType"))); + hb.appendChild(div); + hb.appendChild(cboType); + cboType.setWidth("70%"); + cboType.setStyle("border-width:1px !important;"); + + Vlayout vb = new Vlayout(); + ZKUpdateUtil.setWidth(vb, "100%"); + vb.setVflex("1"); + appendChild(vb); + vb.appendChild(hb); + + cboActions.setMold("select"); + hb = new Div(); + hb.setSclass("dialog-content"); + hb.setWidth("100%"); + div = new Div(); + div.setStyle("text-align: right;display:inline-block;padding-right:5px;"); + div.setWidth("30%"); + div.appendChild(new Label(Msg.getMsg(Env.getCtx(), "UploadAction"))); + hb.appendChild(div); + hb.appendChild(cboActions); + cboActions.setWidth("70%"); + cboActions.setStyle("border-width:1px !important;"); + vb.appendChild(hb); + onOutputTypeSelectionChanged(); + + vb.appendChild(confirmPanel); + LayoutUtils.addSclass("dialog-footer", confirmPanel); + confirmPanel.addActionListener(this); + + addEventListener(Events.ON_CANCEL, e -> onClose()); + this.setVflex("min"); + } + + @Override + public void onEvent(Event event) throws Exception { + if(event.getTarget().getId().equals(ConfirmPanel.A_CANCEL)) { + onClose(); + } else if(event.getTarget().getId().equals(ConfirmPanel.A_OK)) { + uploadFile(); + } else if (event.getTarget() == cboType) { + onOutputTypeSelectionChanged(); + } + } + + private void onOutputTypeSelectionChanged() { + Listitem li = cboType.getSelectedItem(); + String ext = li.getValue().toString(); + String mime = toContentType(ext); + + cboActions.getItems().clear(); + Map map = viewer.getUploadServiceMap(); + for(MAuthorizationAccount account : map.keySet()) { + IUploadService service = map.get(account); + IUploadHandler[] handlers = service.getUploadHandlers(mime); + for (IUploadHandler handler : handlers) { + cboActions.appendItem(handler.getLabel(), new UploadHandler(account, handler)); + } + } + } + + private class UploadHandler { + private MAuthorizationAccount account; + private IUploadHandler handler; + + private UploadHandler(MAuthorizationAccount account, IUploadHandler handler) { + this.account = account; + this.handler = handler; + } + } + + private String toContentType(String ext) { + if (ext.equals(IReportViewerExportSource.PDF_FILE_EXT)) + { + return IReportViewerExportSource.PDF_MIME_TYPE; + } + else if (ext.equals(IReportViewerExportSource.POSTSCRIPT_FILE_EXT)) + { + return IReportViewerExportSource.POSTSCRIPT_MIME_TYPE; + } + else if (ext.equals(IReportViewerExportSource.XML_FILE_EXT)) + { + return IReportViewerExportSource.XML_MIME_TYPE; + } + else if (ext.equals(IReportViewerExportSource.CSV_FILE_EXT)) + { + return IReportViewerExportSource.CSV_MIME_TYPE; + } + else if (ext.equals(IReportViewerExportSource.SSV_FILE_EXT)) + { + return IReportViewerExportSource.CSV_MIME_TYPE; + } + else if (ext.equals(IReportViewerExportSource.TEXT_FILE_EXT)) + { + return IReportViewerExportSource.TEXT_MIME_TYPE; + } + else if (ext.equals(IReportViewerExportSource.HTML_FILE_EXT) || ext.equals("htm")) + { + return IReportViewerExportSource.HTML_MIME_TYPE; + } + else if (ext.equals(IReportViewerExportSource.EXCEL_XML_FILE_EXT)) + { + return IReportViewerExportSource.EXCEL_XML_MIME_TYPE; + } + else if (ext.equals(IReportViewerExportSource.EXCEL_FILE_EXT)) + { + return IReportViewerExportSource.EXCEL_MIME_TYPE; + } + + return null; + } + + private void uploadFile() + { + try + { + AMedia media = null; + ListItem li = cboType.getSelectedItem(); + String ext = li.getValue().toString(); + + if (ext.equals(IReportViewerExportSource.PDF_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.PDF_MIME_TYPE, IReportViewerExportSource.PDF_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.POSTSCRIPT_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.POSTSCRIPT_MIME_TYPE, IReportViewerExportSource.POSTSCRIPT_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.XML_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.XML_MIME_TYPE, IReportViewerExportSource.XML_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.CSV_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.CSV_MIME_TYPE, IReportViewerExportSource.CSV_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.SSV_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.CSV_MIME_TYPE, IReportViewerExportSource.SSV_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.TEXT_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.TEXT_MIME_TYPE, IReportViewerExportSource.TEXT_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.HTML_FILE_EXT) || ext.equals("htm")) + { + media = viewer.getMedia(IReportViewerExportSource.HTML_MIME_TYPE, IReportViewerExportSource.HTML_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.EXCEL_XML_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.EXCEL_XML_MIME_TYPE, IReportViewerExportSource.EXCEL_XML_FILE_EXT); + } + else if (ext.equals(IReportViewerExportSource.EXCEL_FILE_EXT)) + { + media = viewer.getMedia(IReportViewerExportSource.EXCEL_MIME_TYPE, IReportViewerExportSource.EXCEL_FILE_EXT); + } + else + { + FDialog.error(-1, this, "FileInvalidExtension", ext, this.getTitle()); + return; + } + + Page page = this.getPage(); + onClose(); + UploadHandler uh = cboActions.getSelectedItem().getValue(); + UploadResponse response = uh.handler.uploadMedia(new UploadMedia(media.getName(), media.getContentType(), + media.isBinary() ? media.getStreamData() : new ReaderInputStream(media.getReaderData(), StandardCharsets.UTF_8.name()), + media.isBinary() ? media.getByteData().length : 0), uh.account); + if (response != null && response.getLink() != null) { + LinkWindow linkWindow = new LinkWindow(response.getLink(), response.getLinkLabel()); + linkWindow.setPage(page); + linkWindow.doHighlighted(); + } + } + catch (Exception e) + { + log.log(Level.SEVERE, "Failed to upload content.", e); + FDialog.error(-1, this, "Error", e.getMessage(), this.getTitle()); + } + } +} diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java index bc2904dc6d..8b6ba9c505 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkJRViewer.java @@ -6,10 +6,16 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; import java.util.logging.Level; import javax.activation.FileDataSource; +import org.adempiere.base.Core; +import org.adempiere.base.upload.IUploadService; import org.adempiere.exceptions.AdempiereException; import org.adempiere.webui.ClientInfo; import org.adempiere.webui.LayoutUtils; @@ -24,6 +30,7 @@ import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.theme.ThemeManager; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.model.MArchive; +import org.compiere.model.MAuthorizationAccount; import org.compiere.model.MRole; import org.compiere.model.MSysConfig; import org.compiere.model.MUser; @@ -73,7 +80,7 @@ import net.sf.jasperreports.export.SimpleWriterExporterOutput; import net.sf.jasperreports.export.SimpleXlsReportConfiguration; import net.sf.jasperreports.export.SimpleXlsxReportConfiguration; -public class ZkJRViewer extends Window implements EventListener, ITabOnCloseHandler { +public class ZkJRViewer extends Window implements EventListener, ITabOnCloseHandler, IReportViewerExportSource { /** * */ @@ -98,10 +105,31 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl private String m_title; // local title - embedded windows clear the title protected ToolBarButton bArchive = new ToolBarButton(); + protected ToolBarButton bExport = new ToolBarButton(); + protected ToolBarButton bCloudUpload = new ToolBarButton(); private PrintInfo m_printInfo; private int mediaVersion = 0; + protected static final String CSV_OUTPUT_TYPE = "CSV"; + protected static final String HTML_OUTPUT_TYPE = "HTML"; + protected static final String PDF_OUTPUT_TYPE = "PDF"; + protected static final String SSV_OUTPUT_TYPE = "SSV"; + protected static final String XLS_OUTPUT_TYPE = "XLS"; + protected static final String XLSX_OUTPUT_TYPE = "XLSX"; + + protected final Map> mediaSuppliers = new HashMap>(); + protected Map uploadServicesMap = new HashMap<>(); + + private final ExportFormat[] exportFormats = new ExportFormat[] { + new ExportFormat(PDF_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FilePDF"), PDF_FILE_EXT, PDF_MIME_TYPE), + new ExportFormat(HTML_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileHTML"), HTML_FILE_EXT, HTML_MIME_TYPE), + new ExportFormat(CSV_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileCSV"), CSV_FILE_EXT, CSV_MIME_TYPE), + new ExportFormat(EXCEL_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileXLS"), EXCEL_FILE_EXT, EXCEL_MIME_TYPE), + new ExportFormat(EXCEL_XML_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileXLSX"), EXCEL_XML_FILE_EXT, EXCEL_XML_MIME_TYPE), + new ExportFormat(SSV_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileSSV"), SSV_FILE_EXT, CSV_MIME_TYPE) + }; + public ZkJRViewer(JasperPrint jasperPrint, String title, PrintInfo printInfo) { super(); this.setTitle(title); @@ -161,31 +189,31 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl previewType.setMold("select"); attachment = null; // Added by Martin Augustine - Ntier software Services 09/10/2013 if (isCanExport) { - previewType.appendItem("PDF", "PDF"); - previewType.appendItem("HTML", "HTML"); - previewType.appendItem("XLS", "XLS"); - previewType.appendItem("CSV", "CSV"); - previewType.appendItem("SSV", "SSV"); - previewType.appendItem("XLSX", "XLSX"); - if ("PDF".equals(defaultType)) { + previewType.appendItem(PDF_OUTPUT_TYPE, PDF_OUTPUT_TYPE); + previewType.appendItem(HTML_OUTPUT_TYPE, HTML_OUTPUT_TYPE); + previewType.appendItem(XLS_OUTPUT_TYPE, XLS_OUTPUT_TYPE); + previewType.appendItem(CSV_OUTPUT_TYPE, CSV_OUTPUT_TYPE); + previewType.appendItem(SSV_OUTPUT_TYPE, SSV_OUTPUT_TYPE); + previewType.appendItem(XLSX_OUTPUT_TYPE, XLSX_OUTPUT_TYPE); + if (PDF_OUTPUT_TYPE.equals(defaultType)) { previewType.setSelectedIndex(0); - } else if ("HTML".equals(defaultType)) { + } else if (HTML_OUTPUT_TYPE.equals(defaultType)) { previewType.setSelectedIndex(1); - } else if ("XLS".equals(defaultType)) { + } else if (XLS_OUTPUT_TYPE.equals(defaultType)) { previewType.setSelectedIndex(2); - } else if ("CSV".equals(defaultType)) { + } else if (CSV_OUTPUT_TYPE.equals(defaultType)) { previewType.setSelectedIndex(3); - } else if ("SSV".equals(defaultType)) { + } else if (SSV_OUTPUT_TYPE.equals(defaultType)) { previewType.setSelectedIndex(4); - } else if ("XLSX".equals(defaultType)) { + } else if (XLSX_OUTPUT_TYPE.equals(defaultType)) { previewType.setSelectedIndex(5); } else { previewType.setSelectedIndex(0); log.info("Format not Valid: "+defaultType); } } else { - previewType.appendItem("PDF", "PDF"); - previewType.appendItem("HTML", "HTML"); + previewType.appendItem(PDF_OUTPUT_TYPE, PDF_OUTPUT_TYPE); + previewType.appendItem(HTML_OUTPUT_TYPE, HTML_OUTPUT_TYPE); if ("PDF".equals(defaultType)) { previewType.setSelectedIndex(0); } else if ("HTML".equals(defaultType)) { @@ -228,6 +256,38 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl toolbar.appendChild(bArchive); bArchive.addEventListener(Events.ON_CLICK, this); + if ( isCanExport ) + { + bExport.setName("Export"); + if (ThemeManager.isUseFontIconForImage()) + bExport.setIconSclass("z-icon-Export"); + else + bExport.setImage(ThemeManager.getThemeResource("images/Export24.png")); + bExport.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "Export"))); + toolbar.appendChild(bExport); + bExport.addEventListener(Events.ON_CLICK, this); + if (ThemeManager.isUseFontIconForImage()) + LayoutUtils.addSclass("medium-toolbarbutton", bExport); + + List accounts = MAuthorizationAccount.getAuthorizedAccouts(Env.getAD_User_ID(Env.getCtx()), MAuthorizationAccount.AD_AUTHORIZATIONSCOPES_Document); + for (MAuthorizationAccount account : accounts) { + IUploadService service = Core.getUploadService(account); + if (service != null) { + uploadServicesMap.put(account, service); + } + } + if (uploadServicesMap.size() > 0) { + bCloudUpload.setName("CloudUpload"); + if (ThemeManager.isUseFontIconForImage()) + bCloudUpload.setIconSclass("z-icon-FileImport"); + else + bCloudUpload.setImage(ThemeManager.getThemeResource("images/FileImport24.png")); + bCloudUpload.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "CloudUpload"))); + toolbar.appendChild(bCloudUpload); + bCloudUpload.addEventListener(Events.ON_CLICK, this); + } + } + North north = new North(); layout.appendChild(north); north.appendChild(toolbar); @@ -251,8 +311,199 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl center.appendChild(iframe); this.setBorder("normal"); + + initMediaSuppliers(); } + private void initMediaSuppliers() { + mediaSuppliers.put(toMediaType(PDF_MIME_TYPE, PDF_FILE_EXT), () -> { + try { + attachment = getPDF(); + return new AMedia(m_title+"."+PDF_FILE_EXT, PDF_FILE_EXT, PDF_MIME_TYPE, attachment, true); + } catch (Exception e) { + if (e instanceof RuntimeException) + throw (RuntimeException)e; + else + throw new RuntimeException(e); + } + }); + + mediaSuppliers.put(toMediaType(HTML_MIME_TYPE, HTML_FILE_EXT), () -> { + try { + String path = System.getProperty("java.io.tmpdir"); + String prefix = null; + if (isList) + prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; + else + prefix = makePrefix(jasperPrint.getName()); + if (prefix.length() < 3) + prefix += "_".repeat(3-prefix.length()); + if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); + File file = File.createTempFile(prefix, "."+HTML_FILE_EXT, new File(path)); + + HtmlExporter exporter = new HtmlExporter(); + SimpleHtmlReportConfiguration htmlConfig = new SimpleHtmlReportConfiguration(); + htmlConfig.setEmbedImage(true); + htmlConfig.setAccessibleHtml(true); + if (!isList){ + jasperPrintList = new ArrayList<>(); + jasperPrintList.add(jasperPrint); + } + exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporter.setExporterOutput(new SimpleHtmlExporterOutput(file)); + exporter.setConfiguration(htmlConfig); + exporter.exportReport(); + return new AMedia(m_title+"."+HTML_FILE_EXT, HTML_FILE_EXT, HTML_MIME_TYPE, file, false); + } catch (Exception e) { + if (e instanceof RuntimeException) + throw (RuntimeException)e; + else + throw new RuntimeException(e); + } + }); + + mediaSuppliers.put(toMediaType(EXCEL_MIME_TYPE, EXCEL_FILE_EXT), () -> { + try { + String path = System.getProperty("java.io.tmpdir"); + String prefix = null; + if (isList) + prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; + else + prefix = makePrefix(jasperPrint.getName()); + if (prefix.length() < 3) + prefix += "_".repeat(3-prefix.length()); + if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); + File file = File.createTempFile(prefix, ".xls", new File(path)); + FileOutputStream fos = new FileOutputStream(file); + + // coding For Excel: + JRXlsExporter exporterXLS = new JRXlsExporter(); + SimpleXlsReportConfiguration xlsConfig = new SimpleXlsReportConfiguration(); + xlsConfig.setOnePagePerSheet(false); + + if (!isList){ + jasperPrintList = new ArrayList<>(); + jasperPrintList.add(jasperPrint); + } + exporterXLS.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporterXLS.setExporterOutput(new SimpleOutputStreamExporterOutput(fos)); + exporterXLS.setConfiguration(xlsConfig); + exporterXLS.exportReport(); + return new AMedia(m_title+"."+EXCEL_FILE_EXT, EXCEL_FILE_EXT, EXCEL_MIME_TYPE, file, true); + } catch (Exception e) { + if (e instanceof RuntimeException) + throw (RuntimeException)e; + else + throw new RuntimeException(e); + } + }); + + mediaSuppliers.put(toMediaType(EXCEL_XML_MIME_TYPE, EXCEL_XML_FILE_EXT), () -> { + try { + String path = System.getProperty("java.io.tmpdir"); + String prefix = null; + if (isList) + prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; + else + prefix = makePrefix(jasperPrint.getName()); + if (prefix.length() < 3) + prefix += "_".repeat(3-prefix.length()); + if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); + File file = File.createTempFile(prefix, "."+EXCEL_XML_FILE_EXT, new File(path)); + FileOutputStream fos = new FileOutputStream(file); + + // coding For Excel: + JRXlsxExporter exporterXLSX = new JRXlsxExporter(); + SimpleXlsxReportConfiguration xlsxConfig = new SimpleXlsxReportConfiguration(); + xlsxConfig.setOnePagePerSheet(false); + + if (!isList){ + jasperPrintList = new ArrayList<>(); + jasperPrintList.add(jasperPrint); + } + exporterXLSX.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporterXLSX.setExporterOutput(new SimpleOutputStreamExporterOutput(fos)); + exporterXLSX.setConfiguration(xlsxConfig); + exporterXLSX.exportReport(); + return new AMedia(m_title+"."+EXCEL_XML_FILE_EXT, EXCEL_XML_FILE_EXT, EXCEL_XML_MIME_TYPE, file, true); + } catch (Exception e) { + if (e instanceof RuntimeException) + throw (RuntimeException)e; + else + throw new RuntimeException(e); + } + }); + + mediaSuppliers.put(toMediaType(CSV_MIME_TYPE, CSV_FILE_EXT), () -> { + try { + String path = System.getProperty("java.io.tmpdir"); + String prefix = null; + if (isList) + prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; + else + prefix = makePrefix(jasperPrint.getName()); + if (prefix.length() < 3) + prefix += "_".repeat(3-prefix.length()); + if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); + File file = File.createTempFile(prefix, "."+CSV_FILE_EXT, new File(path)); + FileOutputStream fos = new FileOutputStream(file); + JRCsvExporter exporter= new JRCsvExporter(); + if (!isList){ + jasperPrintList = new ArrayList<>(); + jasperPrintList.add(jasperPrint); + } + exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporter.setExporterOutput(new SimpleWriterExporterOutput(fos)); + exporter.exportReport(); + + return new AMedia(m_title+"."+CSV_FILE_EXT, CSV_FILE_EXT, CSV_MIME_TYPE, file, true); + } catch (Exception e) { + if (e instanceof RuntimeException) + throw (RuntimeException)e; + else + throw new RuntimeException(e); + } + }); + + mediaSuppliers.put(toMediaType(CSV_MIME_TYPE, SSV_FILE_EXT), () -> { + try { + String path = System.getProperty("java.io.tmpdir"); + String prefix = null; + if (isList) + prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; + else + prefix = makePrefix(jasperPrint.getName()); + if (prefix.length() < 3) + prefix += "_".repeat(3-prefix.length()); + if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); + File file = File.createTempFile(prefix, "."+SSV_FILE_EXT, new File(path)); + FileOutputStream fos = new FileOutputStream(file); + JRCsvExporter exporter= new JRCsvExporter(); + SimpleCsvExporterConfiguration csvConfig = new SimpleCsvExporterConfiguration(); + csvConfig.setFieldDelimiter(";"); + if (!isList){ + jasperPrintList = new ArrayList<>(); + jasperPrintList.add(jasperPrint); + } + exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporter.setExporterOutput(new SimpleWriterExporterOutput(fos)); + exporter.setConfiguration(csvConfig); + exporter.exportReport(); + + return new AMedia(m_title+"."+SSV_FILE_EXT, SSV_FILE_EXT, CSV_MIME_TYPE, file, true); + } catch (Exception e) { + if (e instanceof RuntimeException) + throw (RuntimeException)e; + else + throw new RuntimeException(e); + } + }); + } + + private String toMediaType(String contentType, String fileExtension) { + return contentType + ";" + fileExtension; + } + private String makePrefix(String name) { StringBuilder prefix = new StringBuilder(); char[] nameArray = name.toCharArray(); @@ -278,6 +529,10 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl cmd_sendMail(); else if (e.getTarget() == bArchive) cmd_archive(); + else if (e.getTarget() == bExport) + cmd_export(); + else if (e.getTarget() == bCloudUpload) + cmd_upload(); } // actionPerformed private void cmd_render() { @@ -352,140 +607,18 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl Thread.currentThread().setContextClassLoader(JasperReport.class.getClassLoader()); Listitem selected = previewType.getSelectedItem(); reportType=selected.getValue(); - if ( "PDF".equals( reportType ) ) - { - attachment = getPDF(); - media = new AMedia(m_title + ".pdf", "pdf", "application/pdf", attachment, true); - - } else if ("HTML".equals(reportType)) { - String path = System.getProperty("java.io.tmpdir"); - String prefix = null; - if (isList) - prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; - else - prefix = makePrefix(jasperPrint.getName()); - if (prefix.length() < 3) - prefix += "_".repeat(3-prefix.length()); - if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); - File file = File.createTempFile(prefix, ".html", new File(path)); - - HtmlExporter exporter = new HtmlExporter(); - SimpleHtmlReportConfiguration htmlConfig = new SimpleHtmlReportConfiguration(); - htmlConfig.setEmbedImage(true); - htmlConfig.setAccessibleHtml(true); - if (!isList){ - jasperPrintList = new ArrayList<>(); - jasperPrintList.add(jasperPrint); - } - exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); - exporter.setExporterOutput(new SimpleHtmlExporterOutput(file)); - exporter.setConfiguration(htmlConfig); - exporter.exportReport(); - media = new AMedia(m_title, "html", "text/html", file, false); - } else if ("XLS".equals(reportType)) { - String path = System.getProperty("java.io.tmpdir"); - String prefix = null; - if (isList) - prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; - else - prefix = makePrefix(jasperPrint.getName()); - if (prefix.length() < 3) - prefix += "_".repeat(3-prefix.length()); - if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); - File file = File.createTempFile(prefix, ".xls", new File(path)); - FileOutputStream fos = new FileOutputStream(file); - - // coding For Excel: - JRXlsExporter exporterXLS = new JRXlsExporter(); - SimpleXlsReportConfiguration xlsConfig = new SimpleXlsReportConfiguration(); - xlsConfig.setOnePagePerSheet(false); - - if (!isList){ - jasperPrintList = new ArrayList<>(); - jasperPrintList.add(jasperPrint); - } - exporterXLS.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); - exporterXLS.setExporterOutput(new SimpleOutputStreamExporterOutput(fos)); - exporterXLS.setConfiguration(xlsConfig); - exporterXLS.exportReport(); - media = new AMedia(m_title + ".xls", "xls", "application/vnd.ms-excel", file, true); - - } else if ("XLSX".equals(reportType)) { - String path = System.getProperty("java.io.tmpdir"); - String prefix = null; - if (isList) - prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; - else - prefix = makePrefix(jasperPrint.getName()); - if (prefix.length() < 3) - prefix += "_".repeat(3-prefix.length()); - if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); - File file = File.createTempFile(prefix, ".xlsx", new File(path)); - FileOutputStream fos = new FileOutputStream(file); - - // coding For Excel: - JRXlsxExporter exporterXLSX = new JRXlsxExporter(); - SimpleXlsxReportConfiguration xlsxConfig = new SimpleXlsxReportConfiguration(); - xlsxConfig.setOnePagePerSheet(false); - - if (!isList){ - jasperPrintList = new ArrayList<>(); - jasperPrintList.add(jasperPrint); - } - exporterXLSX.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); - exporterXLSX.setExporterOutput(new SimpleOutputStreamExporterOutput(fos)); - exporterXLSX.setConfiguration(xlsxConfig); - exporterXLSX.exportReport(); - media = new AMedia(m_title + ".xlsx", "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", file, true); - - }else if ("CSV".equals(reportType)) { - String path = System.getProperty("java.io.tmpdir"); - String prefix = null; - if (isList) - prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; - else - prefix = makePrefix(jasperPrint.getName()); - if (prefix.length() < 3) - prefix += "_".repeat(3-prefix.length()); - if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); - File file = File.createTempFile(prefix, ".csv", new File(path)); - FileOutputStream fos = new FileOutputStream(file); - JRCsvExporter exporter= new JRCsvExporter(); - if (!isList){ - jasperPrintList = new ArrayList<>(); - jasperPrintList.add(jasperPrint); - } - exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); - exporter.setExporterOutput(new SimpleWriterExporterOutput(fos)); - exporter.exportReport(); - - media = new AMedia(m_title + ".csv", "csv", "application/csv", file, true); - - }else if ("SSV".equals(reportType)) { - String path = System.getProperty("java.io.tmpdir"); - String prefix = null; - if (isList) - prefix = makePrefix(jasperPrintList.get(0).getName())+"_List"; - else - prefix = makePrefix(jasperPrint.getName()); - if (prefix.length() < 3) - prefix += "_".repeat(3-prefix.length()); - if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); - File file = File.createTempFile(prefix, ".ssv", new File(path)); - FileOutputStream fos = new FileOutputStream(file); - JRCsvExporter exporter= new JRCsvExporter(); - SimpleCsvExporterConfiguration csvConfig = new SimpleCsvExporterConfiguration(); - csvConfig.setFieldDelimiter(";"); - if (!isList){ - jasperPrintList = new ArrayList<>(); - jasperPrintList.add(jasperPrint); - } - exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); - exporter.setExporterOutput(new SimpleWriterExporterOutput(fos)); - exporter.setConfiguration(csvConfig); - exporter.exportReport(); - - media = new AMedia(m_title, "ssv", "application/ssv", file, true); + if (PDF_OUTPUT_TYPE.equals(reportType)) { + createNewMedia(PDF_MIME_TYPE, PDF_FILE_EXT); + } else if (HTML_OUTPUT_TYPE.equals(reportType)) { + createNewMedia(HTML_MIME_TYPE, HTML_FILE_EXT); + } else if (XLS_OUTPUT_TYPE.equals(reportType)) { + createNewMedia(EXCEL_MIME_TYPE, EXCEL_FILE_EXT); + } else if (XLSX_OUTPUT_TYPE.equals(reportType)) { + createNewMedia(EXCEL_XML_MIME_TYPE, EXCEL_FILE_EXT); + } else if (CSV_OUTPUT_TYPE.equals(reportType)) { + createNewMedia(CSV_MIME_TYPE, CSV_FILE_EXT); + }else if (SSV_OUTPUT_TYPE.equals(reportType)) { + createNewMedia(CSV_MIME_TYPE, SSV_FILE_EXT); } } finally { Thread.currentThread().setContextClassLoader(cl); @@ -508,7 +641,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl { log.log(Level.FINE, "Path="+path + " Prefix="+prefix); } - File file = new File(FileUtil.getTempMailName(prefix, ".pdf")); + File file = new File(FileUtil.getTempMailName(prefix, "."+PDF_FILE_EXT)); JasperReportsContext context = new SimpleJasperReportsContext(DefaultJasperReportsContext.getInstance()); JRPdfExporter exporter = new JRPdfExporter(context); if (!isList){ @@ -525,7 +658,7 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl if (ClientInfo.isMobile()) { Listitem selected = previewType.getSelectedItem(); String reportType=selected.getValue(); - if ( "PDF".equals( reportType ) ) { + if ( PDF_OUTPUT_TYPE.equals( reportType ) ) { openWithPdfJsViewer(); return; } @@ -648,4 +781,64 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl return fileContent; } // getFileByteData + /** + * Export + */ + private void cmd_export() + { + WReportExportDialog winExportFile = new WReportExportDialog(this); + winExportFile.setTitle(Msg.getMsg(Env.getCtx(), "Export") + ": " + getTitle()); + winExportFile.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED); + AEnv.showWindow(winExportFile); + } // cmd_export + + private void cmd_upload() { + if (media == null) + return; + + WReportUploadDialog winUploadFile = new WReportUploadDialog(this); + winUploadFile.setTitle(Msg.getMsg(Env.getCtx(), "CloudUpload") + ": " + getTitle()); + winUploadFile.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED); + AEnv.showWindow(winUploadFile); + } + + private void createNewMedia(String contentType, String fileExtension) { + media = null; + media = getMedia(contentType, fileExtension); + } + + @Override + public AMedia getMedia(String contentType, String fileExtension) { + if (media != null && media.getContentType().equals(contentType) && media.getFormat().equals(fileExtension)) + return media; + + Supplier supplier = mediaSuppliers.get(toMediaType(contentType, fileExtension)); + return supplier != null ? supplier.get() : null; + } + + @Override + public ExportFormat[] getExportFormats() { + return exportFormats; + } + + @Override + public String getContentType() { + return media.getContentType(); + } + + @Override + public String getFileExtension() { + return media.getFormat(); + } + + @Override + public Map getUploadServiceMap() { + return uploadServicesMap; + } + + @Override + public String getReportName() { + return m_title; + } + } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java index 4c26444c0e..1b43f3165b 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/ZkReportViewer.java @@ -22,12 +22,19 @@ import java.io.StringWriter; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Properties; +import java.util.function.Supplier; import java.util.logging.Level; import javax.activation.FileDataSource; import javax.servlet.http.HttpServletRequest; +import org.adempiere.base.Core; +import org.adempiere.base.upload.IUploadService; import org.adempiere.exceptions.DBException; import org.adempiere.pdf.Document; import org.adempiere.util.ContextRunnable; @@ -38,7 +45,6 @@ import org.adempiere.webui.apps.BusyDialog; import org.adempiere.webui.apps.WReport; import org.adempiere.webui.apps.form.WReportCustomization; import org.adempiere.webui.component.Checkbox; -import org.adempiere.webui.component.ConfirmPanel; import org.adempiere.webui.component.Label; import org.adempiere.webui.component.ListItem; import org.adempiere.webui.component.Listbox; @@ -62,6 +68,7 @@ import org.adempiere.webui.util.ServerPushTemplate; import org.adempiere.webui.util.ZKUpdateUtil; import org.compiere.model.GridField; import org.compiere.model.MArchive; +import org.compiere.model.MAuthorizationAccount; import org.compiere.model.MClient; import org.compiere.model.MLanguage; import org.compiere.model.MQuery; @@ -100,8 +107,6 @@ import org.zkoss.zul.A; import org.zkoss.zul.Borderlayout; import org.zkoss.zul.Center; import org.zkoss.zul.Div; -import org.zkoss.zul.Filedownload; -import org.zkoss.zul.Hbox; import org.zkoss.zul.Hlayout; import org.zkoss.zul.Iframe; import org.zkoss.zul.Listitem; @@ -113,7 +118,6 @@ import org.zkoss.zul.South; import org.zkoss.zul.Tab; import org.zkoss.zul.Toolbar; import org.zkoss.zul.Toolbarbutton; -import org.zkoss.zul.Vbox; import org.zkoss.zul.Vlayout; import org.zkoss.zul.impl.Utils; import org.zkoss.zul.impl.XulElement; @@ -135,14 +139,21 @@ import org.zkoss.zul.impl.XulElement; * * @author Low Heng Sin */ -public class ZkReportViewer extends Window implements EventListener, ITabOnCloseHandler { +public class ZkReportViewer extends Window implements EventListener, ITabOnCloseHandler, IReportViewerExportSource { + /** - * + * generated serial id */ - private static final long serialVersionUID = -424164233048709765L; + private static final long serialVersionUID = 6307014622485159910L; + + protected static final String CSV_OUTPUT_TYPE = "CSV"; + protected static final String HTML_OUTPUT_TYPE = "HTML"; + protected static final String PDF_OUTPUT_TYPE = "PDF"; + protected static final String XLS_OUTPUT_TYPE = "XLS"; + protected static final String XLSX_OUTPUT_TYPE = "XLSX"; /** Window No */ - private int m_WindowNo = -1; + protected int m_WindowNo = -1; private long prevKeyEventTime = 0; private KeyEvent prevKeyEvent; /** Print Context */ @@ -150,7 +161,7 @@ public class ZkReportViewer extends Window implements EventListener, ITab /** Setting Values */ private boolean m_setting = false; /** Report Engine */ - private ReportEngine m_reportEngine; + protected ReportEngine m_reportEngine; /** Table ID */ private int m_AD_Table_ID = 0; private boolean m_isCanExport; @@ -176,17 +187,14 @@ public class ZkReportViewer extends Window implements EventListener, ITab private WTableDirEditor wLanguage; private Label labelDrill = new Label(); private Listbox comboDrill = new Listbox(); - private Listbox previewType = new Listbox(); + protected Listbox previewType = new Listbox(); private ToolBarButton bRefresh = new ToolBarButton(); private Iframe iframe; - private Window winExportFile = null; - private ConfirmPanel confirmPanel = new ConfirmPanel(true); - private Listbox cboType = new Listbox(); private Checkbox summary = new Checkbox(); - private AMedia media; + protected AMedia media; private int mediaVersion = 0; private A reportLink; @@ -200,8 +208,22 @@ public class ZkReportViewer extends Window implements EventListener, ITab private Popup toolbarPopup; - //private static final String REPORT = "org.idempiere.ui.report"; + private ToolBarButton bCloudUpload = new ToolBarButton(); + protected Map uploadServicesMap = new HashMap<>(); + private final ExportFormat[] exportFormats = new ExportFormat[] { + new ExportFormat(POSTSCRIPT_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FilePS"), POSTSCRIPT_FILE_EXT, POSTSCRIPT_MIME_TYPE), + new ExportFormat(XML_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileXML"), XML_FILE_EXT, XML_MIME_TYPE), + new ExportFormat(PDF_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FilePDF"), PDF_FILE_EXT, PDF_MIME_TYPE), + new ExportFormat(HTML_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileHTML"), HTML_FILE_EXT, HTML_MIME_TYPE), + new ExportFormat(TEXT_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileTXT"), TEXT_FILE_EXT, TEXT_MIME_TYPE), + new ExportFormat(SSV_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileSSV"), SSV_FILE_EXT, CSV_MIME_TYPE), + new ExportFormat(CSV_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileCSV"), CSV_FILE_EXT, CSV_MIME_TYPE), + new ExportFormat(EXCEL_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileXLS"), EXCEL_FILE_EXT, EXCEL_MIME_TYPE), + new ExportFormat(EXCEL_XML_FILE_EXT + " - " + Msg.getMsg(Env.getCtx(), "FileXLSX"), EXCEL_XML_FILE_EXT, EXCEL_XML_MIME_TYPE) + }; + + private final Map> mediaSuppliers = new HashMap>(); /** * Static Layout * @throws Exception @@ -229,6 +251,135 @@ public class ZkReportViewer extends Window implements EventListener, ITab addEventListener("onPostInit", e -> { postRenderReportEvent(); }); + + initMediaSuppliers(); + } + + private String toMediaType(String contentType, String fileExtension) { + return contentType + ";" + fileExtension; + } + + private void initMediaSuppliers() { + mediaSuppliers.put(toMediaType(PDF_MIME_TYPE, PDF_FILE_EXT), () -> { + try { + String path = System.getProperty("java.io.tmpdir"); + String prefix = makePrefix(m_reportEngine.getName()); + if (prefix.length() < 3) + prefix += "_".repeat(3-prefix.length()); + if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); + File file = File.createTempFile(prefix, "."+PDF_FILE_EXT, new File(path)); + m_reportEngine.createPDF(file); + return new AMedia(file.getName(), PDF_FILE_EXT, PDF_MIME_TYPE, file, true); + } catch (Exception e) { + if (e instanceof RuntimeException) + throw (RuntimeException)e; + else + throw new RuntimeException(e); + } + }); + + mediaSuppliers.put(toMediaType(HTML_MIME_TYPE, HTML_FILE_EXT), () -> { + try { + String path = System.getProperty("java.io.tmpdir"); + String prefix = makePrefix(m_reportEngine.getName()); + if (prefix.length() < 3) + prefix += "_".repeat(3-prefix.length()); + if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); + File file = File.createTempFile(prefix, "."+HTML_FILE_EXT, new File(path)); + String contextPath = Executions.getCurrent().getContextPath(); + m_reportEngine.createHTML(file, false, m_reportEngine.getPrintFormat().getLanguage(), new HTMLExtension(contextPath, "rp", getUuid())); + return new AMedia(file.getName(), HTML_FILE_EXT, HTML_MIME_TYPE, file, false); + } catch (Exception e) { + if (e instanceof RuntimeException) + throw (RuntimeException)e; + else + throw new RuntimeException(e); + } + }); + + mediaSuppliers.put(toMediaType(EXCEL_MIME_TYPE, EXCEL_FILE_EXT), () -> { + try { + String path = System.getProperty("java.io.tmpdir"); + String prefix = makePrefix(m_reportEngine.getName()); + if (prefix.length() < 3) + prefix += "_".repeat(3-prefix.length()); + if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); + File file = File.createTempFile(prefix, "."+EXCEL_FILE_EXT, new File(path)); + m_reportEngine.createXLS(file, m_reportEngine.getPrintFormat().getLanguage()); + return new AMedia(file.getName(), EXCEL_FILE_EXT, EXCEL_MIME_TYPE, file, true); + } catch (Exception e) { + if (e instanceof RuntimeException) + throw (RuntimeException)e; + else + throw new RuntimeException(e); + } + }); + + mediaSuppliers.put(toMediaType(CSV_MIME_TYPE, CSV_FILE_EXT), () -> { + try { + String path = System.getProperty("java.io.tmpdir"); + String prefix = makePrefix(m_reportEngine.getName()); + if (log.isLoggable(Level.FINE)) + { + log.log(Level.FINE, "Path="+path + " Prefix="+prefix); + } + File file = File.createTempFile(prefix, "."+CSV_FILE_EXT, new File(path)); + m_reportEngine.createCSV(file, ',', AEnv.getLanguage(Env.getCtx())); + return new AMedia(file.getName(), CSV_FILE_EXT, CSV_MIME_TYPE, file, true); + } catch (Exception e) { + if (e instanceof RuntimeException) + throw (RuntimeException)e; + else + throw new RuntimeException(e); + } + }); + + mediaSuppliers.put(toMediaType(EXCEL_XML_MIME_TYPE, EXCEL_XML_FILE_EXT), () -> { + try { + String path = System.getProperty("java.io.tmpdir"); + String prefix = makePrefix(m_reportEngine.getName()); + if (log.isLoggable(Level.FINE)) + { + log.log(Level.FINE, "Path=" + path + " Prefix=" + prefix); + } + File file = File.createTempFile(prefix, "."+EXCEL_XML_FILE_EXT, new File(path)); + m_reportEngine.createXLSX(file, m_reportEngine.getPrintFormat().getLanguage()); + return new AMedia(file.getName(), EXCEL_XML_FILE_EXT, EXCEL_XML_MIME_TYPE, file, true); + } catch (Exception e) { + if (e instanceof RuntimeException) + throw (RuntimeException)e; + else + throw new RuntimeException(e); + } + }); + + mediaSuppliers.put(toMediaType(POSTSCRIPT_MIME_TYPE, POSTSCRIPT_FILE_EXT), () -> { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + m_reportEngine.createPS(baos); + byte[] data = baos.toByteArray(); + return new AMedia(m_reportEngine.getName() + "."+POSTSCRIPT_FILE_EXT, POSTSCRIPT_FILE_EXT, POSTSCRIPT_MIME_TYPE, data); + }); + + mediaSuppliers.put(toMediaType(XML_MIME_TYPE, XML_FILE_EXT), () -> { + StringWriter sw = new StringWriter(); + m_reportEngine.createXML(sw); + byte[] data = sw.getBuffer().toString().getBytes(); + return new AMedia(m_reportEngine.getName() + "."+XML_FILE_EXT, XML_FILE_EXT, XML_MIME_TYPE, data); + }); + + mediaSuppliers.put(toMediaType(CSV_MIME_TYPE, SSV_FILE_EXT), () -> { + StringWriter sw = new StringWriter(); + m_reportEngine.createCSV(sw, ';', m_reportEngine.getPrintFormat().getLanguage()); + byte[] data = sw.getBuffer().toString().getBytes(); + return new AMedia(m_reportEngine.getName() + "."+SSV_FILE_EXT, SSV_FILE_EXT, CSV_MIME_TYPE, data); + }); + + mediaSuppliers.put(toMediaType(TEXT_MIME_TYPE, TEXT_FILE_EXT), () -> { + StringWriter sw = new StringWriter(); + m_reportEngine.createCSV(sw, '\t', m_reportEngine.getPrintFormat().getLanguage()); + byte[] data = sw.getBuffer().toString().getBytes(); + return new AMedia(m_reportEngine.getName() + "."+TEXT_FILE_EXT, TEXT_FILE_EXT, TEXT_MIME_TYPE, data); + }); } @Override @@ -270,14 +421,14 @@ public class ZkReportViewer extends Window implements EventListener, ITab ZKUpdateUtil.setWidth(toolBar, "100%"); previewType.setMold("select"); - previewType.appendItem("HTML", "HTML"); - previewType.appendItem("PDF", "PDF"); + previewType.appendItem(HTML_OUTPUT_TYPE, HTML_OUTPUT_TYPE); + previewType.appendItem(PDF_OUTPUT_TYPE, PDF_OUTPUT_TYPE); if ( m_isCanExport ) { - previewType.appendItem("XLS", "XLS"); - previewType.appendItem("CSV", "CSV"); - previewType.appendItem("XLSX", "XLSX"); + previewType.appendItem(XLS_OUTPUT_TYPE, XLS_OUTPUT_TYPE); + previewType.appendItem(CSV_OUTPUT_TYPE, CSV_OUTPUT_TYPE); + previewType.appendItem(XLSX_OUTPUT_TYPE, XLSX_OUTPUT_TYPE); } toolBar.appendChild(previewType); @@ -289,13 +440,13 @@ public class ZkReportViewer extends Window implements EventListener, ITab if (m_reportEngine.getReportType() != null) { - if (m_reportEngine.getReportType().equals("PDF")) + if (m_reportEngine.getReportType().equals(PDF_OUTPUT_TYPE)) pTypeIndex = 1; - else if (m_reportEngine.getReportType().equals("XLS") && m_isCanExport) + else if (m_reportEngine.getReportType().equals(XLS_OUTPUT_TYPE) && m_isCanExport) pTypeIndex = 2; - else if (m_reportEngine.getReportType().equals("CSV") && m_isCanExport) + else if (m_reportEngine.getReportType().equals(CSV_OUTPUT_TYPE) && m_isCanExport) pTypeIndex = 3; - else if (m_reportEngine.getReportType().equals("XLSX") && m_isCanExport) + else if (m_reportEngine.getReportType().equals(XLSX_OUTPUT_TYPE) && m_isCanExport) pTypeIndex = 4; } else @@ -303,18 +454,18 @@ public class ZkReportViewer extends Window implements EventListener, ITab //set default type String type = m_reportEngine.getPrintFormat().isForm() // a42niem - provide explicit default and check on client/org specifics - ? MSysConfig.getValue(MSysConfig.ZK_REPORT_FORM_OUTPUT_TYPE,"PDF",Env.getAD_Client_ID(m_ctx),Env.getAD_Org_ID(m_ctx)) - : MSysConfig.getValue(MSysConfig.ZK_REPORT_TABLE_OUTPUT_TYPE,"PDF",Env.getAD_Client_ID(m_ctx),Env.getAD_Org_ID(m_ctx)); + ? MSysConfig.getValue(MSysConfig.ZK_REPORT_FORM_OUTPUT_TYPE,PDF_OUTPUT_TYPE,Env.getAD_Client_ID(m_ctx),Env.getAD_Org_ID(m_ctx)) + : MSysConfig.getValue(MSysConfig.ZK_REPORT_TABLE_OUTPUT_TYPE,PDF_OUTPUT_TYPE,Env.getAD_Client_ID(m_ctx),Env.getAD_Org_ID(m_ctx)); - if ("HTML".equals(type)) { + if (HTML_OUTPUT_TYPE.equals(type)) { pTypeIndex = 0; - } else if ("PDF".equals(type)) { + } else if (PDF_OUTPUT_TYPE.equals(type)) { pTypeIndex = 1; - } else if ("XLS".equals(type) && m_isCanExport) { + } else if (XLS_OUTPUT_TYPE.equals(type) && m_isCanExport) { pTypeIndex = 2; - } else if ("CSV".equals(type) && m_isCanExport) { + } else if (CSV_OUTPUT_TYPE.equals(type) && m_isCanExport) { pTypeIndex = 3; - } else if ("XLSX".equals(type) && m_isCanExport) { + } else if (XLSX_OUTPUT_TYPE.equals(type) && m_isCanExport) { pTypeIndex = 4; } } @@ -545,6 +696,33 @@ public class ZkReportViewer extends Window implements EventListener, ITab }); } + if (m_isCanExport) + { + List accounts = MAuthorizationAccount.getAuthorizedAccouts(Env.getAD_User_ID(Env.getCtx()), MAuthorizationAccount.AD_AUTHORIZATIONSCOPES_Document); + for (MAuthorizationAccount account : accounts) { + IUploadService service = Core.getUploadService(account); + if (service != null) { + uploadServicesMap.put(account, service); + } + } + if (uploadServicesMap.size() > 0) { + bCloudUpload.setName("CloudUpload"); + if (ThemeManager.isUseFontIconForImage()) + bCloudUpload.setIconSclass("z-icon-FileImport"); + else + bCloudUpload.setImage(ThemeManager.getThemeResource("images/FileImport24.png")); + bCloudUpload.setTooltiptext(Util.cleanAmp(Msg.getMsg(Env.getCtx(), "CloudUpload"))); + if (toolbarPopup != null) + { + toolbarPopupLayout.appendChild(bCloudUpload); + bCloudUpload.setLabel(bCloudUpload.getTooltiptext()); + } + else + toolBar.appendChild(bCloudUpload); + bCloudUpload.addEventListener(Events.ON_CLICK, this); + } + } + North north = new North(); layout.appendChild(north); north.appendChild(toolBar); @@ -553,8 +731,6 @@ public class ZkReportViewer extends Window implements EventListener, ITab Center center = new Center(); layout.appendChild(center); iframe = new Iframe(); - //ZKUpdateUtil.setHflex(iframe, "true"); - //ZKUpdateUtil.setVflex(iframe, "true"); ZKUpdateUtil.setWidth(iframe, "100%"); ZKUpdateUtil.setHeight(iframe, "100%"); iframe.setId("reportFrame"); @@ -651,15 +827,15 @@ public class ZkReportViewer extends Window implements EventListener, ITab private void renderReport() { media = null; Listitem selected = previewType.getSelectedItem(); - if (selected == null || "PDF".equals(selected.getValue())) { + if (selected == null || PDF_OUTPUT_TYPE.equals(selected.getValue())) { new PDFRendererRunnable(this).run(); - } else if ("HTML".equals(previewType.getSelectedItem().getValue())) { + } else if (HTML_OUTPUT_TYPE.equals(selected.getValue())) { new HTMLRendererRunnable(this).run(); - } else if ("XLS".equals(previewType.getSelectedItem().getValue())) { + } else if (XLS_OUTPUT_TYPE.equals(selected.getValue())) { new XLSRendererRunnable(this).run(); - } else if ("CSV".equals(previewType.getSelectedItem().getValue())) { + } else if (CSV_OUTPUT_TYPE.equals(selected.getValue())) { new CSVRendererRunnable(this).run(); - } else if ("XLSX".equals(previewType.getSelectedItem().getValue())) { + } else if (XLSX_OUTPUT_TYPE.equals(selected.getValue())) { new XLSXRendererRunnable(this).run(); } } @@ -677,9 +853,9 @@ public class ZkReportViewer extends Window implements EventListener, ITab if (ClientInfo.isMobile()) { Listitem selected = previewType.getSelectedItem(); - if (selected == null || "PDF".equals(selected.getValue())) { + if (selected == null || PDF_OUTPUT_TYPE.equals(selected.getValue())) { iframe.setSrc(pdfJsUrl); - } else if ("HTML".equals(previewType.getSelectedItem().getValue())) { + } else if (HTML_OUTPUT_TYPE.equals(previewType.getSelectedItem().getValue())) { iframe.setSrc(null); iframe.setContent(media); } else { @@ -691,7 +867,7 @@ public class ZkReportViewer extends Window implements EventListener, ITab } else { Listitem selected = previewType.getSelectedItem(); if (MSysConfig.getBooleanValue(MSysConfig.ZK_USE_PDF_JS_VIEWER, false, Env.getAD_Client_ID(Env.getCtx())) - && (selected == null || "PDF".equals(selected.getValue()))) { + && (selected == null || PDF_OUTPUT_TYPE.equals(selected.getValue()))) { iframe.setSrc(pdfJsUrl); } else { iframe.setSrc(null); @@ -928,13 +1104,8 @@ public class ZkReportViewer extends Window implements EventListener, ITab } } - public void onEvent(Event event) throws Exception { - - if(event.getTarget().getId().equals(ConfirmPanel.A_CANCEL)) - winExportFile.onClose(); - else if(event.getTarget().getId().equals(ConfirmPanel.A_OK)) - exportFile(); - else if(event.getName().equals(Events.ON_CLICK) || event.getName().equals(Events.ON_SELECT)) + public void onEvent(Event event) throws Exception { + if(event.getName().equals(Events.ON_CLICK) || event.getName().equals(Events.ON_SELECT)) actionPerformed(event); else if (event.getTarget() == summary) { @@ -965,6 +1136,16 @@ public class ZkReportViewer extends Window implements EventListener, ITab } } + private void cmd_upload() { + if (media == null) + return; + + WReportUploadDialog winUploadFile = new WReportUploadDialog(this); + winUploadFile.setTitle(Msg.getMsg(Env.getCtx(), "CloudUpload") + ": " + getTitle()); + winUploadFile.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED); + AEnv.showWindow(winUploadFile); + } + private void onCtrlKeyEvent(KeyEvent keyEvent) { if (keyEvent.isAltKey() && keyEvent.getKeyCode() == 0x58) { // Alt-X if (m_WindowNo > 0) { @@ -1013,6 +1194,8 @@ public class ZkReportViewer extends Window implements EventListener, ITab cmd_window(m_ddQ); else if (e.getTarget() == m_daM) cmd_window(m_daQ); + else if (e.getTarget() == bCloudUpload) + cmd_upload(); } // actionPerformed private void cmd_render() { @@ -1106,142 +1289,12 @@ public class ZkReportViewer extends Window implements EventListener, ITab return; } - if(winExportFile == null) - { - winExportFile = new Window(); - winExportFile.setTitle(Msg.getMsg(Env.getCtx(), "Export") + ": " + getTitle()); - ZKUpdateUtil.setWindowWidthX(winExportFile, 450); - ZKUpdateUtil.setWindowHeightX(winExportFile, 150); - winExportFile.setClosable(true); - winExportFile.setBorder("normal"); - winExportFile.setSclass("popup-dialog"); - winExportFile.setStyle("position:absolute"); - - cboType.setMold("select"); - - cboType.getItems().clear(); - cboType.appendItem("ps" + " - " + Msg.getMsg(Env.getCtx(), "FilePS"), "ps"); - cboType.appendItem("xml" + " - " + Msg.getMsg(Env.getCtx(), "FileXML"), "xml"); - ListItem li = cboType.appendItem("pdf" + " - " + Msg.getMsg(Env.getCtx(), "FilePDF"), "pdf"); - cboType.appendItem("html" + " - " + Msg.getMsg(Env.getCtx(), "FileHTML"), "html"); - cboType.appendItem("txt" + " - " + Msg.getMsg(Env.getCtx(), "FileTXT"), "txt"); - cboType.appendItem("ssv" + " - " + Msg.getMsg(Env.getCtx(), "FileSSV"), "ssv"); - cboType.appendItem("csv" + " - " + Msg.getMsg(Env.getCtx(), "FileCSV"), "csv"); - cboType.appendItem("xls" + " - " + Msg.getMsg(Env.getCtx(), "FileXLS"), "xls"); - cboType.appendItem("xlsx" + " - " + Msg.getMsg(Env.getCtx(), "FileXLSX"), "xlsx"); - cboType.setSelectedItem(li); - - Hbox hb = new Hbox(); - hb.setSclass("dialog-content"); - hb.setAlign("center"); - hb.setPack("start"); - Div div = new Div(); - div.setStyle("text-align: right;"); - div.appendChild(new Label(Msg.getMsg(Env.getCtx(), "FilesOfType"))); - hb.appendChild(div); - hb.appendChild(cboType); - ZKUpdateUtil.setWidth(cboType, "100%"); - - Vbox vb = new Vbox(); - ZKUpdateUtil.setWidth(vb, "100%"); - winExportFile.appendChild(vb); - vb.appendChild(hb); - vb.appendChild(confirmPanel); - LayoutUtils.addSclass("dialog-footer", confirmPanel); - confirmPanel.addActionListener(this); - } - + WReportExportDialog winExportFile = new WReportExportDialog(this); + winExportFile.setTitle(Msg.getMsg(Env.getCtx(), "Export") + ": " + getTitle()); winExportFile.setAttribute(Window.MODE_KEY, Window.MODE_HIGHLIGHTED); AEnv.showWindow(winExportFile); } // cmd_export - private void exportFile() - { - try - { - ListItem li = cboType.getSelectedItem(); - if(li == null || li.getValue() == null) - { - FDialog.error(m_WindowNo, winExportFile, "FileInvalidExtension"); - return; - } - - String ext = li.getValue().toString(); - - byte[] data = null; - File inputFile = null; - - if (ext.equals("pdf")) - { - data = m_reportEngine.createPDFData(); - } - else if (ext.equals("ps")) - { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - m_reportEngine.createPS(baos); - data = baos.toByteArray(); - } - else if (ext.equals("xml")) - { - StringWriter sw = new StringWriter(); - m_reportEngine.createXML(sw); - data = sw.getBuffer().toString().getBytes(); - } - else if (ext.equals("csv")) - { - StringWriter sw = new StringWriter(); - m_reportEngine.createCSV(sw, ',', m_reportEngine.getPrintFormat().getLanguage()); - data = sw.getBuffer().toString().getBytes(); - } - else if (ext.equals("ssv")) - { - StringWriter sw = new StringWriter(); - m_reportEngine.createCSV(sw, ';', m_reportEngine.getPrintFormat().getLanguage()); - data = sw.getBuffer().toString().getBytes(); - } - else if (ext.equals("txt")) - { - StringWriter sw = new StringWriter(); - m_reportEngine.createCSV(sw, '\t', m_reportEngine.getPrintFormat().getLanguage()); - data = sw.getBuffer().toString().getBytes(); - } - else if (ext.equals("html") || ext.equals("htm")) - { - StringWriter sw = new StringWriter(); - String contextPath = Executions.getCurrent().getContextPath(); - m_reportEngine.createHTML(sw, false, m_reportEngine.getPrintFormat().getLanguage(), new HTMLExtension(contextPath, "rp", this.getUuid()), true); - data = sw.getBuffer().toString().getBytes(); - } - else if (ext.equals("xlsx")) - { - inputFile = File.createTempFile("Export", ".xlsx"); - m_reportEngine.createXLSX(inputFile, m_reportEngine.getPrintFormat().getLanguage()); - } - else if (ext.equals("xls")) - { - inputFile = File.createTempFile("Export", ".xls"); - m_reportEngine.createXLS(inputFile, m_reportEngine.getPrintFormat().getLanguage()); - } - else - { - FDialog.error(m_WindowNo, winExportFile, "FileInvalidExtension"); - return; - } - - winExportFile.onClose(); - AMedia media = null; - if (data != null) - media = new AMedia(m_reportEngine.getName() + "." + ext, null, "application/octet-stream", data); - else - media = new AMedia(m_reportEngine.getName() + "." + ext, null, "application/octet-stream", inputFile, true); - Filedownload.save(media, m_reportEngine.getName() + "." + ext); - } - catch (Exception e) - { - log.log(Level.SEVERE, "Failed to export content.", e); - } - } - /** * Report Combo - Start other Report or create new one */ @@ -1560,14 +1613,7 @@ public class ZkReportViewer extends Window implements EventListener, ITab try { if (!ArchiveEngine.isValid(viewer.m_reportEngine.getLayout())) log.warning("Cannot archive Document"); - String path = System.getProperty("java.io.tmpdir"); - String prefix = viewer.makePrefix(viewer.m_reportEngine.getName()); - if (prefix.length() < 3) - prefix += "_".repeat(3-prefix.length()); - if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); - File file = File.createTempFile(prefix, ".pdf", new File(path)); - viewer.m_reportEngine.createPDF(file); - viewer.media = new AMedia(file.getName(), "pdf", "application/pdf", file, true); + viewer.createNewMedia(PDF_MIME_TYPE, PDF_FILE_EXT); } catch (Exception e) { if (e instanceof RuntimeException) throw (RuntimeException)e; @@ -1593,12 +1639,10 @@ public class ZkReportViewer extends Window implements EventListener, ITab static class HTMLRendererRunnable extends ContextRunnable implements IServerPushCallback { private ZkReportViewer viewer; - private String contextPath; - public HTMLRendererRunnable(ZkReportViewer viewer) { super(); this.viewer = viewer; - contextPath = Executions.getCurrent().getContextPath(); + } @Override @@ -1606,14 +1650,7 @@ public class ZkReportViewer extends Window implements EventListener, ITab try { if (!ArchiveEngine.isValid(viewer.m_reportEngine.getLayout())) log.warning("Cannot archive Document"); - String path = System.getProperty("java.io.tmpdir"); - String prefix = viewer.makePrefix(viewer.m_reportEngine.getName()); - if (prefix.length() < 3) - prefix += "_".repeat(3-prefix.length()); - if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); - File file = File.createTempFile(prefix, ".html", new File(path)); - viewer.m_reportEngine.createHTML(file, false, viewer.m_reportEngine.getPrintFormat().getLanguage(), new HTMLExtension(contextPath, "rp", viewer.getUuid())); - viewer.media = new AMedia(file.getName(), "html", "text/html", file, false); + viewer.createNewMedia(HTML_MIME_TYPE, HTML_FILE_EXT); } catch (Exception e) { if (e instanceof RuntimeException) throw (RuntimeException)e; @@ -1651,14 +1688,7 @@ public class ZkReportViewer extends Window implements EventListener, ITab try { if (!ArchiveEngine.isValid(viewer.m_reportEngine.getLayout())) log.warning("Cannot archive Document"); - String path = System.getProperty("java.io.tmpdir"); - String prefix = viewer.makePrefix(viewer.m_reportEngine.getName()); - if (prefix.length() < 3) - prefix += "_".repeat(3-prefix.length()); - if (log.isLoggable(Level.FINE)) log.log(Level.FINE, "Path="+path + " Prefix="+prefix); - File file = File.createTempFile(prefix, ".xls", new File(path)); - viewer.m_reportEngine.createXLS(file, viewer.m_reportEngine.getPrintFormat().getLanguage()); - viewer.media = new AMedia(file.getName(), "xls", "application/vnd.ms-excel", file, true); + viewer.createNewMedia(EXCEL_MIME_TYPE, EXCEL_FILE_EXT); } catch (Exception e) { if (e instanceof RuntimeException) throw (RuntimeException)e; @@ -1693,15 +1723,7 @@ public class ZkReportViewer extends Window implements EventListener, ITab @Override protected void doRun() { try { - String path = System.getProperty("java.io.tmpdir"); - String prefix = viewer.makePrefix(viewer.m_reportEngine.getName()); - if (log.isLoggable(Level.FINE)) - { - log.log(Level.FINE, "Path="+path + " Prefix="+prefix); - } - File file = File.createTempFile(prefix, ".csv", new File(path)); - viewer.m_reportEngine.createCSV(file, ',', AEnv.getLanguage(Env.getCtx())); - viewer.media = new AMedia(file.getName(), "csv", "text/csv", file, true); + viewer.createNewMedia(CSV_MIME_TYPE,CSV_FILE_EXT); } catch (Exception e) { if (e instanceof RuntimeException) throw (RuntimeException)e; @@ -1742,16 +1764,7 @@ public class ZkReportViewer extends Window implements EventListener, ITab { if (!ArchiveEngine.isValid(viewer.m_reportEngine.getLayout())) log.warning("Cannot archive Document"); - String path = System.getProperty("java.io.tmpdir"); - String prefix = viewer.makePrefix(viewer.m_reportEngine.getName()); - if (log.isLoggable(Level.FINE)) - { - log.log(Level.FINE, "Path=" + path + " Prefix=" + prefix); - } - File file = File.createTempFile(prefix, ".xlsx", new File(path)); - viewer.m_reportEngine.createXLSX(file, viewer.m_reportEngine.getPrintFormat().getLanguage()); - viewer.media = new AMedia(file.getName(), "xlsx", - "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", file, true); + viewer.createNewMedia(EXCEL_XML_MIME_TYPE, EXCEL_XML_FILE_EXT); } catch (Exception e) { @@ -1780,4 +1793,44 @@ public class ZkReportViewer extends Window implements EventListener, ITab } + private void createNewMedia(String contentType, String fileExtension) { + media = null; + media = getMedia(contentType, fileExtension); + } + + @Override + public AMedia getMedia(String contentType, String fileExtension) { + if (media != null && media.getContentType().equals(contentType) && media.getFormat().equals(fileExtension)) + return media; + + Supplier supplier = mediaSuppliers.get(toMediaType(contentType, fileExtension)); + return supplier != null ? supplier.get() : null; + } + + + @Override + public ExportFormat[] getExportFormats() { + return exportFormats; + } + + @Override + public String getContentType() { + return media != null ? media.getContentType() : null; + } + + @Override + public String getFileExtension() { + return media != null ? media.getFormat() : null; + } + + @Override + public Map getUploadServiceMap() { + return Collections.unmodifiableMap(uploadServicesMap); + } + + @Override + public String getReportName() { + return m_reportEngine.getName(); + } + } diff --git a/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java b/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java index 170a8a9d97..6e280037df 100644 --- a/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java +++ b/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java @@ -1341,9 +1341,9 @@ public class DB_Oracle implements AdempiereDatabase .append(columnName) .append(")"); builder.append(" submultiset of ") - .append("toTableOfVarchar2('") - .append(csv) - .append("')"); + .append("toTableOfVarchar2(") + .append(DB.TO_STRING(csv)) + .append(")"); return builder.toString(); } @@ -1355,9 +1355,9 @@ public class DB_Oracle implements AdempiereDatabase .append(columnName) .append(")"); builder.append(" MULTISET INTERSECT ") - .append("toTableOfVarchar2('") - .append(csv) - .append("') IS NOT EMPTY"); + .append("toTableOfVarchar2(") + .append(DB.TO_STRING(csv)) + .append(") IS NOT EMPTY"); return builder.toString(); } diff --git a/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java b/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java index 0b9fc3f6cc..d21722d186 100755 --- a/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java +++ b/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java @@ -1186,9 +1186,9 @@ public class DB_PostgreSQL implements AdempiereDatabase .append(columnName) .append(",',')"); builder.append(" <@ "); //is contained by - builder.append("string_to_array('") - .append(csv) - .append("',',')"); + builder.append("string_to_array(") + .append(DB.TO_STRING(csv)) + .append(",',')"); return builder.toString(); } @@ -1215,10 +1215,10 @@ public class DB_PostgreSQL implements AdempiereDatabase builder.append("string_to_array(") .append(columnName) .append(",',')"); - builder.append(" && "); //is contained by - builder.append("string_to_array('") - .append(csv) - .append("',',')"); + builder.append(" && "); //intersect + builder.append("string_to_array(") + .append(DB.TO_STRING(csv)) + .append(",',')"); return builder.toString(); }