From a1a7b80bd03620030f162196503fc2d4de0e5e44 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Tue, 21 May 2019 18:17:05 +0200 Subject: [PATCH 1/5] IDEMPIERE-2850 Allow to schedule background reports in xls --- .../oracle/201905202132_IDEMPIERE-2850.sql | 79 ++++++++++++ .../201905202132_IDEMPIERE-2850.sql | 76 +++++++++++ .../org/compiere/model/I_AD_Scheduler.java | 24 ++++ .../src/org/compiere/model/MSchedule.java | 3 +- .../org/compiere/model/X_AD_Scheduler.java | 55 +++++++- .../src/org/compiere/print/ReportEngine.java | 120 +++++++++++++++++- .../org/compiere/print/ServerReportCtl.java | 94 +++++++++++++- .../src/org/compiere/process/ProcessInfo.java | 3 +- .../src/org/compiere/report/FinReport.java | 12 +- .../report/jasper/ReportStarter.java | 32 +++-- .../server/org/compiere/server/Scheduler.java | 87 ++++++++----- .../webui/apps/AbstractProcessDialog.java | 110 +++++++++++----- .../webui/apps/ProcessModalDialog.java | 10 ++ .../adempiere/webui/window/ZkJRViewer.java | 7 +- .../webui/window/ZkReportViewer.java | 58 ++++++++- .../org/compiere/apps/AbstractProcessCtl.java | 2 + 16 files changed, 681 insertions(+), 91 deletions(-) create mode 100644 migration/i6.2/oracle/201905202132_IDEMPIERE-2850.sql create mode 100644 migration/i6.2/postgresql/201905202132_IDEMPIERE-2850.sql diff --git a/migration/i6.2/oracle/201905202132_IDEMPIERE-2850.sql b/migration/i6.2/oracle/201905202132_IDEMPIERE-2850.sql new file mode 100644 index 0000000000..e90c54842c --- /dev/null +++ b/migration/i6.2/oracle/201905202132_IDEMPIERE-2850.sql @@ -0,0 +1,79 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- IDEMPIERE-2850 +-- May 20, 2019, 9:32:31 PM CEST +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 (203337,0,0,'Y',TO_DATE('2019-05-20 21:32:30','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-05-20 21:32:30','YYYY-MM-DD HH24:MI:SS'),100,'ReportOutputType','Report Output Type','Report Output Type','D','cd782f63-e5c5-4f12-8925-4b13733002b8') +; + +-- May 20, 2019, 9:32:31 PM CEST +INSERT INTO AD_Reference (AD_Reference_ID,Name,ValidationType,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,IsOrderByValue,AD_Reference_UU) VALUES (200169,'ReportOutputType','L',0,0,'Y',TO_DATE('2019-05-20 21:32:31','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-05-20 21:32:31','YYYY-MM-DD HH24:MI:SS'),100,'D','N','b6fc4bb2-ce72-4de3-b753-302da5fd1173') +; + +-- May 20, 2019, 9:32:32 PM CEST +INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200470,'PDF',200169,'PDF',0,0,'Y',TO_DATE('2019-05-20 21:32:31','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-05-20 21:32:31','YYYY-MM-DD HH24:MI:SS'),100,'D','303c23cc-5dcf-4f5a-a105-8b62f856165a') +; + +-- May 20, 2019, 9:32:32 PM CEST +INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200471,'HTML',200169,'HTML',0,0,'Y',TO_DATE('2019-05-20 21:32:32','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-05-20 21:32:32','YYYY-MM-DD HH24:MI:SS'),100,'D','67cf2cdf-75a2-441c-ab33-12033e121e69') +; + +-- May 20, 2019, 9:32:32 PM CEST +INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200472,'Excel',200169,'XLS',0,0,'Y',TO_DATE('2019-05-20 21:32:32','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-05-20 21:32:32','YYYY-MM-DD HH24:MI:SS'),100,'D','0190b839-041b-43ae-a5f5-a52efb120e9d') +; + +-- May 20, 2019, 9:32:33 PM CEST +INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200473,'CSV',200169,'CSV',0,0,'Y',TO_DATE('2019-05-20 21:32:32','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-05-20 21:32:32','YYYY-MM-DD HH24:MI:SS'),100,'D','e0aa166a-b354-46d5-8a60-e2e21bf49f44') +; + +-- May 20, 2019, 9:32:33 PM CEST +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,FKConstraintType) VALUES (213942,1,'Report Output Type',688,'ReportOutputType',4,'N','N','N','N','N',0,'N',17,200169,0,0,'Y',TO_DATE('2019-05-20 21:32:33','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-05-20 21:32:33','YYYY-MM-DD HH24:MI:SS'),100,203337,'Y','N','D','Y','N','N','Y','45acf545-7427-4c34-a6a5-c74b10ebb13b','Y',0,'N','N','N') +; + +-- May 20, 2019, 9:32:33 PM CEST +ALTER TABLE AD_Scheduler ADD ReportOutputType VARCHAR2(4) DEFAULT NULL +; + +-- May 20, 2019, 9:32:33 PM CEST +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 (200135,'PrintFormat for Process','S','AD_PrintFormat.AD_Table_ID IN (select coalesce(rv.ad_table_id,pp.ad_table_id) from ad_process p left join ad_reportview rv on p.ad_reportview_id=rv.ad_reportview_id left join ad_printformat pp on p.ad_printformat_id=pp.ad_printformat_id where p.ad_process_id=@AD_Process_ID@)',0,0,'Y',TO_DATE('2019-05-20 21:32:33','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-05-20 21:32:33','YYYY-MM-DD HH24:MI:SS'),100,'D','5b2362f8-10ed-4b0d-b636-c47b7cd15b78') +; + +-- May 20, 2019, 9:32:34 PM CEST +INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,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,FKConstraintName,FKConstraintType) VALUES (213943,0,'Print Format','Data Print Format','The print format determines how data is rendered for print.',688,200135,'AD_PrintFormat_ID',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_DATE('2019-05-20 21:32:33','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-05-20 21:32:33','YYYY-MM-DD HH24:MI:SS'),100,1790,'Y','N','D','Y','N','N','Y','81d67ace-8a49-403c-bc6f-5604d944cfd8','Y',0,'N','N','ADPrintFormat_ADScheduler','S') +; + +-- May 20, 2019, 9:32:34 PM CEST +ALTER TABLE AD_Scheduler ADD AD_PrintFormat_ID NUMBER(10) DEFAULT NULL +; + +-- May 20, 2019, 9:32:34 PM CEST +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) VALUES (206075,'Print Format','Data Print Format','The print format determines how data is rendered for print.',589,213943,'Y','@AD_Process_ID.IsReport@=Y',0,64,0,'N','N','N','N',0,0,'Y',TO_DATE('2019-05-20 21:32:34','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-05-20 21:32:34','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','bc1c07e4-3306-466c-a14b-144eaf6c900e','Y',64,4,2,1,'N','N','N') +; + +-- May 20, 2019, 9:32:34 PM CEST +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) VALUES (206076,'Report Output Type',589,213942,'Y','@AD_Process_ID.IsReport@=Y',0,65,0,'N','N','N','N',0,0,'Y',TO_DATE('2019-05-20 21:32:34','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2019-05-20 21:32:34','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','43f6c13e-6eb0-4a22-b293-49f980f40098','Y',65,1,1,1,'N','N','N') +; + +-- May 20, 2019, 9:32:35 PM CEST +ALTER TABLE AD_Scheduler ADD CONSTRAINT ADPrintFormat_ADScheduler FOREIGN KEY (AD_PrintFormat_ID) REFERENCES ad_printformat(ad_printformat_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED +; + +-- May 21, 2019, 1:03:56 PM CEST +UPDATE AD_SysConfig SET Description='Type of output in zkwebui for reports of type form, possible values are PDF, HTML, XLS, CSV',Updated=TO_DATE('2019-05-21 13:03:56','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200002 +; + +-- May 21, 2019, 1:04:10 PM CEST +UPDATE AD_SysConfig SET Description='Type of output in zkwebui for reports of type table, possible values are PDF, HTML, XLS, CSV',Updated=TO_DATE('2019-05-21 13:04:10','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200003 +; + +-- May 21, 2019, 1:04:51 PM CEST +UPDATE AD_SysConfig SET Description='Type of output in zkwebui for jasper reports, possible values are PDF, HTML, XLS, CSV, SSV',Updated=TO_DATE('2019-05-21 13:04:51','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200030 +; + +-- May 21, 2019, 2:59:39 PM CEST +UPDATE AD_Field SET DisplayLogic='@AD_Process_ID.IsReport@=Y & @AD_Process_ID.JasperReport=''''', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2019-05-21 14:59:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206075 +; + +SELECT register_migration_script('201905202132_IDEMPIERE-2850.sql') FROM dual +; + diff --git a/migration/i6.2/postgresql/201905202132_IDEMPIERE-2850.sql b/migration/i6.2/postgresql/201905202132_IDEMPIERE-2850.sql new file mode 100644 index 0000000000..8016c00c5f --- /dev/null +++ b/migration/i6.2/postgresql/201905202132_IDEMPIERE-2850.sql @@ -0,0 +1,76 @@ +-- IDEMPIERE-2850 +-- May 20, 2019, 9:32:31 PM CEST +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 (203337,0,0,'Y',TO_TIMESTAMP('2019-05-20 21:32:30','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-05-20 21:32:30','YYYY-MM-DD HH24:MI:SS'),100,'ReportOutputType','Report Output Type','Report Output Type','D','cd782f63-e5c5-4f12-8925-4b13733002b8') +; + +-- May 20, 2019, 9:32:31 PM CEST +INSERT INTO AD_Reference (AD_Reference_ID,Name,ValidationType,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,IsOrderByValue,AD_Reference_UU) VALUES (200169,'ReportOutputType','L',0,0,'Y',TO_TIMESTAMP('2019-05-20 21:32:31','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-05-20 21:32:31','YYYY-MM-DD HH24:MI:SS'),100,'D','N','b6fc4bb2-ce72-4de3-b753-302da5fd1173') +; + +-- May 20, 2019, 9:32:32 PM CEST +INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200470,'PDF',200169,'PDF',0,0,'Y',TO_TIMESTAMP('2019-05-20 21:32:31','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-05-20 21:32:31','YYYY-MM-DD HH24:MI:SS'),100,'D','303c23cc-5dcf-4f5a-a105-8b62f856165a') +; + +-- May 20, 2019, 9:32:32 PM CEST +INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200471,'HTML',200169,'HTML',0,0,'Y',TO_TIMESTAMP('2019-05-20 21:32:32','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-05-20 21:32:32','YYYY-MM-DD HH24:MI:SS'),100,'D','67cf2cdf-75a2-441c-ab33-12033e121e69') +; + +-- May 20, 2019, 9:32:32 PM CEST +INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200472,'Excel',200169,'XLS',0,0,'Y',TO_TIMESTAMP('2019-05-20 21:32:32','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-05-20 21:32:32','YYYY-MM-DD HH24:MI:SS'),100,'D','0190b839-041b-43ae-a5f5-a52efb120e9d') +; + +-- May 20, 2019, 9:32:33 PM CEST +INSERT INTO AD_Ref_List (AD_Ref_List_ID,Name,AD_Reference_ID,Value,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,EntityType,AD_Ref_List_UU) VALUES (200473,'CSV',200169,'CSV',0,0,'Y',TO_TIMESTAMP('2019-05-20 21:32:32','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-05-20 21:32:32','YYYY-MM-DD HH24:MI:SS'),100,'D','e0aa166a-b354-46d5-8a60-e2e21bf49f44') +; + +-- May 20, 2019, 9:32:33 PM CEST +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,FKConstraintType) VALUES (213942,1,'Report Output Type',688,'ReportOutputType',4,'N','N','N','N','N',0,'N',17,200169,0,0,'Y',TO_TIMESTAMP('2019-05-20 21:32:33','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-05-20 21:32:33','YYYY-MM-DD HH24:MI:SS'),100,203337,'Y','N','D','Y','N','N','Y','45acf545-7427-4c34-a6a5-c74b10ebb13b','Y',0,'N','N','N') +; + +-- May 20, 2019, 9:32:33 PM CEST +ALTER TABLE AD_Scheduler ADD COLUMN ReportOutputType VARCHAR(4) DEFAULT NULL +; + +-- May 20, 2019, 9:32:33 PM CEST +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 (200135,'PrintFormat for Process','S','AD_PrintFormat.AD_Table_ID IN (select coalesce(rv.ad_table_id,pp.ad_table_id) from ad_process p left join ad_reportview rv on p.ad_reportview_id=rv.ad_reportview_id left join ad_printformat pp on p.ad_printformat_id=pp.ad_printformat_id where p.ad_process_id=@AD_Process_ID@)',0,0,'Y',TO_TIMESTAMP('2019-05-20 21:32:33','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-05-20 21:32:33','YYYY-MM-DD HH24:MI:SS'),100,'D','5b2362f8-10ed-4b0d-b636-c47b7cd15b78') +; + +-- May 20, 2019, 9:32:34 PM CEST +INSERT INTO AD_Column (AD_Column_ID,Version,Name,Description,Help,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,FKConstraintName,FKConstraintType) VALUES (213943,0,'Print Format','Data Print Format','The print format determines how data is rendered for print.',688,200135,'AD_PrintFormat_ID',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_TIMESTAMP('2019-05-20 21:32:33','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-05-20 21:32:33','YYYY-MM-DD HH24:MI:SS'),100,1790,'Y','N','D','Y','N','N','Y','81d67ace-8a49-403c-bc6f-5604d944cfd8','Y',0,'N','N','ADPrintFormat_ADScheduler','S') +; + +-- May 20, 2019, 9:32:34 PM CEST +ALTER TABLE AD_Scheduler ADD COLUMN AD_PrintFormat_ID NUMERIC(10) DEFAULT NULL +; + +-- May 20, 2019, 9:32:34 PM CEST +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) VALUES (206075,'Print Format','Data Print Format','The print format determines how data is rendered for print.',589,213943,'Y','@AD_Process_ID.IsReport@=Y',0,64,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2019-05-20 21:32:34','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-05-20 21:32:34','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','bc1c07e4-3306-466c-a14b-144eaf6c900e','Y',64,4,2,1,'N','N','N') +; + +-- May 20, 2019, 9:32:34 PM CEST +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) VALUES (206076,'Report Output Type',589,213942,'Y','@AD_Process_ID.IsReport@=Y',0,65,0,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2019-05-20 21:32:34','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2019-05-20 21:32:34','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','43f6c13e-6eb0-4a22-b293-49f980f40098','Y',65,1,1,1,'N','N','N') +; + +-- May 20, 2019, 9:32:35 PM CEST +ALTER TABLE AD_Scheduler ADD CONSTRAINT ADPrintFormat_ADScheduler FOREIGN KEY (AD_PrintFormat_ID) REFERENCES ad_printformat(ad_printformat_id) ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED +; + +-- May 21, 2019, 1:03:56 PM CEST +UPDATE AD_SysConfig SET Description='Type of output in zkwebui for reports of type form, possible values are PDF, HTML, XLS, CSV',Updated=TO_TIMESTAMP('2019-05-21 13:03:56','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200002 +; + +-- May 21, 2019, 1:04:10 PM CEST +UPDATE AD_SysConfig SET Description='Type of output in zkwebui for reports of type table, possible values are PDF, HTML, XLS, CSV',Updated=TO_TIMESTAMP('2019-05-21 13:04:10','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200003 +; + +-- May 21, 2019, 1:04:51 PM CEST +UPDATE AD_SysConfig SET Description='Type of output in zkwebui for jasper reports, possible values are PDF, HTML, XLS, CSV, SSV',Updated=TO_TIMESTAMP('2019-05-21 13:04:51','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200030 +; + +-- May 21, 2019, 2:59:39 PM CEST +UPDATE AD_Field SET DisplayLogic='@AD_Process_ID.IsReport@=Y & @AD_Process_ID.JasperReport=''''', AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2019-05-21 14:59:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206075 +; + +SELECT register_migration_script('201905202132_IDEMPIERE-2850.sql') FROM dual +; + diff --git a/org.adempiere.base/src/org/compiere/model/I_AD_Scheduler.java b/org.adempiere.base/src/org/compiere/model/I_AD_Scheduler.java index cb1987a666..50dfc1e138 100644 --- a/org.adempiere.base/src/org/compiere/model/I_AD_Scheduler.java +++ b/org.adempiere.base/src/org/compiere/model/I_AD_Scheduler.java @@ -62,6 +62,21 @@ public interface I_AD_Scheduler */ public int getAD_Org_ID(); + /** Column name AD_PrintFormat_ID */ + public static final String COLUMNNAME_AD_PrintFormat_ID = "AD_PrintFormat_ID"; + + /** Set Print Format. + * Data Print Format + */ + public void setAD_PrintFormat_ID (int AD_PrintFormat_ID); + + /** Get Print Format. + * Data Print Format + */ + public int getAD_PrintFormat_ID(); + + public org.compiere.model.I_AD_PrintFormat getAD_PrintFormat() throws RuntimeException; + /** Column name AD_Process_ID */ public static final String COLUMNNAME_AD_Process_ID = "AD_Process_ID"; @@ -241,6 +256,15 @@ public interface I_AD_Scheduler */ public int getRecord_ID(); + /** Column name ReportOutputType */ + public static final String COLUMNNAME_ReportOutputType = "ReportOutputType"; + + /** Set Report Output Type */ + public void setReportOutputType (String ReportOutputType); + + /** Get Report Output Type */ + public String getReportOutputType(); + /** Column name R_MailText_ID */ public static final String COLUMNNAME_R_MailText_ID = "R_MailText_ID"; diff --git a/org.adempiere.base/src/org/compiere/model/MSchedule.java b/org.adempiere.base/src/org/compiere/model/MSchedule.java index b2a7a9fe9f..a95f0ba7f4 100644 --- a/org.adempiere.base/src/org/compiere/model/MSchedule.java +++ b/org.adempiere.base/src/org/compiere/model/MSchedule.java @@ -90,7 +90,8 @@ public class MSchedule extends X_AD_Schedule public boolean isOKtoRunOnIP() { String ipOnly = getRunOnlyOnIP(); - if ((ipOnly == null) || (ipOnly.length() == 0)) + // 0.0.0.0 = all ip address + if ((ipOnly == null) || (ipOnly.length() == 0) || "0.0.0.0".equals(ipOnly)) return true; StringTokenizer st = new StringTokenizer(ipOnly, ";"); diff --git a/org.adempiere.base/src/org/compiere/model/X_AD_Scheduler.java b/org.adempiere.base/src/org/compiere/model/X_AD_Scheduler.java index 0ac67079b2..f93b44c053 100644 --- a/org.adempiere.base/src/org/compiere/model/X_AD_Scheduler.java +++ b/org.adempiere.base/src/org/compiere/model/X_AD_Scheduler.java @@ -31,7 +31,7 @@ public class X_AD_Scheduler extends PO implements I_AD_Scheduler, I_Persistent /** * */ - private static final long serialVersionUID = 20190106L; + private static final long serialVersionUID = 20190521L; /** Standard Constructor */ public X_AD_Scheduler (Properties ctx, int AD_Scheduler_ID, String trxName) @@ -77,6 +77,34 @@ public class X_AD_Scheduler extends PO implements I_AD_Scheduler, I_Persistent return sb.toString(); } + public org.compiere.model.I_AD_PrintFormat getAD_PrintFormat() throws RuntimeException + { + return (org.compiere.model.I_AD_PrintFormat)MTable.get(getCtx(), org.compiere.model.I_AD_PrintFormat.Table_Name) + .getPO(getAD_PrintFormat_ID(), get_TrxName()); } + + /** Set Print Format. + @param AD_PrintFormat_ID + Data Print Format + */ + public void setAD_PrintFormat_ID (int AD_PrintFormat_ID) + { + if (AD_PrintFormat_ID < 1) + set_Value (COLUMNNAME_AD_PrintFormat_ID, null); + else + set_Value (COLUMNNAME_AD_PrintFormat_ID, Integer.valueOf(AD_PrintFormat_ID)); + } + + /** Get Print Format. + @return Data Print Format + */ + public int getAD_PrintFormat_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_AD_PrintFormat_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + public org.compiere.model.I_AD_Process getAD_Process() throws RuntimeException { return (org.compiere.model.I_AD_Process)MTable.get(getCtx(), org.compiere.model.I_AD_Process.Table_Name) @@ -335,6 +363,31 @@ public class X_AD_Scheduler extends PO implements I_AD_Scheduler, I_Persistent return ii.intValue(); } + /** ReportOutputType AD_Reference_ID=200169 */ + public static final int REPORTOUTPUTTYPE_AD_Reference_ID=200169; + /** PDF = PDF */ + public static final String REPORTOUTPUTTYPE_PDF = "PDF"; + /** HTML = HTML */ + public static final String REPORTOUTPUTTYPE_HTML = "HTML"; + /** Excel = XLS */ + public static final String REPORTOUTPUTTYPE_Excel = "XLS"; + /** CSV = CSV */ + public static final String REPORTOUTPUTTYPE_CSV = "CSV"; + /** Set Report Output Type. + @param ReportOutputType Report Output Type */ + public void setReportOutputType (String ReportOutputType) + { + + set_Value (COLUMNNAME_ReportOutputType, ReportOutputType); + } + + /** Get Report Output Type. + @return Report Output Type */ + public String getReportOutputType () + { + return (String)get_Value(COLUMNNAME_ReportOutputType); + } + public org.compiere.model.I_R_MailText getR_MailText() throws RuntimeException { return (org.compiere.model.I_R_MailText)MTable.get(getCtx(), org.compiere.model.I_R_MailText.Table_Name) diff --git a/org.adempiere.base/src/org/compiere/print/ReportEngine.java b/org.adempiere.base/src/org/compiere/print/ReportEngine.java index bd87d854da..19c643a08f 100644 --- a/org.adempiere.base/src/org/compiere/print/ReportEngine.java +++ b/org.adempiere.base/src/org/compiere/print/ReportEngine.java @@ -866,7 +866,7 @@ queued-job-count = 0 (class javax.print.attribute.standard.QueuedJobCount) log.log(Level.SEVERE, "(w)", e); throw new AdempiereException(e); } - return false; + return true; } // createHTML @@ -997,8 +997,9 @@ queued-job-count = 0 (class javax.print.attribute.standard.QueuedJobCount) catch (Exception e) { log.log(Level.SEVERE, "(w)", e); + return false; } - return false; + return true; } // createCSV /** @@ -1103,7 +1104,7 @@ queued-job-count = 0 (class javax.print.attribute.standard.QueuedJobCount) try { if (file == null) - file = File.createTempFile ("ReportEngine", ".pdf"); + file = File.createTempFile (makePrefix(getName()), ".pdf"); } catch (IOException e) { @@ -1114,6 +1115,106 @@ queued-job-count = 0 (class javax.print.attribute.standard.QueuedJobCount) return null; } // getPDF + /************************************************************************** + * Create HTML file. + * (created in temporary storage) + * @return HTML file + */ + public File getHTML() + { + return getHTML(null); + } // getHTML + + /** + * Create HTML file. + * @param file file + * @return HTML file + */ + public File getHTML(File file) + { + try + { + if (file == null) + file = File.createTempFile (makePrefix(getName()), ".html"); + } + catch (IOException e) + { + log.log(Level.SEVERE, "", e); + } + if (createHTML(file, false, Env.getLanguage(getCtx()))) + return file; + return null; + } // getHTML + + /************************************************************************** + * Create CSV file. + * (created in temporary storage) + * @return CSV file + */ + public File getCSV() + { + return getCSV(null); + } // getCSV + + /** + * Create CSV file. + * @param file file + * @return CSV file + */ + public File getCSV(File file) + { + try + { + if (file == null) + file = File.createTempFile (makePrefix(getName()), ".csv"); + } + catch (IOException e) + { + log.log(Level.SEVERE, "", e); + } + if (createCSV(file, ',', Env.getLanguage(getCtx()))) + return file; + return null; + } // getCSV + + /************************************************************************** + * Create XLS file. + * (created in temporary storage) + * @return XLS file + */ + public File getXLS() + { + return getXLS(null); + } // getXLS + + /** + * Create XLS file. + * @param file file + * @return XLS file + */ + public File getXLS(File file) + { + try + { + if (file == null) + file = File.createTempFile (makePrefix(getName()), ".xls"); + } + catch (IOException e) + { + log.log(Level.SEVERE, "", e); + } + try + { + createXLS(file, Env.getLanguage(getCtx())); + return file; + } + catch (Exception e) + { + log.log(Level.SEVERE, "", e); + return null; + } + } // getXLS + /** * Create PDF File * @param file file @@ -1167,6 +1268,19 @@ queued-job-count = 0 (class javax.print.attribute.standard.QueuedJobCount) return file2.exists(); } // createPDF + private String makePrefix(String name) { + StringBuilder prefix = new StringBuilder(); + char[] nameArray = name.toCharArray(); + for (char ch : nameArray) { + if (Character.isLetterOrDigit(ch)) { + prefix.append(ch); + } else { + prefix.append("_"); + } + } + return prefix.toString(); + } + /** * Create PDF as Data array * @return pdf data diff --git a/org.adempiere.base/src/org/compiere/print/ServerReportCtl.java b/org.adempiere.base/src/org/compiere/print/ServerReportCtl.java index 12af7b4db2..6282570e6a 100644 --- a/org.adempiere.base/src/org/compiere/print/ServerReportCtl.java +++ b/org.adempiere.base/src/org/compiere/print/ServerReportCtl.java @@ -94,7 +94,28 @@ public class ServerReportCtl { { if (pi != null && pi.isBatch() && pi.isPrintPreview()) { - pi.setPDFReport(re.getPDF()); + if ("HTML".equals(pi.getReportType())) + { + pi.setExport(true); + pi.setExportFileExtension("html"); + pi.setExportFile(re.getHTML()); + } + else if ("CSV".equals(pi.getReportType())) + { + pi.setExport(true); + pi.setExportFileExtension("csv"); + pi.setExportFile(re.getCSV()); + } + else if ("XLS".equals(pi.getReportType())) + { + pi.setExport(true); + pi.setExportFileExtension("xls"); + pi.setExportFile(re.getXLS()); + } + else + { + pi.setPDFReport(re.getPDF()); + } } else { @@ -261,10 +282,31 @@ public class ServerReportCtl { String TableName = MTable.getTableName(ctx, format.getAD_Table_ID()); MQuery query = MQuery.get (ctx, pi.getAD_PInstance_ID(), TableName); PrintInfo info = new PrintInfo(pi); - re = new ReportEngine(ctx, format, query, info, pi.getTransactionName()); + re = new ReportEngine(ctx, format, query, info, pi.isSummary(), pi.getTransactionName()); if (pi.isPrintPreview() && pi.isBatch()) { - pi.setPDFReport(re.getPDF()); + if ("HTML".equals(pi.getReportType())) + { + pi.setExport(true); + pi.setExportFileExtension("html"); + pi.setExportFile(re.getHTML()); + } + else if ("CSV".equals(pi.getReportType())) + { + pi.setExport(true); + pi.setExportFileExtension("csv"); + pi.setExportFile(re.getCSV()); + } + else if ("XLS".equals(pi.getReportType())) + { + pi.setExport(true); + pi.setExportFileExtension("xls"); + pi.setExportFile(re.getXLS()); + } + else + { + pi.setPDFReport(re.getPDF()); + } } else { @@ -285,7 +327,28 @@ public class ServerReportCtl { if (pi.isPrintPreview() && pi.isBatch()) { - pi.setPDFReport(re.getPDF()); + if ("HTML".equals(pi.getReportType())) + { + pi.setExport(true); + pi.setExportFileExtension("html"); + pi.setExportFile(re.getHTML()); + } + else if ("CSV".equals(pi.getReportType())) + { + pi.setExport(true); + pi.setExportFileExtension("csv"); + pi.setExportFile(re.getCSV()); + } + else if ("XLS".equals(pi.getReportType())) + { + pi.setExport(true); + pi.setExportFileExtension("xls"); + pi.setExportFile(re.getXLS()); + } + else + { + pi.setPDFReport(re.getPDF()); + } } else { @@ -322,7 +385,28 @@ public class ServerReportCtl { ReportEngine re = new ReportEngine(Env.getCtx(), format, query, info); if (pi.isPrintPreview() && pi.isBatch()) { - pi.setPDFReport(re.getPDF()); + if ("HTML".equals(pi.getReportType())) + { + pi.setExport(true); + pi.setExportFileExtension("html"); + pi.setExportFile(re.getHTML()); + } + else if ("CSV".equals(pi.getReportType())) + { + pi.setExport(true); + pi.setExportFileExtension("csv"); + pi.setExportFile(re.getCSV()); + } + else if ("XLS".equals(pi.getReportType())) + { + pi.setExport(true); + pi.setExportFileExtension("xls"); + pi.setExportFile(re.getXLS()); + } + else + { + pi.setPDFReport(re.getPDF()); + } } else { diff --git a/org.adempiere.base/src/org/compiere/process/ProcessInfo.java b/org.adempiere.base/src/org/compiere/process/ProcessInfo.java index 81760af172..2ee731b625 100644 --- a/org.adempiere.base/src/org/compiere/process/ProcessInfo.java +++ b/org.adempiere.base/src/org/compiere/process/ProcessInfo.java @@ -173,7 +173,8 @@ public class ProcessInfo implements Serializable } public void setReportType(String reportType) { - this.reportType = reportType; + if (!Util.isEmpty(reportType)) + this.reportType = reportType; } public void setIsSummary(boolean isSummary) { diff --git a/org.adempiere.base/src/org/compiere/report/FinReport.java b/org.adempiere.base/src/org/compiere/report/FinReport.java index e4948487cd..8856160c8a 100644 --- a/org.adempiere.base/src/org/compiere/report/FinReport.java +++ b/org.adempiere.base/src/org/compiere/report/FinReport.java @@ -345,10 +345,16 @@ public class FinReport extends SvrProcess scaleResults(); // Create Report - if (Ini.isClient()) - getProcessInfo().setTransientObject (getPrintFormat()); + if (Ini.isClient()) + { + if (getProcessInfo().getTransientObject() == null) + getProcessInfo().setTransientObject (getPrintFormat()); + } else - getProcessInfo().setSerializableObject(getPrintFormat()); + { + if (getProcessInfo().getSerializableObject() == null) + getProcessInfo().setSerializableObject(getPrintFormat()); + } if (log.isLoggable(Level.FINE)) log.fine((System.currentTimeMillis() - m_start) + " ms"); return ""; diff --git a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java index b170cf149a..3a91485679 100644 --- a/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java +++ b/org.adempiere.report.jasper/src/org/adempiere/report/jasper/ReportStarter.java @@ -108,13 +108,14 @@ import net.sf.jasperreports.export.ExporterOutput; import net.sf.jasperreports.export.SimpleCsvExporterConfiguration; import net.sf.jasperreports.export.SimpleExporterConfiguration; import net.sf.jasperreports.export.SimpleExporterInput; -import net.sf.jasperreports.export.SimpleHtmlExporterConfiguration; +import net.sf.jasperreports.export.SimpleHtmlExporterOutput; +import net.sf.jasperreports.export.SimpleHtmlReportConfiguration; import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput; import net.sf.jasperreports.export.SimplePdfExporterConfiguration; import net.sf.jasperreports.export.SimplePrintServiceExporterConfiguration; import net.sf.jasperreports.export.SimpleTextExporterConfiguration; import net.sf.jasperreports.export.SimpleWriterExporterOutput; -import net.sf.jasperreports.export.SimpleXlsExporterConfiguration; +import net.sf.jasperreports.export.SimpleXlsReportConfiguration; import net.sf.jasperreports.export.SimpleXmlExporterOutput; /** @@ -724,6 +725,9 @@ public class ReportStarter implements ProcessCall, ClientProcess if (reportPathList.length == 1) { if (log.isLoggable(Level.INFO)) log.info( "ReportStarter.startProcess run report -"+jasperPrint.getName()); JRViewerProvider viewerLauncher = Service.locator().locate(JRViewerProvider.class).getService(); + if (!Util.isEmpty(processInfo.getReportType())) { + jasperPrint.setProperty("IDEMPIERE_REPORT_TYPE", processInfo.getReportType()); + } viewerLauncher.openViewer(jasperPrint, pi.getTitle()); } else { jasperPrintList.add(jasperPrint); @@ -785,17 +789,25 @@ public class ReportStarter implements ProcessCall, ClientProcess JRTextExporter export = new JRTextExporter(jasperContext); SimpleTextExporterConfiguration config = new SimpleTextExporterConfiguration(); export.setConfiguration(config); + export.setExporterOutput(new SimpleWriterExporterOutput(strm)); exporter = export; } else if (ext.equals("html") || ext.equals("htm")) { - HtmlExporter export = new HtmlExporter(jasperContext); - SimpleHtmlExporterConfiguration config = new SimpleHtmlExporterConfiguration(); - export.setConfiguration(config); - exporter = export; + HtmlExporter exporterHTML = new HtmlExporter(); + SimpleHtmlReportConfiguration htmlConfig = new SimpleHtmlReportConfiguration(); + htmlConfig.setEmbedImage(true); + htmlConfig.setAccessibleHtml(true); + exporterHTML.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporterHTML.setExporterOutput(new SimpleHtmlExporterOutput(file)); + exporterHTML.setConfiguration(htmlConfig); + exporter = exporterHTML; } else if (ext.equals("xls")) { - JRXlsExporter export = new JRXlsExporter(jasperContext); - SimpleXlsExporterConfiguration config = new SimpleXlsExporterConfiguration(); - export.setConfiguration(config); - exporter = export; + JRXlsExporter exporterXLS = new JRXlsExporter(jasperContext); + SimpleXlsReportConfiguration xlsConfig = new SimpleXlsReportConfiguration(); + xlsConfig.setOnePagePerSheet(false); + exporterXLS.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList)); + exporterXLS.setExporterOutput(new SimpleOutputStreamExporterOutput(strm)); + exporterXLS.setConfiguration(xlsConfig); + exporter = exporterXLS; } else { log.severe("FileInvalidExtension="+ext); strm.close(); 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 97022d89d0..1176be7068 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 @@ -43,6 +43,7 @@ import org.compiere.model.MScheduler; import org.compiere.model.MSchedulerLog; import org.compiere.model.MSchedulerPara; import org.compiere.model.MUser; +import org.compiere.print.MPrintFormat; import org.compiere.process.ProcessInfo; import org.compiere.process.ProcessInfoUtil; import org.compiere.process.ServerProcessCtl; @@ -91,16 +92,17 @@ public class Scheduler extends AdempiereServer */ protected void doWork () { - m_summary = new StringBuffer(get(getCtx(), AD_Scheduler_ID).toString()) + MScheduler scheduler = get(getCtx(), AD_Scheduler_ID); + m_summary = new StringBuffer(scheduler.toString()) .append(" - "); // Prepare a ctx for the report/process - BF [1966880] - MClient schedclient = MClient.get(getCtx(), get(getCtx(), AD_Scheduler_ID).getAD_Client_ID()); + MClient schedclient = MClient.get(getCtx(), scheduler.getAD_Client_ID()); Env.setContext(getCtx(), "#AD_Client_ID", schedclient.getAD_Client_ID()); Env.setContext(getCtx(), "#AD_Language", schedclient.getAD_Language()); - Env.setContext(getCtx(), "#AD_Org_ID", get(getCtx(), AD_Scheduler_ID).getAD_Org_ID()); - if (get(getCtx(), AD_Scheduler_ID).getAD_Org_ID() != 0) { - MOrgInfo schedorg = MOrgInfo.get(getCtx(), get(getCtx(), AD_Scheduler_ID).getAD_Org_ID(), null); + Env.setContext(getCtx(), "#AD_Org_ID", scheduler.getAD_Org_ID()); + if (scheduler.getAD_Org_ID() != 0) { + MOrgInfo schedorg = MOrgInfo.get(getCtx(), scheduler.getAD_Org_ID(), null); if (schedorg.getM_Warehouse_ID() > 0) Env.setContext(getCtx(), "#M_Warehouse_ID", schedorg.getM_Warehouse_ID()); } @@ -108,14 +110,14 @@ public class Scheduler extends AdempiereServer Env.setContext(getCtx(), "#SalesRep_ID", getAD_User_ID()); // TODO: It can be convenient to add AD_Scheduler.AD_Role_ID MUser scheduser = MUser.get(getCtx(), getAD_User_ID()); - MRole[] schedroles = scheduser.getRoles(get(getCtx(), AD_Scheduler_ID).getAD_Org_ID()); + MRole[] schedroles = scheduser.getRoles(scheduler.getAD_Org_ID()); if (schedroles != null && schedroles.length > 0) Env.setContext(getCtx(), "#AD_Role_ID", schedroles[0].getAD_Role_ID()); // first role, ordered by AD_Role_ID Timestamp ts = new Timestamp(System.currentTimeMillis()); SimpleDateFormat dateFormat4Timestamp = new SimpleDateFormat("yyyy-MM-dd"); Env.setContext(getCtx(), "#Date", dateFormat4Timestamp.format(ts)+" 00:00:00" ); // JDBC format - MProcess process = new MProcess(getCtx(), get(getCtx(), AD_Scheduler_ID).getAD_Process_ID(), null); + MProcess process = new MProcess(getCtx(), scheduler.getAD_Process_ID(), null); try { m_trx = Trx.get(Trx.createTrxName("Scheduler"), true); @@ -137,10 +139,10 @@ public class Scheduler extends AdempiereServer } // - int no = get(getCtx(), AD_Scheduler_ID).deleteLog(); + int no = scheduler.deleteLog(); m_summary.append(" Logs deleted=").append(no); // - MSchedulerLog pLog = new MSchedulerLog(get(getCtx(), AD_Scheduler_ID), m_summary.toString()); + MSchedulerLog pLog = new MSchedulerLog(scheduler, m_summary.toString()); pLog.setReference("#" + String.valueOf(p_runCount) + " - " + TimeUtil.formatElapsed(new Timestamp(p_startWork))); pLog.saveEx(); @@ -155,32 +157,52 @@ public class Scheduler extends AdempiereServer protected String runProcess(MProcess process) throws Exception { if (log.isLoggable(Level.INFO)) log.info(process.toString()); + MScheduler scheduler = get(getCtx(), AD_Scheduler_ID); boolean isReport = (process.isReport() || process.getAD_ReportView_ID() > 0 || process.getJasperReport() != null || process.getAD_PrintFormat_ID() > 0); - String schedulerName = Env.parseContext(getCtx(), -1, get(getCtx(), AD_Scheduler_ID).getName(), false, true); + String schedulerName = Env.parseContext(getCtx(), -1, scheduler.getName(), false, true); // Process (see also MWFActivity.performWork - int AD_Table_ID = get(getCtx(), AD_Scheduler_ID).getAD_Table_ID(); - int Record_ID = get(getCtx(), AD_Scheduler_ID).getRecord_ID(); + int AD_Table_ID = scheduler.getAD_Table_ID(); + int Record_ID = scheduler.getRecord_ID(); // MPInstance pInstance = new MPInstance(process, Record_ID); fillParameter(pInstance); // ProcessInfo pi = new ProcessInfo (process.getName(), process.getAD_Process_ID(), AD_Table_ID, Record_ID); pi.setAD_User_ID(getAD_User_ID()); - pi.setAD_Client_ID(get(getCtx(), AD_Scheduler_ID).getAD_Client_ID()); + pi.setAD_Client_ID(scheduler.getAD_Client_ID()); pi.setAD_PInstance_ID(pInstance.getAD_PInstance_ID()); pi.setAD_Process_UU(process.getAD_Process_UU()); pi.setIsBatch(true); pi.setPrintPreview(true); + pi.setReportType(scheduler.getReportOutputType()); + int AD_PrintFormat_ID = scheduler.getAD_PrintFormat_ID(); + if (AD_PrintFormat_ID > 0) + { + MPrintFormat format = new MPrintFormat(Env.getCtx(), AD_PrintFormat_ID, null); + pi.setSerializableObject(format); + } MUser from = new MUser(getCtx(), pi.getAD_User_ID(), null); pi.setTransactionName(m_trx != null ? m_trx.getTrxName() : null); + if (!Util.isEmpty(process.getJasperReport())) + { + pi.setExport(true); + if ("HTML".equals(pi.getReportType())) + pi.setExportFileExtension("html"); + else if ("CSV".equals(pi.getReportType())) + pi.setExportFileExtension("csv"); + else if ("XLS".equals(pi.getReportType())) + pi.setExportFileExtension("xls"); + else + pi.setExportFileExtension("pdf"); + } ServerProcessCtl.process(pi, m_trx); if ( pi.isError() ) // note, this call close the transaction, don't use m_trx below { // notify supervisor if error - int supervisor = get(getCtx(), AD_Scheduler_ID).getSupervisor_ID(); + int supervisor = scheduler.getSupervisor_ID(); if (supervisor > 0) { MUser user = new MUser(getCtx(), supervisor, null); @@ -192,20 +214,20 @@ public class Scheduler extends AdempiereServer if (email) { - MClient client = MClient.get(get(getCtx(), AD_Scheduler_ID).getCtx(), get(getCtx(), AD_Scheduler_ID).getAD_Client_ID()); + MClient client = MClient.get(scheduler.getCtx(), scheduler.getAD_Client_ID()); client.sendEMail(from, user, schedulerName, pi.getSummary() + " " + pi.getLogInfo(), null); } 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.setClientOrg(scheduler.getAD_Client_ID(), scheduler.getAD_Org_ID()); note.setTextMsg(schedulerName+"\n"+pi.getSummary()); note.setRecord(MPInstance.Table_ID, pi.getAD_PInstance_ID()); note.saveEx(); String log = pi.getLogInfo(true); if (log != null && log.trim().length() > 0) { MAttachment attachment = new MAttachment (getCtx(), MNote.Table_ID, note.getAD_Note_ID(), null); - attachment.setClientOrg(get(getCtx(), AD_Scheduler_ID).getAD_Client_ID(), get(getCtx(), AD_Scheduler_ID).getAD_Org_ID()); + attachment.setClientOrg(scheduler.getAD_Client_ID(), scheduler.getAD_Org_ID()); attachment.setTextMsg(schedulerName); attachment.addEntry("ProcessLog.html", log.getBytes("UTF-8")); attachment.saveEx(); @@ -215,12 +237,12 @@ public class Scheduler extends AdempiereServer } // always notify recipients - Integer[] userIDs = get(getCtx(), AD_Scheduler_ID).getRecipientAD_User_IDs(); + Integer[] userIDs = scheduler.getRecipientAD_User_IDs(); if (userIDs.length > 0) { ProcessInfoUtil.setLogFromDB(pi); List fileList = new ArrayList(); - if (isReport) { + if (isReport && pi.getPDFReport() != null) { fileList.add(pi.getPDFReport()); } if (pi.isExport() && pi.getExportFile() != null) @@ -239,10 +261,10 @@ public class Scheduler extends AdempiereServer if (isReport) AD_Message_ID = 884; // HARDCODED SchedulerResult MNote note = new MNote(getCtx(), AD_Message_ID, userIDs[i].intValue(), null); - note.setClientOrg(get(getCtx(), AD_Scheduler_ID).getAD_Client_ID(), get(getCtx(), AD_Scheduler_ID).getAD_Org_ID()); + note.setClientOrg(scheduler.getAD_Client_ID(), scheduler.getAD_Org_ID()); if (isReport) { note.setTextMsg(schedulerName); - note.setDescription(get(getCtx(), AD_Scheduler_ID).getDescription()); + note.setDescription(scheduler.getDescription()); note.setRecord(AD_Table_ID, Record_ID); } else { note.setTextMsg(schedulerName + "\n" + pi.getSummary()); @@ -253,7 +275,7 @@ public class Scheduler extends AdempiereServer if (fileList != null && !fileList.isEmpty()) { // Attachment attachment = new MAttachment (getCtx(), MNote.Table_ID, note.getAD_Note_ID(), null); - attachment.setClientOrg(get(getCtx(), AD_Scheduler_ID).getAD_Client_ID(), get(getCtx(), AD_Scheduler_ID).getAD_Org_ID()); + attachment.setClientOrg(scheduler.getAD_Client_ID(), scheduler.getAD_Org_ID()); attachment.setTextMsg(schedulerName); for (File entry : fileList) attachment.addEntry(entry); @@ -263,7 +285,7 @@ public class Scheduler extends AdempiereServer if (log != null && log.trim().length() > 0) { if (attachment == null) { attachment = new MAttachment (getCtx(), MNote.Table_ID, note.getAD_Note_ID(), null); - attachment.setClientOrg(get(getCtx(), AD_Scheduler_ID).getAD_Client_ID(), get(getCtx(), AD_Scheduler_ID).getAD_Org_ID()); + attachment.setClientOrg(scheduler.getAD_Client_ID(), scheduler.getAD_Org_ID()); attachment.setTextMsg(schedulerName); } attachment.addEntry("ProcessLog.html", log.getBytes("UTF-8")); @@ -276,11 +298,11 @@ public class Scheduler extends AdempiereServer if (email) { - MMailText mailTemplate = new MMailText(getCtx(), get(getCtx(), AD_Scheduler_ID).getR_MailText_ID(), null); + MMailText mailTemplate = new MMailText(getCtx(), scheduler.getR_MailText_ID(), null); String mailContent = ""; if (mailTemplate.is_new()){ - mailContent = get(getCtx(), AD_Scheduler_ID).getDescription(); + mailContent = scheduler.getDescription(); }else{ mailTemplate.setUser(user); mailTemplate.setLanguage(Env.getContext(getCtx(), "#AD_Language")); @@ -289,7 +311,7 @@ public class Scheduler extends AdempiereServer schedulerName = mailTemplate.getMailHeader(); } - MClient client = MClient.get(get(getCtx(), AD_Scheduler_ID).getCtx(), get(getCtx(), AD_Scheduler_ID).getAD_Client_ID()); + MClient client = MClient.get(scheduler.getCtx(), scheduler.getAD_Client_ID()); if (fileList != null && !fileList.isEmpty()) { client.sendEMailAttachments(from, user, schedulerName, mailContent, fileList); } else { @@ -312,13 +334,14 @@ public class Scheduler extends AdempiereServer } // runProcess protected int getAD_User_ID() { + MScheduler scheduler = get(getCtx(), AD_Scheduler_ID); int AD_User_ID; - if (get(getCtx(), AD_Scheduler_ID).getSupervisor_ID() > 0) - AD_User_ID = get(getCtx(), AD_Scheduler_ID).getSupervisor_ID(); - else if (get(getCtx(), AD_Scheduler_ID).getCreatedBy() > 0) - AD_User_ID = get(getCtx(), AD_Scheduler_ID).getCreatedBy(); - else if (get(getCtx(), AD_Scheduler_ID).getUpdatedBy() > 0) - AD_User_ID = get(getCtx(), AD_Scheduler_ID).getUpdatedBy(); + if (scheduler.getSupervisor_ID() > 0) + AD_User_ID = scheduler.getSupervisor_ID(); + else if (scheduler.getCreatedBy() > 0) + AD_User_ID = scheduler.getCreatedBy(); + else if (scheduler.getUpdatedBy() > 0) + AD_User_ID = scheduler.getUpdatedBy(); else AD_User_ID = 100; //fall back to SuperUser return AD_User_ID; diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AbstractProcessDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AbstractProcessDialog.java index 93a2455718..01bb7940a0 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AbstractProcessDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/AbstractProcessDialog.java @@ -66,7 +66,6 @@ import org.compiere.model.MPInstancePara; import org.compiere.model.MProcess; import org.compiere.model.MRole; import org.compiere.model.MSysConfig; -import org.compiere.model.MTable; import org.compiere.model.MUser; import org.compiere.model.Query; import org.compiere.model.X_AD_ReportView; @@ -103,7 +102,7 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI /** * */ - private static final long serialVersionUID = 2821858988648268894L; + private static final long serialVersionUID = 8232462327114180974L; private static final String ON_COMPLETE = "onComplete"; private static final String ON_STATUS_UPDATE = "onStatusUpdate"; @@ -258,9 +257,9 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI protected HtmlBasedComponent topParameterLayout; protected HtmlBasedComponent bottomParameterLayout; protected HtmlBasedComponent mainParameterLayout; - private WTableDirEditor fPrintFormat; + protected WTableDirEditor fPrintFormat; private WEditor fLanguageType; - private Listbox freportType; + protected Listbox freportType; private Checkbox chbIsSummary; protected Button bOK; protected Button bCancel; @@ -410,29 +409,37 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI } protected void reportOptionLayout(HtmlBasedComponent bottomParameterLayout) { - if (!isReport()) + if (!isReport() && !isJasperReport()) return;//if not a report not need show this pannel - + // option control Hlayout reportOptionLayout = new Hlayout(); reportOptionLayout.setSclass("report-option-container"); reportOptionLayout.setValign("middle"); bottomParameterLayout.appendChild(reportOptionLayout); - + + Label lreportType = new Label(Msg.translate(Env.getCtx(), "view.report")); + lreportType.setSclass("option-input-parameter view-report-label"); freportType = new Listbox(); freportType.setSclass("option-input-parameter view-report-list"); + reportOptionLayout.appendChild(lreportType); + reportOptionLayout.appendChild(freportType); + + if (isJasperReport()) + listReportTypeJasper(); + + if (!isReport()) + return; chbIsSummary = new Checkbox(); chbIsSummary.setSclass("option-input-parameter"); Label lPrintFormat = new Label(Msg.translate(Env.getCtx(), "AD_PrintFormat_ID")); lPrintFormat.setSclass("option-input-parameter print-format-label"); - Label lreportType = new Label(Msg.translate(Env.getCtx(), "view.report")); - lreportType.setSclass("option-input-parameter view-report-label"); Label lIsSummary = new Label(Msg.translate(Env.getCtx(), "Summary")); lIsSummary.setSclass("option-input-parameter"); - + MClient client = MClient.get(m_ctx); listPrintFormat(client); - + reportOptionLayout.appendChild(lPrintFormat); reportOptionLayout.appendChild(fPrintFormat.getComponent()); if (client.isMultiLingualDocument()){ @@ -443,8 +450,6 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI } fPrintFormat.getComponent().setSclass("option-input-parameter print-format-list"); fPrintFormat.getComponent().setPlaceholder(lPrintFormat.getValue()); - reportOptionLayout.appendChild(lreportType); - reportOptionLayout.appendChild(freportType); reportOptionLayout.appendChild(lIsSummary); reportOptionLayout.appendChild(chbIsSummary); } @@ -452,7 +457,11 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI protected boolean isReport () { MProcess pr = new MProcess(m_ctx, m_AD_Process_ID, null); return pr.isReport() && pr.getJasperReport() == null; - + } + + protected boolean isJasperReport () { + MProcess pr = new MProcess(m_ctx, m_AD_Process_ID, null); + return pr.isReport() && pr.getJasperReport() != null; } protected void savePrameterLayout(HtmlBasedComponent bottomParameterLayout) { @@ -565,26 +574,44 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI { log.log(Level.SEVERE, e.getLocalizedMessage()); } + + fillReportType(m_isCanExport); + setReportTypeAndPrintFormat(getLastRun()); + } + + private void listReportTypeJasper() + { + boolean m_isCanExport = MRole.getDefault().isCanExport(); + fillReportType(m_isCanExport); + + setReportTypeAndPrintFormat(getLastRun()); + } + + private MPInstance getLastRun() { + final String where = "AD_Process_ID = ? AND AD_User_ID = ? AND Name IS NULL "; + return new Query(Env.getCtx(), MPInstance.Table_Name, where, null) + .setOnlyActiveRecords(true).setClient_ID() + .setParameters(m_AD_Process_ID, Env.getContextAsInt(Env.getCtx(), "#AD_User_ID")) + .setOrderBy("Created DESC") + .first(); + } + + private void fillReportType(boolean m_isCanExport) { freportType.removeAllItems(); freportType.setMold("select"); + freportType.appendItem("", ""); + freportType.appendItem("PDF", "PDF"); freportType.appendItem("HTML", "HTML"); if (m_isCanExport) { - freportType.appendItem("PDF", "PDF"); freportType.appendItem("Excel", "XLS"); + freportType.appendItem("CSV", "CSV"); } freportType.setSelectedIndex(-1); - - String where = "AD_Process_ID = ? AND AD_User_ID = ? AND Name IS NULL "; - - MPInstance lastrun = MTable.get(Env.getCtx(), MPInstance.Table_Name).createQuery(where, null).setOnlyActiveRecords(true).setClient_ID() - .setParameters(m_AD_Process_ID, Env.getContextAsInt(Env.getCtx(), "#AD_User_ID")).setOrderBy("Created DESC").first(); - - setReportTypeAndPrintFormat(lastrun); } - + private void setReportTypeAndPrintFormat(MPInstance instance) { if (fPrintFormat != null && instance != null) { @@ -607,12 +634,15 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI } protected void saveReportOption (){ - if (!isReport()){ + if (!isReport() && !isJasperReport()){ return; } if(freportType.getSelectedItem() != null) { getProcessInfo().setReportType(freportType.getSelectedItem().getValue().toString()); } + if (!isReport()){ + return; + } if(fPrintFormat != null && fPrintFormat.getValue() != null) { MPrintFormat format = new MPrintFormat(m_ctx, (Integer) fPrintFormat.getValue(), null); if (format != null) { @@ -709,9 +739,14 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI } protected void saveReportOptionToInstance (MPInstance instance){ + if (!isReport() && !isJasperReport()) + return; + + if (freportType.getSelectedItem() != null) + instance.setReportType(freportType.getSelectedItem().getValue().toString()); + if (!isReport()) return; - Object value = fPrintFormat.getValue(); if (value == null){ instance.setAD_PrintFormat_ID(0); @@ -728,7 +763,6 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI } } - instance.setReportType(freportType.getSelectedItem().getValue().toString()); instance.setIsSummary(chbIsSummary.isSelected()); } @@ -874,6 +908,12 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI instance.setIsRunAsJob(true); instance.setIsProcessing(true); instance.setNotificationType(getNotificationType()); + instance.setReportType(m_pi.getReportType()); + instance.setIsSummary(m_pi.isSummary()); + instance.setAD_Language_ID(m_pi.getLanguageID()); + if (m_pi.getSerializableObject() != null && m_pi.getSerializableObject() instanceof MPrintFormat) { + instance.setAD_PrintFormat_ID(((MPrintFormat)m_pi.getSerializableObject()).getAD_PrintFormat_ID()); + } instance.saveEx(); m_pi.setAD_PInstance_ID(instance.getAD_PInstance_ID()); @@ -1154,15 +1194,27 @@ public abstract class AbstractProcessDialog extends Window implements IProcessUI int AD_User_ID = Env.getAD_User_ID(m_ctx); try { - m_pi.setSummary(""); // reset summary - MProcess process = new MProcess(m_ctx, m_pi.getAD_Process_ID(), null); + if (process.isReport() && process.getJasperReport() != null) { + if (!Util.isEmpty(process.getJasperReport())) + { + m_pi.setExport(true); + if ("HTML".equals(m_pi.getReportType())) + m_pi.setExportFileExtension("html"); + else if ("CSV".equals(m_pi.getReportType())) + m_pi.setExportFileExtension("csv"); + else if ("XLS".equals(m_pi.getReportType())) + m_pi.setExportFileExtension("xls"); + else + m_pi.setExportFileExtension("pdf"); + } + } ServerProcessCtl.process(m_pi, null); ProcessInfoUtil.setLogFromDB(m_pi); if (!m_pi.isError()) { boolean isReport = (process.isReport() || process.getAD_ReportView_ID() > 0 || process.getJasperReport() != null || process.getAD_PrintFormat_ID() > 0); - if (isReport) + if (isReport && m_pi.getPDFReport() != null) { download(m_pi.getPDFReport()); } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessModalDialog.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessModalDialog.java index 11c7d1ad18..ebe9fede5a 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessModalDialog.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/apps/ProcessModalDialog.java @@ -23,6 +23,7 @@ import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.component.Window; import org.adempiere.webui.event.DialogEvents; import org.adempiere.webui.util.ZKUpdateUtil; +import org.compiere.print.MPrintFormat; import org.compiere.process.ProcessInfo; import org.compiere.util.CLogger; import org.compiere.util.Env; @@ -221,6 +222,15 @@ public class ProcessModalDialog extends AbstractProcessDialog implements EventLi Events.echoEvent(ON_OK_ECHO, this, null); return; } + if(fPrintFormat != null && fPrintFormat.getValue() != null) { + MPrintFormat format = new MPrintFormat(Env.getCtx(), (Integer) fPrintFormat.getValue(), null); + if (format != null) { + getProcessInfo().setSerializableObject(format); + } + } + if(freportType != null && freportType.getSelectedItem() != null) { + getProcessInfo().setReportType(freportType.getSelectedItem().getValue().toString()); + } startProcess(); } 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 4f5fbc55b8..be67b769df 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 @@ -134,8 +134,11 @@ public class ZkJRViewer extends Window implements EventListener, ITabOnCl private void init() { final boolean isCanExport=MRole.getDefault().isCanExport(); - defaultType = MSysConfig.getValue(MSysConfig.ZK_REPORT_JASPER_OUTPUT_TYPE, "PDF", - Env.getAD_Client_ID(Env.getCtx()), Env.getAD_Org_ID(Env.getCtx()));//It gets default Jasper output type + defaultType = jasperPrint.getProperty("IDEMPIERE_REPORT_TYPE"); + if (Util.isEmpty(defaultType)) { + defaultType = MSysConfig.getValue(MSysConfig.ZK_REPORT_JASPER_OUTPUT_TYPE, "PDF", + Env.getAD_Client_ID(Env.getCtx()), Env.getAD_Org_ID(Env.getCtx()));//It gets default Jasper output type + } Borderlayout layout = new Borderlayout(); layout.setStyle("position: absolute; height: 99%; width: 99%"); 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 4bfd60e9d6..c7368e2ca8 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 @@ -274,11 +274,12 @@ public class ZkReportViewer extends Window implements EventListener, ITab previewType.setMold("select"); previewType.appendItem("HTML", "HTML"); + previewType.appendItem("PDF", "PDF"); if ( m_isCanExport ) { - previewType.appendItem("PDF", "PDF"); previewType.appendItem("Excel", "XLS"); + previewType.appendItem("CSV", "CSV"); } toolBar.appendChild(previewType); @@ -290,10 +291,12 @@ public class ZkReportViewer extends Window implements EventListener, ITab if (m_reportEngine.getReportType() != null) { - if (m_reportEngine.getReportType().equals("PDF") && m_isCanExport) + if (m_reportEngine.getReportType().equals("PDF")) pTypeIndex = 1; else if (m_reportEngine.getReportType().equals("XLS") && m_isCanExport) pTypeIndex = 2; + else if (m_reportEngine.getReportType().equals("CSV") && m_isCanExport) + pTypeIndex = 3; } else { @@ -305,10 +308,12 @@ public class ZkReportViewer extends Window implements EventListener, ITab if ("HTML".equals(type)) { pTypeIndex = 0; - } else if ("PDF".equals(type) && m_isCanExport) { + } else if ("PDF".equals(type)) { pTypeIndex = 1; } else if ("XLS".equals(type) && m_isCanExport) { pTypeIndex = 2; + } else if ("CSV".equals(type) && m_isCanExport) { + pTypeIndex = 3; } } @@ -651,7 +656,9 @@ public class ZkReportViewer extends Window implements EventListener, ITab future = Adempiere.getThreadPoolExecutor().submit(new DesktopRunnable(new HTMLRendererRunnable(this),getDesktop())); } else if ("XLS".equals(previewType.getSelectedItem().getValue())) { future = Adempiere.getThreadPoolExecutor().submit(new DesktopRunnable(new XLSRendererRunnable(this),getDesktop())); - } + } else if ("CSV".equals(previewType.getSelectedItem().getValue())) { + future = Adempiere.getThreadPoolExecutor().submit(new DesktopRunnable(new CSVRendererRunnable(this),getDesktop())); + } } private void onPreviewReport() { @@ -1674,4 +1681,47 @@ public class ZkReportViewer extends Window implements EventListener, ITab } } + + static class CSVRendererRunnable extends ContextRunnable implements IServerPushCallback { + + private ZkReportViewer viewer; + + public CSVRendererRunnable(ZkReportViewer viewer) { + super(); + this.viewer = viewer; + } + + @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); + } catch (Exception e) { + if (e instanceof RuntimeException) + throw (RuntimeException)e; + else + throw new RuntimeException(e); + } finally { + Desktop desktop = AEnv.getDesktop(); + if (desktop != null && desktop.isAlive()) { + new ServerPushTemplate(desktop).executeAsync(this); + } + } + } + + @Override + public void updateUI() { + viewer.labelDrill.setVisible(false); + viewer.comboDrill.setVisible(false); + viewer.onPreviewReport(); + } + + } } diff --git a/org.adempiere.ui/src/org/compiere/apps/AbstractProcessCtl.java b/org.adempiere.ui/src/org/compiere/apps/AbstractProcessCtl.java index 1646848d30..0f2c91f501 100644 --- a/org.adempiere.ui/src/org/compiere/apps/AbstractProcessCtl.java +++ b/org.adempiere.ui/src/org/compiere/apps/AbstractProcessCtl.java @@ -272,6 +272,8 @@ public abstract class AbstractProcessCtl implements Runnable m_pi.setClassName(ProcessUtil.JASPER_STARTER_CLASS); startProcess(); MPInstance pinstance = new MPInstance(Env.getCtx(), m_pi.getAD_PInstance_ID(), null); + if (m_pi.getReportType() != null) + pinstance.setReportType(m_pi.getReportType()); String errmsg = pinstance.getErrorMsg(); if (Util.isEmpty(errmsg, true)) errmsg = "Rows=" + String.valueOf(m_pi.getRowCount()); From cf0d10a3e6058b5391025ace40fd7f3e035af649 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Wed, 22 May 2019 11:16:38 +0200 Subject: [PATCH 2/5] IDEMPIERE-3974 Allow processUI to be access from rule scripts / based on patch from Diego Ruiz --- org.adempiere.ui/src/org/compiere/apps/AbstractProcessCtl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/org.adempiere.ui/src/org/compiere/apps/AbstractProcessCtl.java b/org.adempiere.ui/src/org/compiere/apps/AbstractProcessCtl.java index 0f2c91f501..c0a48f59ad 100644 --- a/org.adempiere.ui/src/org/compiere/apps/AbstractProcessCtl.java +++ b/org.adempiere.ui/src/org/compiere/apps/AbstractProcessCtl.java @@ -464,6 +464,7 @@ public abstract class AbstractProcessCtl implements Runnable if (!started && (!m_IsServerProcess || clientOnly )) { if (m_pi.getClassName().toLowerCase().startsWith(MRule.SCRIPT_PREFIX)) { + m_pi.setProcessUI(m_processUI); return ProcessUtil.startScriptProcess(Env.getCtx(), m_pi, m_trx); } else { return ProcessUtil.startJavaProcess(Env.getCtx(), m_pi, m_trx, true, m_processUI); From a9fbf53acf6f8775488de301295212064994f70b Mon Sep 17 00:00:00 2001 From: Deepak Pansheriya Date: Fri, 17 May 2019 19:18:40 +0530 Subject: [PATCH 3/5] IDEMPIERE-3975: Virtual column can't be used for search, empty result returned --- org.adempiere.base/src/org/compiere/model/MQuery.java | 2 +- .../src/org/adempiere/webui/window/FindWindow.java | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/org.adempiere.base/src/org/compiere/model/MQuery.java b/org.adempiere.base/src/org/compiere/model/MQuery.java index 9b7a03dbd6..d696ede3e8 100644 --- a/org.adempiere.base/src/org/compiere/model/MQuery.java +++ b/org.adempiere.base/src/org/compiere/model/MQuery.java @@ -1126,7 +1126,7 @@ class Restriction implements Serializable String colSQL = col.getColumnSQL(true); if (colSQL != null && colSQL.contains("@")) colSQL = Env.parseContext(Env.getCtx(), -1, colSQL, false, true); - if (ColumnName.equals(colSQL)) { + if (colSQL != null && ColumnName.equals(colSQL.trim())) { virtualColumn = true; break; } diff --git a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java index 6800b3ce09..0e76450a06 100644 --- a/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java +++ b/org.adempiere.ui.zk/WEB-INF/src/org/adempiere/webui/window/FindWindow.java @@ -1699,7 +1699,7 @@ public class FindWindow extends Window implements EventListener, ValueCha if (!(parsedValue instanceof Integer)) { continue; } - m_query.addRestriction(getSubCategoryWhereClause(((Integer) parsedValue).intValue()), and, openBrackets); + m_query.addRestriction(getSubCategoryWhereClause(field, ((Integer) parsedValue).intValue()), and, openBrackets); } else m_query.addRestriction(ColumnSQL, Operator, parsedValue, @@ -1865,7 +1865,7 @@ public class FindWindow extends Window implements EventListener, ValueCha m_query.addRestriction(ColumnSQL.toString(), MQuery.LIKE, value, ColumnName, wed.getDisplay()); appendCode(code, ColumnName, MQuery.LIKE, value.toString(), "", "AND", "", ""); } else if (isProductCategoryField && value instanceof Integer) { - m_query.addRestriction(getSubCategoryWhereClause(((Integer) value).intValue())); + m_query.addRestriction(getSubCategoryWhereClause(field, ((Integer) value).intValue())); appendCode(code, ColumnName, MQuery.EQUAL, value.toString(), "", "AND", "", ""); } else { String oper = MQuery.EQUAL; @@ -2319,13 +2319,14 @@ public class FindWindow extends Window implements EventListener, ValueCha /** * Returns a sql where string with the given category id and all of its subcategory ids. * It is used as restriction in MQuery. + * @param field * @param productCategoryId * @return **/ - private String getSubCategoryWhereClause(int productCategoryId) { + private String getSubCategoryWhereClause(GridField field, int productCategoryId) { //if a node with this id is found later in the search we have a loop in the tree int subTreeRootParentId = 0; - StringBuilder retString = new StringBuilder(" M_Product_Category_ID IN ("); + StringBuilder retString = new StringBuilder(field.getColumnSQL(false)).append(" IN ("); String sql = "SELECT M_Product_Category_ID, M_Product_Category_Parent_ID FROM M_Product_Category WHERE AD_Client_ID=? AND IsActive='Y'"; final Vector categories = new Vector(100); PreparedStatement pstmt = null; From f772f37e4db37e842b8cc9474a6fdce5a4f280b2 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Wed, 22 May 2019 14:27:24 +0200 Subject: [PATCH 4/5] IDEMPIERE-3976 Scheduler in System cannot be assigned to a valid Supervisor (FHCA-963) --- migration/i6.2/oracle/201905221426_IDEMPIERE-3976.sql | 11 +++++++++++ .../i6.2/postgresql/201905221426_IDEMPIERE-3976.sql | 8 ++++++++ 2 files changed, 19 insertions(+) create mode 100644 migration/i6.2/oracle/201905221426_IDEMPIERE-3976.sql create mode 100644 migration/i6.2/postgresql/201905221426_IDEMPIERE-3976.sql diff --git a/migration/i6.2/oracle/201905221426_IDEMPIERE-3976.sql b/migration/i6.2/oracle/201905221426_IDEMPIERE-3976.sql new file mode 100644 index 0000000000..659663b27d --- /dev/null +++ b/migration/i6.2/oracle/201905221426_IDEMPIERE-3976.sql @@ -0,0 +1,11 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- IDEMPIERE-3976 Scheduler in System cannot be assigned to a valid Supervisor (FHCA-963) +-- May 22, 2019, 2:25:16 PM CEST +UPDATE AD_Ref_Table SET WhereClause='(AD_User.AD_Client_ID=0 AND (AD_User.AD_User_ID=0 OR @#AD_Client_ID@=0)) OR EXISTS (SELECT * FROM C_BPartner bp WHERE AD_User.C_BPartner_ID=bp.C_BPartner_ID AND (bp.IsEmployee=''Y'' OR bp.IsSalesRep=''Y''))',Updated=TO_DATE('2019-05-22 14:25:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Reference_ID=316 +; + +SELECT register_migration_script('201905221426_IDEMPIERE-3976.sql') FROM dual +; + diff --git a/migration/i6.2/postgresql/201905221426_IDEMPIERE-3976.sql b/migration/i6.2/postgresql/201905221426_IDEMPIERE-3976.sql new file mode 100644 index 0000000000..18d499e700 --- /dev/null +++ b/migration/i6.2/postgresql/201905221426_IDEMPIERE-3976.sql @@ -0,0 +1,8 @@ +-- IDEMPIERE-3976 Scheduler in System cannot be assigned to a valid Supervisor (FHCA-963) +-- May 22, 2019, 2:25:16 PM CEST +UPDATE AD_Ref_Table SET WhereClause='(AD_User.AD_Client_ID=0 AND (AD_User.AD_User_ID=0 OR @#AD_Client_ID@=0)) OR EXISTS (SELECT * FROM C_BPartner bp WHERE AD_User.C_BPartner_ID=bp.C_BPartner_ID AND (bp.IsEmployee=''Y'' OR bp.IsSalesRep=''Y''))',Updated=TO_TIMESTAMP('2019-05-22 14:25:16','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Reference_ID=316 +; + +SELECT register_migration_script('201905221426_IDEMPIERE-3976.sql') FROM dual +; + From 41f6590608794a68d3fcd0d852dea2730005abd1 Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Sat, 25 May 2019 13:32:38 +0200 Subject: [PATCH 5/5] IDEMPIERE-3977 Allow context variables on subject and message when processing alerts (FHCA-967) --- .../oracle/201905241859_IDEMPIERE-3977.sql | 19 ++++++++++ .../201905241859_IDEMPIERE-3977.sql | 12 +++++++ .../src/org/compiere/util/Env.java | 4 +-- .../org/compiere/server/AlertProcessor.java | 35 ++++++++++++------- 4 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 migration/i6.2/oracle/201905241859_IDEMPIERE-3977.sql create mode 100644 migration/i6.2/postgresql/201905241859_IDEMPIERE-3977.sql diff --git a/migration/i6.2/oracle/201905241859_IDEMPIERE-3977.sql b/migration/i6.2/oracle/201905241859_IDEMPIERE-3977.sql new file mode 100644 index 0000000000..1b16836ecf --- /dev/null +++ b/migration/i6.2/oracle/201905241859_IDEMPIERE-3977.sql @@ -0,0 +1,19 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- IDEMPIERE-3977 Allow context variables on subject and message when processing alerts (FHCA-967) +-- May 24, 2019, 6:58:25 PM CEST +UPDATE AD_Column SET FieldLength=255,Updated=TO_DATE('2019-05-24 18:58:25','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=9077 +; + +-- May 24, 2019, 6:58:27 PM CEST +-- ALTER TABLE AD_Alert MODIFY AlertSubject NVARCHAR2(255); +ALTER TABLE AD_Alert ADD Tmp_AlertSubject NVARCHAR2(255); +UPDATE AD_Alert SET Tmp_AlertSubject = AlertSubject; +ALTER TABLE AD_Alert MODIFY Tmp_AlertSubject NVARCHAR2(255) NOT NULL; +ALTER TABLE AD_Alert DROP COLUMN AlertSubject; +ALTER TABLE AD_Alert RENAME COLUMN Tmp_AlertSubject TO AlertSubject; + +SELECT register_migration_script('201905241859_IDEMPIERE-3977.sql') FROM dual +; + diff --git a/migration/i6.2/postgresql/201905241859_IDEMPIERE-3977.sql b/migration/i6.2/postgresql/201905241859_IDEMPIERE-3977.sql new file mode 100644 index 0000000000..1a66e4af01 --- /dev/null +++ b/migration/i6.2/postgresql/201905241859_IDEMPIERE-3977.sql @@ -0,0 +1,12 @@ +-- IDEMPIERE-3977 Allow context variables on subject and message when processing alerts (FHCA-967) +-- May 24, 2019, 6:58:25 PM CEST +UPDATE AD_Column SET FieldLength=255,Updated=TO_TIMESTAMP('2019-05-24 18:58:25','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=9077 +; + +-- May 24, 2019, 6:58:27 PM CEST +INSERT INTO t_alter_column values('ad_alert','AlertSubject','VARCHAR(255)',null,null) +; + +SELECT register_migration_script('201905241859_IDEMPIERE-3977.sql') FROM dual +; + diff --git a/org.adempiere.base/src/org/compiere/util/Env.java b/org.adempiere.base/src/org/compiere/util/Env.java index 9670df6fa8..e065e3ae55 100644 --- a/org.adempiere.base/src/org/compiere/util/Env.java +++ b/org.adempiere.base/src/org/compiere/util/Env.java @@ -1666,7 +1666,7 @@ public final class Env String foreignTable = colToken.getReferenceTableName(); if (v != null) { if (format != null && format.length() > 0) { - if (v instanceof Integer && (Integer) v > 0 && !Util.isEmpty(foreignTable)) { + if (v instanceof Integer && (Integer) v >= 0 && (!Util.isEmpty(foreignTable) || token.equalsIgnoreCase(po.get_TableName()+"_ID"))){ int tblIndex = format.indexOf("."); String tableName = null; if (tblIndex > 0) @@ -1674,7 +1674,7 @@ public final class Env else tableName = foreignTable; MTable table = MTable.get(ctx, tableName); - if (table != null && tableName.equalsIgnoreCase(foreignTable)) { + if (table != null && (tableName.equalsIgnoreCase(foreignTable) || tableName.equalsIgnoreCase(po.get_TableName()))) { String columnName = tblIndex > 0 ? format.substring(tblIndex + 1) : format; MColumn column = table.getColumn(columnName); if (column != null) { diff --git a/org.adempiere.server/src/main/server/org/compiere/server/AlertProcessor.java b/org.adempiere.server/src/main/server/org/compiere/server/AlertProcessor.java index f10b8979f0..0bf3b09930 100644 --- a/org.adempiere.server/src/main/server/org/compiere/server/AlertProcessor.java +++ b/org.adempiere.server/src/main/server/org/compiere/server/AlertProcessor.java @@ -36,6 +36,7 @@ import org.compiere.model.MAttachment; import org.compiere.model.MClient; import org.compiere.model.MNote; import org.compiere.model.MSysConfig; +import org.compiere.model.MSystem; import org.compiere.model.MUser; import org.compiere.util.CLogger; import org.compiere.util.DB; @@ -132,8 +133,12 @@ public class AlertProcessor extends AdempiereServer return false; if (log.isLoggable(Level.INFO)) log.info("" + alert); - StringBuffer message = new StringBuffer(alert.getAlertMessage()) - .append(Env.NL); + MSystem system = MSystem.get(Env.getCtx()); + MClient client = MClient.get(Env.getCtx()); + // parse variables from Client, then from System + String alertMessage = Env.parseVariable(alert.getAlertMessage(), client, null, true); + alertMessage = Env.parseVariable(alertMessage, system, null, true); + StringBuffer message = new StringBuffer(alertMessage).append(Env.NL); // boolean valid = true; boolean processed = false; @@ -228,12 +233,15 @@ public class AlertProcessor extends AdempiereServer // // Report footer - Date Generated DateFormat df = DisplayType.getDateFormat(DisplayType.DateTime, language); - message.append("\n\n"); + message.append(Env.NL).append(Env.NL); message.append(Msg.translate(language, "Date")).append(" : ") .append(df.format(new Timestamp(System.currentTimeMillis()))); Collection users = alert.getRecipientUsers(); - int countMail = notifyUsers(users, alert.getAlertSubject(), message.toString(), attachments); + // parse variables from Client, then from System + String alertSubject = Env.parseVariable(alert.getAlertSubject(), client, null, true); + alertSubject = Env.parseVariable(alertSubject, system, null, true); + int countMail = notifyUsers(users, alertSubject, message.toString(), attachments); // IDEMPIERE-2864 for(File attachment : attachments) @@ -260,7 +268,8 @@ public class AlertProcessor extends AdempiereServer for (int user_id : users) { MUser user = MUser.get(getCtx(), user_id); if (user.isNotificationEMail()) { - if (m_client.sendEMailAttachments (user_id, subject, message, attachments)) + String messageHTML = message.replaceAll(Env.NL, "
"); + if (m_client.sendEMailAttachments (user_id, subject, messageHTML, attachments, true)) { countMail++; } @@ -276,15 +285,17 @@ public class AlertProcessor extends AdempiereServer MNote note = new MNote(getCtx(), AD_Message_ID, user_id, trx.getTrxName()); note.setClientOrg(m_model.getAD_Client_ID(), m_model.getAD_Org_ID()); note.setTextMsg(message); + note.setDescription(subject); note.saveEx(); - // Attachment - MAttachment attachment = new MAttachment (getCtx(), MNote.Table_ID, note.getAD_Note_ID(), trx.getTrxName()); - attachment.setClientOrg(m_model.getAD_Client_ID(), m_model.getAD_Org_ID()); - for (File f : attachments) { - attachment.addEntry(f); + if (attachments.size() > 0) { + // Attachment + MAttachment attachment = new MAttachment (getCtx(), MNote.Table_ID, note.getAD_Note_ID(), trx.getTrxName()); + attachment.setClientOrg(m_model.getAD_Client_ID(), m_model.getAD_Org_ID()); + for (File f : attachments) { + attachment.addEntry(f); + } + attachment.saveEx(); } - attachment.setTextMsg(message); - attachment.saveEx(); countMail++; trx.commit(); } catch (Throwable e) {