1003856 IDEMPIERE-1951 Integrate commit from hengsin -> Run report as a background job. Peer review implementation from Elaine.

This commit is contained in:
Carlos Ruiz 2014-05-14 14:44:06 -05:00
parent e247dac3a8
commit c73000c38b
17 changed files with 1880 additions and 799 deletions

View File

@ -0,0 +1,184 @@
SET SQLBLANKLINES ON
SET DEFINE OFF
-- Mar 28, 2014 6:34:26 PM SGT
-- Ticket #1003856: Run report as a background job
INSERT INTO AD_Element (ColumnName,AD_Element_ID,Name,PrintName,AD_Element_UU,Created,Updated,AD_Org_ID,CreatedBy,UpdatedBy,IsActive,AD_Client_ID,EntityType) VALUES ('IsRunAsJob',202694,'Run as Job','Run as Job','c52c9e5a-da3e-401d-8f52-e58f557a56f2',TO_DATE('2014-03-28 18:34:24','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2014-03-28 18:34:24','YYYY-MM-DD HH24:MI:SS'),0,100,100,'Y',0,'D')
;
-- Mar 28, 2014 6:35:05 PM SGT
INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,Version,AD_Column_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,DefaultValue,Name,IsAllowCopy,Updated,CreatedBy,AD_Org_ID,IsActive,Created,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,AD_Client_ID,IsEncrypted,IsSecure,FKConstraintType,AD_Element_ID,AD_Reference_ID,AD_Table_ID,EntityType) VALUES (0,'N',0,211199,'Y','N','N',0,'N',1,'N','N','N','Y','e67be641-2f1b-4c6b-9c8a-a6788940a686','Y','IsRunAsJob','N','Run as Job','Y',TO_DATE('2014-03-28 18:35:03','YYYY-MM-DD HH24:MI:SS'),100,0,'Y',TO_DATE('2014-03-28 18:35:03','YYYY-MM-DD HH24:MI:SS'),100,'N','N',0,'N','N','N',202694,20,282,'D')
;
-- Mar 28, 2014 6:38:03 PM SGT
INSERT INTO AD_Element (ColumnName,AD_Element_ID,Name,PrintName,AD_Element_UU,Created,Updated,AD_Org_ID,CreatedBy,UpdatedBy,IsActive,AD_Client_ID,EntityType) VALUES ('IsJobProcessing',202695,'Job Processing','Job Processing','54265662-ebe2-4521-ba7e-8a9f9a96bcab',TO_DATE('2014-03-28 18:38:02','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2014-03-28 18:38:02','YYYY-MM-DD HH24:MI:SS'),0,100,100,'Y',0,'D')
;
-- Mar 28, 2014 6:38:22 PM SGT
INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,Version,AD_Column_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,DefaultValue,Name,IsAllowCopy,Updated,CreatedBy,AD_Org_ID,IsActive,Created,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,AD_Client_ID,IsEncrypted,IsSecure,FKConstraintType,AD_Element_ID,AD_Reference_ID,AD_Table_ID,EntityType) VALUES (0,'N',0,211200,'Y','N','N',0,'N',1,'N','N','N','Y','922b7724-599a-49c8-a053-0f8f4b8e2156','Y','IsJobProcessing','N','Job Processing','Y',TO_DATE('2014-03-28 18:38:21','YYYY-MM-DD HH24:MI:SS'),100,0,'Y',TO_DATE('2014-03-28 18:38:21','YYYY-MM-DD HH24:MI:SS'),100,'N','N',0,'N','N','N',202695,20,282,'D')
;
-- Mar 28, 2014 6:38:42 PM SGT
INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,Version,AD_Column_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,Description,Help,Name,IsAllowCopy,Updated,CreatedBy,AD_Org_ID,IsActive,Created,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,AD_Client_ID,IsEncrypted,IsSecure,AD_Element_ID,AD_Reference_ID,AD_Reference_Value_ID,AD_Table_ID,EntityType) VALUES (0,'N',0,211201,'N','N','N',0,'N',2,'N','N','N','Y','5c07ac2d-8342-4e86-ae06-5109f872a16b','Y','NotificationType','Type of Notifications','Emails or Notification sent out for Request Updates, etc.','Notification Type','Y',TO_DATE('2014-03-28 18:38:41','YYYY-MM-DD HH24:MI:SS'),100,0,'Y',TO_DATE('2014-03-28 18:38:41','YYYY-MM-DD HH24:MI:SS'),100,'N','N',0,'N','N',2755,17,200026,282,'D')
;
-- Mar 28, 2014 6:43:27 PM SGT
ALTER TABLE AD_PInstance ADD IsRunAsJob CHAR(1) DEFAULT 'N'
;
-- Mar 28, 2014 6:43:44 PM SGT
ALTER TABLE AD_PInstance ADD IsJobProcessing CHAR(1) DEFAULT 'N'
;
-- Mar 28, 2014 6:43:51 PM SGT
ALTER TABLE AD_PInstance ADD NotificationType VARCHAR2(2) DEFAULT NULL
;
-- Mar 28, 2014 6:44:35 PM SGT
INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,EntityType,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,Created,CreatedBy,Updated,IsActive,IsDisplayedGrid,AD_Client_ID,ColumnSpan,AD_Column_ID) VALUES ('N',663,36,'N','N',110,'Y',202844,'N','D','AD_PInstance_UU','3540b3cc-efe6-4509-bafc-a15c59c9d7f8','N','N',100,0,TO_DATE('2014-03-28 18:44:34','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2014-03-28 18:44:34','YYYY-MM-DD HH24:MI:SS'),'Y','N',0,2,60451)
;
-- Mar 28, 2014 6:44:36 PM SGT
INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,EntityType,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,Created,CreatedBy,Updated,IsActive,XPosition,AD_Client_ID,ColumnSpan,AD_Column_ID) VALUES ('N',663,1,'N','N',120,'Y',202845,'N','D','Run as Job','72ecc44d-a61b-44b9-a94a-14bd270dbf22','Y','N',100,0,TO_DATE('2014-03-28 18:44:35','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2014-03-28 18:44:35','YYYY-MM-DD HH24:MI:SS'),'Y',2,0,2,211199)
;
-- Mar 28, 2014 6:44:37 PM SGT
INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,EntityType,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,Created,CreatedBy,Updated,IsActive,XPosition,AD_Client_ID,ColumnSpan,AD_Column_ID) VALUES ('N',663,1,'N','N',130,'Y',202846,'N','D','Job Processing','96118891-6592-4f41-8ba0-05057e17d60e','Y','N',100,0,TO_DATE('2014-03-28 18:44:36','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2014-03-28 18:44:36','YYYY-MM-DD HH24:MI:SS'),'Y',2,0,2,211200)
;
-- Mar 28, 2014 6:44:38 PM SGT
INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,EntityType,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,Created,CreatedBy,Updated,IsActive,AD_Client_ID,ColumnSpan,AD_Column_ID) VALUES ('N',663,2,'N','N',140,'Y',202847,'N','Emails or Notification sent out for Request Updates, etc.','D','Type of Notifications','Notification Type','d76699c8-2abe-4f62-9e10-6e10fd5dba20','Y','N',100,0,TO_DATE('2014-03-28 18:44:37','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2014-03-28 18:44:37','YYYY-MM-DD HH24:MI:SS'),'Y',0,2,211201)
;
-- Mar 28, 2014 6:45:04 PM SGT
UPDATE AD_Field SET SeqNo=0,IsDisplayed='N' WHERE AD_Field_ID=202844
;
-- Mar 28, 2014 6:45:04 PM SGT
UPDATE AD_Field SET SeqNo=110,IsDisplayed='Y' WHERE AD_Field_ID=202845
;
-- Mar 28, 2014 6:45:04 PM SGT
UPDATE AD_Field SET SeqNo=120,IsDisplayed='Y' WHERE AD_Field_ID=202847
;
-- Mar 28, 2014 6:45:11 PM SGT
UPDATE AD_Field SET SeqNoGrid=110,IsDisplayedGrid='Y' WHERE AD_Field_ID=202845
;
-- Mar 28, 2014 6:45:11 PM SGT
UPDATE AD_Field SET SeqNoGrid=120,IsDisplayedGrid='Y' WHERE AD_Field_ID=202847
;
-- Mar 28, 2014 6:45:11 PM SGT
UPDATE AD_Field SET SeqNoGrid=130,IsDisplayedGrid='Y' WHERE AD_Field_ID=202846
;
-- Mar 28, 2014 6:46:01 PM SGT
INSERT INTO AD_FieldGroup (FieldGroupType,EntityType,IsCollapsedByDefault,Name,AD_FieldGroup_UU,AD_FieldGroup_ID,Created,CreatedBy,Updated,AD_Org_ID,UpdatedBy,IsActive,AD_Client_ID) VALUES ('C','D','N','Background Job','3be13370-89e4-42b3-8220-370ce497466a',200018,TO_DATE('2014-03-28 18:46:00','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2014-03-28 18:46:00','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',0)
;
-- Mar 28, 2014 6:46:18 PM SGT
UPDATE AD_Field SET AD_FieldGroup_ID=200018,Updated=TO_DATE('2014-03-28 18:46:18','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202847
;
-- Mar 28, 2014 6:46:22 PM SGT
UPDATE AD_Field SET AD_FieldGroup_ID=200018,Updated=TO_DATE('2014-03-28 18:46:22','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202845
;
-- Mar 28, 2014 6:46:28 PM SGT
UPDATE AD_Field SET AD_FieldGroup_ID=200018,Updated=TO_DATE('2014-03-28 18:46:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202846
;
-- Mar 28, 2014 6:46:44 PM SGT
UPDATE AD_Field SET IsSameLine='Y', XPosition=4,Updated=TO_DATE('2014-03-28 18:46:44','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202847
;
-- Mar 28, 2014 6:49:07 PM SGT
INSERT INTO AD_SysConfig (AD_SysConfig_ID,ConfigurationLevel,Value,AD_SysConfig_UU,Updated,Created,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name,AD_Client_ID,EntityType) VALUES (200047,'C','Y','feb88039-2fe8-47e5-a7be-c3a634674f0b',TO_DATE('2014-03-28 18:49:06','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2014-03-28 18:49:06','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',100,'BACKGROUND_JOB_ALLOWED',0,'D')
;
-- Mar 28, 2014 6:49:31 PM SGT
INSERT INTO AD_SysConfig (AD_SysConfig_ID,ConfigurationLevel,Value,AD_SysConfig_UU,Updated,Created,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name,AD_Client_ID,EntityType) VALUES (200048,'C','N','f2fd6f9b-d8bb-4ade-9857-78ba68951776',TO_DATE('2014-03-28 18:49:30','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2014-03-28 18:49:30','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',100,'BACKGROUND_JOB_BY_DEFAULT',0,'D')
;
-- Mar 28, 2014 6:50:36 PM SGT
INSERT INTO AD_SysConfig (AD_SysConfig_ID,ConfigurationLevel,Value,AD_SysConfig_UU,Updated,Created,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name,AD_Client_ID,EntityType) VALUES (200049,'S','20','0a24332e-a83a-465a-903f-6f3d7caea306',TO_DATE('2014-03-28 18:50:35','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2014-03-28 18:50:35','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',100,'BACKGROUND_JOB_MAX_IN_SYSTEM',0,'D')
;
-- Mar 28, 2014 6:51:09 PM SGT
INSERT INTO AD_SysConfig (AD_SysConfig_ID,ConfigurationLevel,Value,AD_SysConfig_UU,Updated,Created,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name,AD_Client_ID,EntityType) VALUES (200050,'C','10','d2d149e8-e642-4691-8ed3-8a875ee9b1ed',TO_DATE('2014-03-28 18:51:08','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2014-03-28 18:51:08','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',100,'BACKGROUND_JOB_MAX_PER_CLIENT',0,'D')
;
-- Mar 28, 2014 6:52:26 PM SGT
INSERT INTO AD_SysConfig (AD_SysConfig_ID,ConfigurationLevel,Value,AD_SysConfig_UU,Updated,Created,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name,AD_Client_ID,EntityType) VALUES (200051,'C','10','b0697150-68d7-4cfe-b103-f626db07793a',TO_DATE('2014-03-28 18:52:25','YYYY-MM-DD HH24:MI:SS'),TO_DATE('2014-03-28 18:52:25','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',100,'BACKGROUND_JOB_MAX_PER_USER',0,'D')
;
-- Mar 28, 2014 6:53:28 PM SGT
UPDATE AD_SysConfig SET Value='5',Updated=TO_DATE('2014-03-28 18:53:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200051
;
-- Mar 28, 2014 6:54:11 PM SGT
UPDATE AD_SysConfig SET ConfigurationLevel='S',Updated=TO_DATE('2014-03-28 18:54:11','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200050
;
-- Mar 28, 2014 6:58:22 PM SGT
INSERT INTO PA_DashboardContent (Line,PA_DashboardContent_ID,ColumnNo,IsCollapsible,GoalDisplay,Description,Name,PA_DashboardContent_UU,IsShowInDashboard,AD_Org_ID,Created,CreatedBy,Updated,AD_Client_ID,UpdatedBy,IsActive,IsEmbedReportContent,IsCollapsedByDefault,AD_Role_ID,IsShowinLogin,ZulFilePath,AD_User_ID) VALUES (3.000000000000,200002,0,'Y','T','Running Jobs','Running Jobs','e3fb872e-ce14-4029-830b-2d21a556fc60','Y',0,TO_DATE('2014-03-28 18:58:20','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2014-03-28 18:58:20','YYYY-MM-DD HH24:MI:SS'),0,100,'Y','N','N',0,'Y','/zul/runningJobs.zul',0)
;
-- Mar 28, 2014 7:57:19 PM SGT
-- Ticket #1003856: Run report as a background job
UPDATE AD_Column SET AD_Reference_Value_ID=344,Updated=TO_DATE('2014-03-28 19:57:19','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=211201
;
-- Mar 28, 2014 7:58:52 PM SGT
INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,Created,EntityType,AD_Client_ID,AD_Org_ID) VALUES ('E','Exceed maximum number of running jobs allowed per user',200263,'82593e5f-86c6-45c5-bc38-4d9d5b2c8609','BackgroundJobExceedMaxPerUser','Y',TO_DATE('2014-03-28 19:58:49','YYYY-MM-DD HH24:MI:SS'),100,100,TO_DATE('2014-03-28 19:58:49','YYYY-MM-DD HH24:MI:SS'),'D',0,0)
;
-- Mar 28, 2014 7:59:12 PM SGT
INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,Created,EntityType,AD_Client_ID,AD_Org_ID) VALUES ('E','Exceed maximum number of running jobs allowed per client',200264,'fcebfad5-8283-498e-a835-b42bf0a0219a','BackgroundJobExceedMaxPerClient','Y',TO_DATE('2014-03-28 19:59:11','YYYY-MM-DD HH24:MI:SS'),100,100,TO_DATE('2014-03-28 19:59:11','YYYY-MM-DD HH24:MI:SS'),'D',0,0)
;
-- Mar 28, 2014 7:59:51 PM SGT
INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,Created,EntityType,AD_Client_ID,AD_Org_ID) VALUES ('E','Exceed maximum number of running jobs allowed in the system',200265,'405ea4c2-5a19-42fa-a5ff-f22601453f7f','BackgroundJobExceedMaxInSystem','Y',TO_DATE('2014-03-28 19:59:50','YYYY-MM-DD HH24:MI:SS'),100,100,TO_DATE('2014-03-28 19:59:50','YYYY-MM-DD HH24:MI:SS'),'D',0,0)
;
-- Mar 28, 2014 8:00:19 PM SGT
INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,Created,EntityType,AD_Client_ID,AD_Org_ID) VALUES ('I','The process has been scheduled as job. The status of the process will be sent as notification to owner of the process.',200266,'dc68fd3b-0ce8-416c-a286-37f192a90f7d','BackgroundJobScheduled','Y',TO_DATE('2014-03-28 20:00:18','YYYY-MM-DD HH24:MI:SS'),100,100,TO_DATE('2014-03-28 20:00:18','YYYY-MM-DD HH24:MI:SS'),'D',0,0)
;
-- Mar 28, 2014 9:03:01 PM SGT
-- Ticket #1003856: Run report as a background job
INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,Created,EntityType,AD_Client_ID,AD_Org_ID) VALUES ('I','Background Job',200267,'530545f2-f32c-4072-8bd1-d9ca65f31f65','BackgroundJob','Y',TO_DATE('2014-03-28 21:02:59','YYYY-MM-DD HH24:MI:SS'),100,100,TO_DATE('2014-03-28 21:02:59','YYYY-MM-DD HH24:MI:SS'),'D',0,0)
;
-- Mar 31, 2014 5:54:16 PM SGT
-- Ticket #1003856: Run report as a background job
DELETE FROM AD_Field_Trl WHERE AD_Field_ID=202846
;
-- Mar 31, 2014 5:54:16 PM SGT
DELETE FROM AD_Field WHERE AD_Field_ID=202846
;
-- Mar 31, 2014 5:54:49 PM SGT
DELETE FROM AD_Column_Trl WHERE AD_Column_ID=211200
;
-- Mar 31, 2014 5:54:49 PM SGT
DELETE FROM AD_Column WHERE AD_Column_ID=211200
;
-- Mar 31, 2014 5:54:56 PM SGT
DELETE FROM AD_Element_Trl WHERE AD_Element_ID=202695
;
-- Mar 31, 2014 5:54:56 PM SGT
DELETE FROM AD_Element WHERE AD_Element_ID=202695
;
ALTER TABLE AD_PInstance DROP COLUMN IsJobProcessing
;
SELECT register_migration_script('201403311258_Ticket_1003856.sql') FROM dual
;

View File

@ -0,0 +1,181 @@
-- Mar 28, 2014 6:34:26 PM SGT
-- Ticket #1003856: Run report as a background job
INSERT INTO AD_Element (ColumnName,AD_Element_ID,Name,PrintName,AD_Element_UU,Created,Updated,AD_Org_ID,CreatedBy,UpdatedBy,IsActive,AD_Client_ID,EntityType) VALUES ('IsRunAsJob',202694,'Run as Job','Run as Job','c52c9e5a-da3e-401d-8f52-e58f557a56f2',TO_TIMESTAMP('2014-03-28 18:34:24','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2014-03-28 18:34:24','YYYY-MM-DD HH24:MI:SS'),0,100,100,'Y',0,'D')
;
-- Mar 28, 2014 6:35:05 PM SGT
INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,Version,AD_Column_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,DefaultValue,Name,IsAllowCopy,Updated,CreatedBy,AD_Org_ID,IsActive,Created,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,AD_Client_ID,IsEncrypted,IsSecure,FKConstraintType,AD_Element_ID,AD_Reference_ID,AD_Table_ID,EntityType) VALUES (0,'N',0,211199,'Y','N','N',0,'N',1,'N','N','N','Y','e67be641-2f1b-4c6b-9c8a-a6788940a686','Y','IsRunAsJob','N','Run as Job','Y',TO_TIMESTAMP('2014-03-28 18:35:03','YYYY-MM-DD HH24:MI:SS'),100,0,'Y',TO_TIMESTAMP('2014-03-28 18:35:03','YYYY-MM-DD HH24:MI:SS'),100,'N','N',0,'N','N','N',202694,20,282,'D')
;
-- Mar 28, 2014 6:38:03 PM SGT
INSERT INTO AD_Element (ColumnName,AD_Element_ID,Name,PrintName,AD_Element_UU,Created,Updated,AD_Org_ID,CreatedBy,UpdatedBy,IsActive,AD_Client_ID,EntityType) VALUES ('IsJobProcessing',202695,'Job Processing','Job Processing','54265662-ebe2-4521-ba7e-8a9f9a96bcab',TO_TIMESTAMP('2014-03-28 18:38:02','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2014-03-28 18:38:02','YYYY-MM-DD HH24:MI:SS'),0,100,100,'Y',0,'D')
;
-- Mar 28, 2014 6:38:22 PM SGT
INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,Version,AD_Column_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,DefaultValue,Name,IsAllowCopy,Updated,CreatedBy,AD_Org_ID,IsActive,Created,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,AD_Client_ID,IsEncrypted,IsSecure,FKConstraintType,AD_Element_ID,AD_Reference_ID,AD_Table_ID,EntityType) VALUES (0,'N',0,211200,'Y','N','N',0,'N',1,'N','N','N','Y','922b7724-599a-49c8-a053-0f8f4b8e2156','Y','IsJobProcessing','N','Job Processing','Y',TO_TIMESTAMP('2014-03-28 18:38:21','YYYY-MM-DD HH24:MI:SS'),100,0,'Y',TO_TIMESTAMP('2014-03-28 18:38:21','YYYY-MM-DD HH24:MI:SS'),100,'N','N',0,'N','N','N',202695,20,282,'D')
;
-- Mar 28, 2014 6:38:42 PM SGT
INSERT INTO AD_Column (SeqNoSelection,IsSyncDatabase,Version,AD_Column_ID,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsParent,FieldLength,IsSelectionColumn,IsKey,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsUpdateable,ColumnName,Description,Help,Name,IsAllowCopy,Updated,CreatedBy,AD_Org_ID,IsActive,Created,UpdatedBy,IsToolbarButton,IsAlwaysUpdateable,AD_Client_ID,IsEncrypted,IsSecure,AD_Element_ID,AD_Reference_ID,AD_Reference_Value_ID,AD_Table_ID,EntityType) VALUES (0,'N',0,211201,'N','N','N',0,'N',2,'N','N','N','Y','5c07ac2d-8342-4e86-ae06-5109f872a16b','Y','NotificationType','Type of Notifications','Emails or Notification sent out for Request Updates, etc.','Notification Type','Y',TO_TIMESTAMP('2014-03-28 18:38:41','YYYY-MM-DD HH24:MI:SS'),100,0,'Y',TO_TIMESTAMP('2014-03-28 18:38:41','YYYY-MM-DD HH24:MI:SS'),100,'N','N',0,'N','N',2755,17,200026,282,'D')
;
-- Mar 28, 2014 6:43:27 PM SGT
ALTER TABLE AD_PInstance ADD COLUMN IsRunAsJob CHAR(1) DEFAULT 'N'
;
-- Mar 28, 2014 6:43:44 PM SGT
ALTER TABLE AD_PInstance ADD COLUMN IsJobProcessing CHAR(1) DEFAULT 'N'
;
-- Mar 28, 2014 6:43:51 PM SGT
ALTER TABLE AD_PInstance ADD COLUMN NotificationType VARCHAR(2) DEFAULT NULL
;
-- Mar 28, 2014 6:44:35 PM SGT
INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,EntityType,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,Created,CreatedBy,Updated,IsActive,IsDisplayedGrid,AD_Client_ID,ColumnSpan,AD_Column_ID) VALUES ('N',663,36,'N','N',110,'Y',202844,'N','D','AD_PInstance_UU','3540b3cc-efe6-4509-bafc-a15c59c9d7f8','N','N',100,0,TO_TIMESTAMP('2014-03-28 18:44:34','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2014-03-28 18:44:34','YYYY-MM-DD HH24:MI:SS'),'Y','N',0,2,60451)
;
-- Mar 28, 2014 6:44:36 PM SGT
INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,EntityType,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,Created,CreatedBy,Updated,IsActive,XPosition,AD_Client_ID,ColumnSpan,AD_Column_ID) VALUES ('N',663,1,'N','N',120,'Y',202845,'N','D','Run as Job','72ecc44d-a61b-44b9-a94a-14bd270dbf22','Y','N',100,0,TO_TIMESTAMP('2014-03-28 18:44:35','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2014-03-28 18:44:35','YYYY-MM-DD HH24:MI:SS'),'Y',2,0,2,211199)
;
-- Mar 28, 2014 6:44:37 PM SGT
INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,EntityType,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,Created,CreatedBy,Updated,IsActive,XPosition,AD_Client_ID,ColumnSpan,AD_Column_ID) VALUES ('N',663,1,'N','N',130,'Y',202846,'N','D','Job Processing','96118891-6592-4f41-8ba0-05057e17d60e','Y','N',100,0,TO_TIMESTAMP('2014-03-28 18:44:36','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2014-03-28 18:44:36','YYYY-MM-DD HH24:MI:SS'),'Y',2,0,2,211200)
;
-- Mar 28, 2014 6:44:38 PM SGT
INSERT INTO AD_Field (IsEncrypted,AD_Tab_ID,DisplayLength,IsSameLine,IsHeading,SeqNo,IsCentrallyMaintained,AD_Field_ID,IsReadOnly,Help,EntityType,Description,Name,AD_Field_UU,IsDisplayed,IsFieldOnly,UpdatedBy,AD_Org_ID,Created,CreatedBy,Updated,IsActive,AD_Client_ID,ColumnSpan,AD_Column_ID) VALUES ('N',663,2,'N','N',140,'Y',202847,'N','Emails or Notification sent out for Request Updates, etc.','D','Type of Notifications','Notification Type','d76699c8-2abe-4f62-9e10-6e10fd5dba20','Y','N',100,0,TO_TIMESTAMP('2014-03-28 18:44:37','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2014-03-28 18:44:37','YYYY-MM-DD HH24:MI:SS'),'Y',0,2,211201)
;
-- Mar 28, 2014 6:45:04 PM SGT
UPDATE AD_Field SET SeqNo=0,IsDisplayed='N' WHERE AD_Field_ID=202844
;
-- Mar 28, 2014 6:45:04 PM SGT
UPDATE AD_Field SET SeqNo=110,IsDisplayed='Y' WHERE AD_Field_ID=202845
;
-- Mar 28, 2014 6:45:04 PM SGT
UPDATE AD_Field SET SeqNo=120,IsDisplayed='Y' WHERE AD_Field_ID=202847
;
-- Mar 28, 2014 6:45:11 PM SGT
UPDATE AD_Field SET SeqNoGrid=110,IsDisplayedGrid='Y' WHERE AD_Field_ID=202845
;
-- Mar 28, 2014 6:45:11 PM SGT
UPDATE AD_Field SET SeqNoGrid=120,IsDisplayedGrid='Y' WHERE AD_Field_ID=202847
;
-- Mar 28, 2014 6:45:11 PM SGT
UPDATE AD_Field SET SeqNoGrid=130,IsDisplayedGrid='Y' WHERE AD_Field_ID=202846
;
-- Mar 28, 2014 6:46:01 PM SGT
INSERT INTO AD_FieldGroup (FieldGroupType,EntityType,IsCollapsedByDefault,Name,AD_FieldGroup_UU,AD_FieldGroup_ID,Created,CreatedBy,Updated,AD_Org_ID,UpdatedBy,IsActive,AD_Client_ID) VALUES ('C','D','N','Background Job','3be13370-89e4-42b3-8220-370ce497466a',200018,TO_TIMESTAMP('2014-03-28 18:46:00','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2014-03-28 18:46:00','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',0)
;
-- Mar 28, 2014 6:46:18 PM SGT
UPDATE AD_Field SET AD_FieldGroup_ID=200018,Updated=TO_TIMESTAMP('2014-03-28 18:46:18','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202847
;
-- Mar 28, 2014 6:46:22 PM SGT
UPDATE AD_Field SET AD_FieldGroup_ID=200018,Updated=TO_TIMESTAMP('2014-03-28 18:46:22','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202845
;
-- Mar 28, 2014 6:46:28 PM SGT
UPDATE AD_Field SET AD_FieldGroup_ID=200018,Updated=TO_TIMESTAMP('2014-03-28 18:46:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202846
;
-- Mar 28, 2014 6:46:44 PM SGT
UPDATE AD_Field SET IsSameLine='Y', XPosition=4,Updated=TO_TIMESTAMP('2014-03-28 18:46:44','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=202847
;
-- Mar 28, 2014 6:49:07 PM SGT
INSERT INTO AD_SysConfig (AD_SysConfig_ID,ConfigurationLevel,Value,AD_SysConfig_UU,Updated,Created,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name,AD_Client_ID,EntityType) VALUES (200047,'C','Y','feb88039-2fe8-47e5-a7be-c3a634674f0b',TO_TIMESTAMP('2014-03-28 18:49:06','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2014-03-28 18:49:06','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',100,'BACKGROUND_JOB_ALLOWED',0,'D')
;
-- Mar 28, 2014 6:49:31 PM SGT
INSERT INTO AD_SysConfig (AD_SysConfig_ID,ConfigurationLevel,Value,AD_SysConfig_UU,Updated,Created,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name,AD_Client_ID,EntityType) VALUES (200048,'C','N','f2fd6f9b-d8bb-4ade-9857-78ba68951776',TO_TIMESTAMP('2014-03-28 18:49:30','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2014-03-28 18:49:30','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',100,'BACKGROUND_JOB_BY_DEFAULT',0,'D')
;
-- Mar 28, 2014 6:50:36 PM SGT
INSERT INTO AD_SysConfig (AD_SysConfig_ID,ConfigurationLevel,Value,AD_SysConfig_UU,Updated,Created,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name,AD_Client_ID,EntityType) VALUES (200049,'S','20','0a24332e-a83a-465a-903f-6f3d7caea306',TO_TIMESTAMP('2014-03-28 18:50:35','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2014-03-28 18:50:35','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',100,'BACKGROUND_JOB_MAX_IN_SYSTEM',0,'D')
;
-- Mar 28, 2014 6:51:09 PM SGT
INSERT INTO AD_SysConfig (AD_SysConfig_ID,ConfigurationLevel,Value,AD_SysConfig_UU,Updated,Created,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name,AD_Client_ID,EntityType) VALUES (200050,'C','10','d2d149e8-e642-4691-8ed3-8a875ee9b1ed',TO_TIMESTAMP('2014-03-28 18:51:08','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2014-03-28 18:51:08','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',100,'BACKGROUND_JOB_MAX_PER_CLIENT',0,'D')
;
-- Mar 28, 2014 6:52:26 PM SGT
INSERT INTO AD_SysConfig (AD_SysConfig_ID,ConfigurationLevel,Value,AD_SysConfig_UU,Updated,Created,AD_Org_ID,CreatedBy,IsActive,UpdatedBy,Name,AD_Client_ID,EntityType) VALUES (200051,'C','10','b0697150-68d7-4cfe-b103-f626db07793a',TO_TIMESTAMP('2014-03-28 18:52:25','YYYY-MM-DD HH24:MI:SS'),TO_TIMESTAMP('2014-03-28 18:52:25','YYYY-MM-DD HH24:MI:SS'),0,100,'Y',100,'BACKGROUND_JOB_MAX_PER_USER',0,'D')
;
-- Mar 28, 2014 6:53:28 PM SGT
UPDATE AD_SysConfig SET Value='5',Updated=TO_TIMESTAMP('2014-03-28 18:53:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200051
;
-- Mar 28, 2014 6:54:11 PM SGT
UPDATE AD_SysConfig SET ConfigurationLevel='S',Updated=TO_TIMESTAMP('2014-03-28 18:54:11','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_SysConfig_ID=200050
;
-- Mar 28, 2014 6:58:22 PM SGT
INSERT INTO PA_DashboardContent (Line,PA_DashboardContent_ID,ColumnNo,IsCollapsible,GoalDisplay,Description,Name,PA_DashboardContent_UU,IsShowInDashboard,AD_Org_ID,Created,CreatedBy,Updated,AD_Client_ID,UpdatedBy,IsActive,IsEmbedReportContent,IsCollapsedByDefault,AD_Role_ID,IsShowinLogin,ZulFilePath,AD_User_ID) VALUES (3.000000000000,200002,0,'Y','T','Running Jobs','Running Jobs','e3fb872e-ce14-4029-830b-2d21a556fc60','Y',0,TO_TIMESTAMP('2014-03-28 18:58:20','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2014-03-28 18:58:20','YYYY-MM-DD HH24:MI:SS'),0,100,'Y','N','N',0,'Y','/zul/runningJobs.zul',0)
;
-- Mar 28, 2014 7:57:19 PM SGT
-- Ticket #1003856: Run report as a background job
UPDATE AD_Column SET AD_Reference_Value_ID=344,Updated=TO_TIMESTAMP('2014-03-28 19:57:19','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=211201
;
-- Mar 28, 2014 7:58:52 PM SGT
INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,Created,EntityType,AD_Client_ID,AD_Org_ID) VALUES ('E','Exceed maximum number of running jobs allowed per user',200263,'82593e5f-86c6-45c5-bc38-4d9d5b2c8609','BackgroundJobExceedMaxPerUser','Y',TO_TIMESTAMP('2014-03-28 19:58:49','YYYY-MM-DD HH24:MI:SS'),100,100,TO_TIMESTAMP('2014-03-28 19:58:49','YYYY-MM-DD HH24:MI:SS'),'D',0,0)
;
-- Mar 28, 2014 7:59:12 PM SGT
INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,Created,EntityType,AD_Client_ID,AD_Org_ID) VALUES ('E','Exceed maximum number of running jobs allowed per client',200264,'fcebfad5-8283-498e-a835-b42bf0a0219a','BackgroundJobExceedMaxPerClient','Y',TO_TIMESTAMP('2014-03-28 19:59:11','YYYY-MM-DD HH24:MI:SS'),100,100,TO_TIMESTAMP('2014-03-28 19:59:11','YYYY-MM-DD HH24:MI:SS'),'D',0,0)
;
-- Mar 28, 2014 7:59:51 PM SGT
INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,Created,EntityType,AD_Client_ID,AD_Org_ID) VALUES ('E','Exceed maximum number of running jobs allowed in the system',200265,'405ea4c2-5a19-42fa-a5ff-f22601453f7f','BackgroundJobExceedMaxInSystem','Y',TO_TIMESTAMP('2014-03-28 19:59:50','YYYY-MM-DD HH24:MI:SS'),100,100,TO_TIMESTAMP('2014-03-28 19:59:50','YYYY-MM-DD HH24:MI:SS'),'D',0,0)
;
-- Mar 28, 2014 8:00:19 PM SGT
INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,Created,EntityType,AD_Client_ID,AD_Org_ID) VALUES ('I','The process has been scheduled as job. The status of the process will be sent as notification to owner of the process.',200266,'dc68fd3b-0ce8-416c-a286-37f192a90f7d','BackgroundJobScheduled','Y',TO_TIMESTAMP('2014-03-28 20:00:18','YYYY-MM-DD HH24:MI:SS'),100,100,TO_TIMESTAMP('2014-03-28 20:00:18','YYYY-MM-DD HH24:MI:SS'),'D',0,0)
;
-- Mar 28, 2014 9:03:01 PM SGT
-- Ticket #1003856: Run report as a background job
INSERT INTO AD_Message (MsgType,MsgText,AD_Message_ID,AD_Message_UU,Value,IsActive,Updated,CreatedBy,UpdatedBy,Created,EntityType,AD_Client_ID,AD_Org_ID) VALUES ('I','Background Job',200267,'530545f2-f32c-4072-8bd1-d9ca65f31f65','BackgroundJob','Y',TO_TIMESTAMP('2014-03-28 21:02:59','YYYY-MM-DD HH24:MI:SS'),100,100,TO_TIMESTAMP('2014-03-28 21:02:59','YYYY-MM-DD HH24:MI:SS'),'D',0,0)
;
-- Mar 31, 2014 5:54:16 PM SGT
-- Ticket #1003856: Run report as a background job
DELETE FROM AD_Field_Trl WHERE AD_Field_ID=202846
;
-- Mar 31, 2014 5:54:16 PM SGT
DELETE FROM AD_Field WHERE AD_Field_ID=202846
;
-- Mar 31, 2014 5:54:49 PM SGT
DELETE FROM AD_Column_Trl WHERE AD_Column_ID=211200
;
-- Mar 31, 2014 5:54:49 PM SGT
DELETE FROM AD_Column WHERE AD_Column_ID=211200
;
-- Mar 31, 2014 5:54:56 PM SGT
DELETE FROM AD_Element_Trl WHERE AD_Element_ID=202695
;
-- Mar 31, 2014 5:54:56 PM SGT
DELETE FROM AD_Element WHERE AD_Element_ID=202695
;
ALTER TABLE AD_PInstance DROP COLUMN IsJobProcessing
;
SELECT register_migration_script('201403311258_Ticket_1003856.sql') FROM dual
;

View File

@ -174,6 +174,28 @@ public interface I_AD_PInstance
*/
public String getName();
/** Column name IsRunAsJob */
public static final String COLUMNNAME_IsRunAsJob = "IsRunAsJob";
/** Set Run as Job */
public void setIsRunAsJob (boolean IsRunAsJob);
/** Get Run as Job */
public boolean isRunAsJob();
/** Column name NotificationType */
public static final String COLUMNNAME_NotificationType = "NotificationType";
/** Set Notification Type.
* Type of Notifications
*/
public void setNotificationType (String NotificationType);
/** Get Notification Type.
* Type of Notifications
*/
public String getNotificationType();
/** Column name Record_ID */
public static final String COLUMNNAME_Record_ID = "Record_ID";

View File

@ -554,6 +554,56 @@ public class MClient extends X_AD_Client
}
} // sendEMail
/**
* Send EMail from User
* @param from sender
* @param to recipient
* @param subject subject
* @param message message
* @param attachment optional attachment
* @return true if sent
*/
public boolean sendEMailAttachments (MUser from, MUser to,
String subject, String message, List<File> attachments)
{
return sendEMailAttachments(from, to, subject, message, attachments, false);
}
/**
* Send EMail from User
* @param from sender
* @param to recipient
* @param subject subject
* @param message message
* @param attachment optional attachment
* @param isHtml
* @return true if sent
*/
public boolean sendEMailAttachments (MUser from, MUser to,
String subject, String message, List<File> attachments, boolean isHtml)
{
EMail email = createEMail(from, to, subject, message, isHtml);
if (email == null)
return false;
if (attachments != null && !attachments.isEmpty())
{
for (File attachment : attachments)
email.addAttachment(attachment);
}
InternetAddress emailFrom = email.getFrom();
try
{
return sendEmailNow(from, to, email);
}
catch (Exception ex)
{
log.severe(getName() + " - from " + emailFrom
+ " to " + to + ": " + ex.getLocalizedMessage());
return false;
}
} // sendEMail
/**
* Send EMail from Request User - no trace
* @param to recipient email address

View File

@ -21,14 +21,21 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import org.adempiere.base.Service;
import org.adempiere.base.event.EventManager;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.idempiere.distributed.IMessageService;
import org.idempiere.distributed.ITopic;
import org.osgi.service.event.Event;
/**
* Process Instance Model
@ -45,7 +52,9 @@ public class MPInstance extends X_AD_PInstance
/**
*
*/
private static final long serialVersionUID = -3952972645135787655L;
private static final long serialVersionUID = -4047766735041088419L;
public static final String ON_RUNNING_JOB_CHANGED_TOPIC = "onRunningJobChanged";
private static CLogger s_log = CLogger.getCLogger (MPInstance.class);
@ -353,6 +362,23 @@ public class MPInstance extends X_AD_PInstance
return ip;
}
public static void publishChangedEvent(int AD_User_ID) {
IMessageService service = Service.locator().locate(IMessageService.class).getService();
if (service != null) {
ITopic<Integer> topic = service.getTopic(ON_RUNNING_JOB_CHANGED_TOPIC);
topic.publish(AD_User_ID);
} else {
postOnChangedEvent(AD_User_ID);
}
}
public static void postOnChangedEvent(int AD_User_ID) {
Map<String, Integer> properties = new HashMap<String, Integer>();
properties.put("AD_User_ID", AD_User_ID);
Event event = new Event(ON_RUNNING_JOB_CHANGED_TOPIC, properties);
EventManager.getInstance().postEvent(event);
}
public static List<MPInstance> get(Properties ctx, int AD_Process_ID, int AD_User_ID) {
List<MPInstance> list = new ArrayList<MPInstance>();
List<String> paramsStrAdded = new ArrayList<String>();

View File

@ -122,6 +122,12 @@ public class MSysConfig extends X_AD_SysConfig
public static final String TAX_SAVE_REQUEST_RESPONSE_LOG = "TAX_SAVE_REQUEST_RESPONSE_LOG";
public static final String ADDRESS_SAVE_REQUEST_RESPONSE_LOG = "ADDRESS_SAVE_REQUEST_RESPONSE_LOG";
public static final String VALIDATE_MATCHING_TO_ORDERED_QTY = "VALIDATE_MATCHING_TO_ORDERED_QTY";
public static final String BACKGROUND_JOB_ALLOWED = "BACKGROUND_JOB_ALLOWED";
public static final String BACKGROUND_JOB_BY_DEFAULT = "BACKGROUND_JOB_BY_DEFAULT";
public static final String BACKGROUND_JOB_MAX_IN_SYSTEM = "BACKGROUND_JOB_MAX_IN_SYSTEM";
public static final String BACKGROUND_JOB_MAX_PER_CLIENT = "BACKGROUND_JOB_MAX_PER_CLIENT";
public static final String BACKGROUND_JOB_MAX_PER_USER = "BACKGROUND_JOB_MAX_PER_USER";
public static final String DPVIEWS_SHOWINFOACCOUNT = "DPViews_ShowInfoAccount";
public static final String DPVIEWS_SHOWINFOSCHEDULE = "DPViews_ShowInfoSchedule";

View File

@ -30,7 +30,7 @@ public class X_AD_PInstance extends PO implements I_AD_PInstance, I_Persistent
/**
*
*/
private static final long serialVersionUID = 20140404L;
private static final long serialVersionUID = 20140331L;
/** Standard Constructor */
public X_AD_PInstance (Properties ctx, int AD_PInstance_ID, String trxName)
@ -41,6 +41,8 @@ public class X_AD_PInstance extends PO implements I_AD_PInstance, I_Persistent
setAD_PInstance_ID (0);
setAD_Process_ID (0);
setIsProcessing (false);
setIsRunAsJob (false);
// N
setRecord_ID (0);
} */
}
@ -226,6 +228,55 @@ public class X_AD_PInstance extends PO implements I_AD_PInstance, I_Persistent
return (String)get_Value(COLUMNNAME_Name);
}
/** Set Run as Job.
@param IsRunAsJob Run as Job */
public void setIsRunAsJob (boolean IsRunAsJob)
{
set_Value (COLUMNNAME_IsRunAsJob, Boolean.valueOf(IsRunAsJob));
}
/** Get Run as Job.
@return Run as Job */
public boolean isRunAsJob ()
{
Object oo = get_Value(COLUMNNAME_IsRunAsJob);
if (oo != null)
{
if (oo instanceof Boolean)
return ((Boolean)oo).booleanValue();
return "Y".equals(oo);
}
return false;
}
/** NotificationType AD_Reference_ID=344 */
public static final int NOTIFICATIONTYPE_AD_Reference_ID=344;
/** EMail = E */
public static final String NOTIFICATIONTYPE_EMail = "E";
/** Notice = N */
public static final String NOTIFICATIONTYPE_Notice = "N";
/** None = X */
public static final String NOTIFICATIONTYPE_None = "X";
/** EMail+Notice = B */
public static final String NOTIFICATIONTYPE_EMailPlusNotice = "B";
/** Set Notification Type.
@param NotificationType
Type of Notifications
*/
public void setNotificationType (String NotificationType)
{
set_Value (COLUMNNAME_NotificationType, NotificationType);
}
/** Get Notification Type.
@return Type of Notifications
*/
public String getNotificationType ()
{
return (String)get_Value(COLUMNNAME_NotificationType);
}
/** Set Record ID.
@param Record_ID
Direct internal record ID

View File

@ -61,31 +61,38 @@ public class ServerProcessCtl implements Runnable {
if (log.isLoggable(Level.FINE)) log.fine("ServerProcess - " + pi);
MPInstance instance = null;
try
if (pi.getAD_PInstance_ID() <= 0)
{
instance = new MPInstance(Env.getCtx(), pi.getAD_Process_ID(), pi.getRecord_ID());
try
{
instance = new MPInstance(Env.getCtx(), pi.getAD_Process_ID(), pi.getRecord_ID());
}
catch (Exception e)
{
pi.setSummary (e.getLocalizedMessage());
pi.setError (true);
log.warning(pi.toString());
return null;
}
catch (Error e)
{
pi.setSummary (e.getLocalizedMessage());
pi.setError (true);
log.warning(pi.toString());
return null;
}
if (!instance.save())
{
pi.setSummary (Msg.getMsg(Env.getCtx(), "ProcessNoInstance"));
pi.setError (true);
return null;
}
pi.setAD_PInstance_ID (instance.getAD_PInstance_ID());
}
catch (Exception e)
else
{
pi.setSummary (e.getLocalizedMessage());
pi.setError (true);
log.warning(pi.toString());
return null;
instance = new MPInstance(Env.getCtx(), pi.getAD_PInstance_ID(), null);
}
catch (Error e)
{
pi.setSummary (e.getLocalizedMessage());
pi.setError (true);
log.warning(pi.toString());
return null;
}
if (!instance.save())
{
pi.setSummary (Msg.getMsg(Env.getCtx(), "ProcessNoInstance"));
pi.setError (true);
return null;
}
pi.setAD_PInstance_ID (instance.getAD_PInstance_ID());
// execute
ServerProcessCtl worker = new ServerProcessCtl(pi, trx);

View File

@ -626,7 +626,7 @@ public class ReportStarter implements ProcessCall, ClientProcess
if (!processInfo.isExport())
{
if (reportData.isDirectPrint())
if (reportData.isDirectPrint() || processInfo.isBatch())
{
if (log.isLoggable(Level.INFO)) log.info( "ReportStarter.startProcess print report -" + jasperPrint.getName());
//RF 1906632
@ -666,8 +666,6 @@ public class ReportStarter implements ProcessCall, ClientProcess
}
else
{
// You can use JasperPrint to create PDF
// Used For the PH
try
{
File PDF = File.createTempFile(makePrefix(jasperPrint.getName()), ".pdf");
@ -685,9 +683,6 @@ public class ReportStarter implements ProcessCall, ClientProcess
log.severe("ReportStarter.startProcess: Can not make PDF File - "+ e.getMessage());
}
}
// You can use JasperPrint to create PDF
// JasperExportManager.exportReportToPdfFile(jasperPrint, "BasicReport.pdf");
} else {
if (log.isLoggable(Level.INFO)) log.info( "ReportStarter.startProcess run report -"+jasperPrint.getName());
JRViewerProvider viewerLauncher = Service.locator().locate(JRViewerProvider.class).getService();

View File

@ -23,6 +23,8 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
@ -157,7 +159,7 @@ public class Scheduler extends AdempiereServer
{
if (log.isLoggable(Level.INFO)) log.info(process.toString());
boolean isReport = (process.isReport() || process.getAD_ReportView_ID() > 0);
boolean isReport = (process.isReport() || process.getAD_ReportView_ID() > 0 || process.getJasperReport() != null || process.getAD_PrintFormat_ID() > 0);
// Process (see also MWFActivity.performWork
int AD_Table_ID = m_model.getAD_Table_ID();
@ -170,9 +172,11 @@ public class Scheduler extends AdempiereServer
pi.setAD_User_ID(getAD_User_ID());
pi.setAD_Client_ID(m_model.getAD_Client_ID());
pi.setAD_PInstance_ID(pInstance.getAD_PInstance_ID());
pi.setIsBatch(true);
MUser from = new MUser(getCtx(), pi.getAD_User_ID(), null);
if ( !process.processIt(pi, m_trx) ) // note, this call close the transaction, don't use m_trx below
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 = m_model.getSupervisor_ID();
@ -195,9 +199,16 @@ public class Scheduler extends AdempiereServer
MNote note = new MNote(getCtx(), AD_Message_ID, supervisor, null);
note.setClientOrg(m_model.getAD_Client_ID(), m_model.getAD_Org_ID());
note.setTextMsg(pi.getSummary());
//note.setDescription();
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(m_model.getAD_Client_ID(), m_model.getAD_Org_ID());
attachment.setTextMsg(m_model.getName());
attachment.addEntry("ProcessLog.html", log.getBytes("UTF-8"));
attachment.saveEx();
}
}
}
}
@ -207,38 +218,45 @@ public class Scheduler extends AdempiereServer
if (userIDs.length > 0)
{
ProcessInfoUtil.setLogFromDB(pi);
List<File> fileList = new ArrayList<File>();
if (isReport) {
// Report
ReportEngine re = ReportEngine.get(m_schedulerctx, pi);
if(re != null && re.getPrintFormat().getJasperProcess_ID() > 0)
{
// We have a Jasper Print Format
// ==============================
ProcessInfo jasperpi = new ProcessInfo ("", re.getPrintFormat().getJasperProcess_ID());
jasperpi.setIsBatch(true);
ServerProcessCtl.process(jasperpi, null);
fileList.add(jasperpi.getPDFReport());
}
else if (process.getJasperReport() != null)
{
fileList.add(pi.getPDFReport());
}
else
{
// Standard Print Format (Non-Jasper)
// ==================================
if (re == null)
return "Cannot create Report AD_Process_ID=" + process.getAD_Process_ID()
+ " - " + process.getName();
fileList.add(re.getPDF());
}
}
if (pi.isExport() && pi.getExportFile() != null)
{
fileList.add(pi.getExportFile());
}
for (int i = 0; i < userIDs.length; i++)
{
MUser user = new MUser(getCtx(), userIDs[i].intValue(), null);
boolean email = user.isNotificationEMail();
boolean notice = user.isNotificationNote();
File report = null;
if (isReport) {
// Report
ReportEngine re = ReportEngine.get(m_schedulerctx, pi);
if(process.getJasperReport() != null
|| (re != null && re.getPrintFormat().getJasperProcess_ID() > 0))
{
// We have a Jasper Print Format
// ==============================
ProcessInfo jasperpi = new ProcessInfo ("", process.getAD_Process_ID());
jasperpi.setIsBatch(true);
ServerProcessCtl.process(jasperpi, null);
report = jasperpi.getPDFReport();
}
else
{
// Standard Print Format (Non-Jasper)
// ==================================
if (re == null)
return "Cannot create Report AD_Process_ID=" + process.getAD_Process_ID()
+ " - " + process.getName();
report = re.getPDF();
}
}
if (notice) {
int AD_Message_ID = 441; // ProcessOK
if (isReport)
@ -250,29 +268,42 @@ public class Scheduler extends AdempiereServer
note.setDescription(m_model.getDescription());
note.setRecord(AD_Table_ID, Record_ID);
} else {
note.setTextMsg(pi.getSummary());
// note.setDescription();
note.setTextMsg(m_model.getName() + "\n" + pi.getSummary());
note.setRecord(MPInstance.Table_ID, pi.getAD_PInstance_ID());
}
if (note.save()) {
if (isReport) {
MAttachment attachment = null;
if (fileList != null && !fileList.isEmpty()) {
// Attachment
MAttachment attachment = new MAttachment (getCtx(), MNote.Table_ID, note.getAD_Note_ID(), null);
attachment = new MAttachment (getCtx(), MNote.Table_ID, note.getAD_Note_ID(), null);
attachment.setClientOrg(m_model.getAD_Client_ID(), m_model.getAD_Org_ID());
attachment.addEntry(report);
attachment.setTextMsg(m_model.getName());
for (File entry : fileList)
attachment.addEntry(entry);
}
String log = pi.getLogInfo(true);
if (log != null && log.trim().length() > 0) {
if (attachment == null) {
attachment = new MAttachment (getCtx(), MNote.Table_ID, note.getAD_Note_ID(), null);
attachment.setClientOrg(m_model.getAD_Client_ID(), m_model.getAD_Org_ID());
attachment.setTextMsg(m_model.getName());
}
attachment.addEntry("ProcessLog.html", log.getBytes("UTF-8"));
attachment.saveEx();
}
if (attachment != null)
attachment.saveEx();
}
}
if (email)
{
MClient client = MClient.get(m_model.getCtx(), m_model.getAD_Client_ID());
if (isReport) {
client.sendEMail(from, user, m_model.getName(), m_model.getDescription(), report);
if (fileList != null && !fileList.isEmpty()) {
client.sendEMailAttachments(from, user, m_model.getName(), m_model.getDescription(), fileList);
} else {
client.sendEMail(from, user, process.getName(), pi.getSummary() + " " + pi.getLogInfo(), null);
client.sendEMail(from, user, m_model.getName(), pi.getSummary() + " " + pi.getLogInfo(), null);
}
}

View File

@ -0,0 +1,761 @@
/******************************************************************************
* Copyright (C) 2014 Elaine Tan *
* Copyright (C) 2014 Trek Global
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. 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., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.webui.apps;
import java.io.File;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import org.adempiere.util.Callback;
import org.adempiere.util.ContextRunnable;
import org.adempiere.util.IProcessUI;
import org.adempiere.util.ServerContext;
import org.adempiere.webui.component.Checkbox;
import org.adempiere.webui.component.Column;
import org.adempiere.webui.component.Columns;
import org.adempiere.webui.component.ComboItem;
import org.adempiere.webui.component.Combobox;
import org.adempiere.webui.component.Grid;
import org.adempiere.webui.component.GridFactory;
import org.adempiere.webui.component.Label;
import org.adempiere.webui.component.Panel;
import org.adempiere.webui.component.Row;
import org.adempiere.webui.component.Rows;
import org.adempiere.webui.component.Window;
import org.adempiere.webui.editor.WTableDirEditor;
import org.adempiere.webui.process.WProcessInfo;
import org.adempiere.webui.window.FDialog;
import org.adempiere.webui.window.MultiFileDownloadDialog;
import org.compiere.Adempiere;
import org.compiere.model.MAttachment;
import org.compiere.model.MClient;
import org.compiere.model.MLookup;
import org.compiere.model.MLookupFactory;
import org.compiere.model.MLookupInfo;
import org.compiere.model.MNote;
import org.compiere.model.MPInstance;
import org.compiere.model.MProcess;
import org.compiere.model.MSysConfig;
import org.compiere.model.MUser;
import org.compiere.model.Query;
import org.compiere.print.ReportEngine;
import org.compiere.process.ProcessInfo;
import org.compiere.process.ProcessInfoUtil;
import org.compiere.process.ServerProcessCtl;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Trx;
import org.zkoss.zk.au.out.AuEcho;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Div;
import org.zkoss.zul.Html;
import org.zkoss.zul.Space;
public abstract class AbstractProcessDialog extends Window implements IProcessUI, EventListener<Event>
{
/**
*
*/
private static final long serialVersionUID = 2190456247109646320L;
private static final String ON_COMPLETE = "onComplete";
private static final String ON_STATUS_UPDATE = "onStatusUpdate";
private static CLogger log = CLogger.getCLogger(AbstractProcessDialog.class);
private int m_WindowNo;
private Properties m_ctx;
private int m_AD_Process_ID;
private ProcessInfo m_pi = null;
private boolean m_disposeOnComplete;
private Html message = null;
private Panel centerPanel = null;
private ProcessParameterPanel parameterPanel = null;
private Checkbox runAsJobField = null;
private WTableDirEditor notificationTypeField = null;
private BusyDialog progressWindow;
private String m_Name = null;
private StringBuffer m_messageText = new StringBuffer();
private String m_ShowHelp = null; // Determine if a Help Process Window is shown
private String initialMessage;
private boolean m_valid = true;
private boolean m_cancel = false;
private Future<?> future;
private List<File> downloadFiles;
private boolean m_locked = false;
protected AbstractProcessDialog()
{
super();
message = new Html();
centerPanel = new Panel();
}
protected boolean init(Properties ctx, int WindowNo, int AD_Process_ID, ProcessInfo pi, String innerWidth, boolean autoStart, boolean isDisposeOnComplete)
{
m_ctx = ctx;
m_WindowNo = WindowNo;
m_AD_Process_ID = AD_Process_ID;
setProcessInfo(pi);
m_disposeOnComplete = isDisposeOnComplete;
log.config("");
//
boolean trl = !Env.isBaseLanguage(m_ctx, "AD_Process");
String sql = "SELECT Name, Description, Help, IsReport, ShowHelp "
+ "FROM AD_Process "
+ "WHERE AD_Process_ID=?";
if (trl)
sql = "SELECT t.Name, t.Description, t.Help, p.IsReport, p.ShowHelp "
+ "FROM AD_Process p, AD_Process_Trl t "
+ "WHERE p.AD_Process_ID=t.AD_Process_ID"
+ " AND p.AD_Process_ID=? AND t.AD_Language=?";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(sql, null);
pstmt.setInt(1, AD_Process_ID);
if (trl)
pstmt.setString(2, Env.getAD_Language(m_ctx));
rs = pstmt.executeQuery();
if (rs.next())
{
m_Name = rs.getString(1);
m_ShowHelp = rs.getString(5);
//
m_messageText.append("<b>");
String s = rs.getString(2); // Description
if (rs.wasNull())
m_messageText.append(Msg.getMsg(m_ctx, "StartProcess?"));
else
m_messageText.append(s);
m_messageText.append("</b>");
s = rs.getString(3); // Help
if (!rs.wasNull())
m_messageText.append("<p>").append(s).append("</p>");
}
}
catch (SQLException e)
{
log.log(Level.SEVERE, sql, e);
return false;
}
finally
{
DB.close(rs, pstmt);
}
if (m_Name == null)
return false;
//
this.setTitle(m_Name);
initialMessage = m_messageText.toString();
message.setContent(initialMessage);
// Move from APanel.actionButton
if (m_pi == null)
m_pi = new WProcessInfo(m_Name, AD_Process_ID);
m_pi.setAD_User_ID (Env.getAD_User_ID(Env.getCtx()));
m_pi.setAD_Client_ID(Env.getAD_Client_ID(Env.getCtx()));
m_pi.setTitle(m_Name);
parameterPanel = new ProcessParameterPanel(m_WindowNo, m_pi, innerWidth);
centerPanel.getChildren().clear();
if ( parameterPanel.init() ) {
centerPanel.appendChild(parameterPanel);
} else {
if (m_ShowHelp != null && m_ShowHelp.equals("N"))
autoStart = true;
if (autoStart)
{
autoStart();
return true;
}
}
// Check if the process is a silent one
if (isValid() && m_ShowHelp != null && m_ShowHelp.equals("S"))
{
autoStart();
return true;
}
MProcess process = new MProcess(m_ctx, m_AD_Process_ID, null);
boolean isReport = (process.isReport() || process.getAD_ReportView_ID() > 0);
if (isReport && MSysConfig.getBooleanValue(MSysConfig.BACKGROUND_JOB_ALLOWED, false))
{
Grid grid = GridFactory.newGridLayout();
centerPanel.appendChild(grid);
grid.setInnerWidth(innerWidth);
Columns columns = new Columns();
grid.appendChild(columns);
Column col = new Column();
col.setWidth("30%");
columns.appendChild(col);
col = new Column();
col.setWidth("70%");
columns.appendChild(col);
Rows rows = new Rows();
grid.appendChild(rows);
Row row = new Row();
rows.appendChild(row);
row.appendChild(new Space());
runAsJobField = new Checkbox();
runAsJobField.setLabel(Msg.getElement(m_ctx, MPInstance.COLUMNNAME_IsRunAsJob));
row.appendChild(runAsJobField);
runAsJobField.addEventListener(Events.ON_CHECK, this);
row = new Row();
rows.appendChild(row);
Div div = new Div();
div.setStyle("text-align: right;");
div.appendChild(new Label(Msg.getElement(m_ctx, MPInstance.COLUMNNAME_NotificationType)));
row.appendChild(div);
MLookupInfo info = MLookupFactory.getLookup_List(Env.getLanguage(m_ctx), MPInstance.NOTIFICATIONTYPE_AD_Reference_ID);
notificationTypeField = new WTableDirEditor(MPInstance.COLUMNNAME_NotificationType, true, false, true, new MLookup(info, 0));
Combobox combobox = notificationTypeField.getComponent();
List<?> items = combobox.getItems();
for (int i = 0; i < items.size(); i++) {
ComboItem item = (ComboItem)items.get(i);
if (MPInstance.NOTIFICATIONTYPE_None.equals(item.getValue()))
combobox.removeItemAt(i);
}
MUser user = MUser.get(m_ctx);
String notificationType = user.getNotificationType();
if (!MPInstance.NOTIFICATIONTYPE_None.equals(notificationType))
notificationTypeField.setValue(notificationType);
row.appendChild(notificationTypeField.getComponent());
runAsJobField.setChecked(MSysConfig.getBooleanValue(MSysConfig.BACKGROUND_JOB_BY_DEFAULT, false));
notificationTypeField.getComponent().getParent().setVisible(runAsJobField.isChecked());
}
return true;
}
protected void autoStart()
{
startProcess0();
}
public void onEvent(Event event)
{
Component component = event.getTarget();
if (component == runAsJobField && event.getName().equals(Events.ON_CHECK))
notificationTypeField.getComponent().getParent().setVisible(runAsJobField.isChecked());
else if (event.getName().equals(ON_COMPLETE))
onComplete();
else if (event.getName().equals(ON_STATUS_UPDATE))
onStatusUpdate(event);
}
protected void startProcess()
{
if (!parameterPanel.validateParameters())
return;
startProcess0();
}
protected void cancelProcess()
{
m_cancel = true;
this.dispose();
}
protected BusyDialog createBusyDialog()
{
progressWindow = new BusyDialog();
this.appendChild(progressWindow);
return progressWindow;
}
protected void closeBusyDialog()
{
if (progressWindow != null) {
progressWindow.dispose();
progressWindow = null;
}
}
@Override
public void dispose()
{
m_valid = false;
} // dispose
private void startProcess0()
{
if (!isBackgroundJob())
getProcessInfo().setPrintPreview(true);
lockUI(getProcessInfo());
downloadFiles = new ArrayList<File>();
//use echo, otherwise lock ui wouldn't work
Clients.response(new AuEcho(this, isBackgroundJob() ? "runBackgroundJob" : "runProcess", this));
}
public void runProcess()
{
future = Adempiere.getThreadPoolExecutor().submit(new DesktopRunnable(new ProcessDialogRunnable(null), getDesktop()));
}
public void runBackgroundJob()
{
Properties m_ctx = getCtx();
ProcessInfo m_pi = getProcessInfo();
MPInstance instance = null;
try
{
int AD_Client_ID = Env.getAD_Client_ID(m_ctx);
int AD_User_ID = Env.getAD_User_ID(m_ctx);
int count = new Query(m_ctx, MPInstance.Table_Name, "NVL(AD_User_ID,0)=? AND IsProcessing='Y'", null)
.setOnlyActiveRecords(true)
.setClient_ID()
.setParameters(AD_User_ID)
.count();
if (count >= MSysConfig.getIntValue(MSysConfig.BACKGROUND_JOB_MAX_PER_USER, 5, AD_Client_ID))
throw new IllegalStateException(Msg.getMsg(m_ctx, "BackgroundJobExceedMaxPerUser"));
count = new Query(m_ctx, MPInstance.Table_Name, "IsProcessing='Y'", null)
.setOnlyActiveRecords(true)
.setClient_ID()
.count();
if (count >= MSysConfig.getIntValue(MSysConfig.BACKGROUND_JOB_MAX_PER_CLIENT, 10, AD_Client_ID))
throw new IllegalStateException(Msg.getMsg(m_ctx, "BackgroundJobExceedMaxPerClient"));
count = new Query(m_ctx, MPInstance.Table_Name, "IsProcessing='Y'", null)
.setOnlyActiveRecords(true)
.count();
if (count >= MSysConfig.getIntValue(MSysConfig.BACKGROUND_JOB_MAX_IN_SYSTEM, 20))
throw new IllegalStateException(Msg.getMsg(m_ctx, "BackgroundJobExceedMaxInSystem"));
instance = new MPInstance(m_ctx, m_pi.getAD_Process_ID(), m_pi.getRecord_ID());
instance.setIsRunAsJob(true);
instance.setIsProcessing(true);
instance.setNotificationType(getNotificationType());
instance.saveEx();
m_pi.setAD_PInstance_ID(instance.getAD_PInstance_ID());
getParameterPanel().saveParameters();
MPInstance.publishChangedEvent(AD_User_ID);
Adempiere.getThreadPoolExecutor().schedule(new BackgroundJobRunnable(getCtx()), 1000, TimeUnit.MILLISECONDS);
m_pi.setSummary(Msg.getMsg(m_ctx, "BackgroundJobScheduled"));
} catch (Exception e) {
m_pi.setSummary(e.getLocalizedMessage());
m_pi.setError(true);
if (instance != null)
{
instance.setIsProcessing(false);
instance.saveEx();
}
}
finally {
unlockUI(m_pi);
if (m_disposeOnComplete)
dispose();
}
}
private void onComplete()
{
ProcessInfo m_pi = getProcessInfo();
if (future != null) {
try {
future.get();
} catch (Exception e) {
log.log(Level.SEVERE, e.getLocalizedMessage(), e);
if (!m_pi.isError()) {
m_pi.setSummary(e.getLocalizedMessage(), true);
}
}
}
future = null;
unlockUI(m_pi);
if (downloadFiles.size() > 0) {
MultiFileDownloadDialog downloadDialog = new MultiFileDownloadDialog(downloadFiles.toArray(new File[0]));
downloadDialog.setPage(getPage());
downloadDialog.setTitle(m_pi.getTitle());
Events.postEvent(downloadDialog, new Event(MultiFileDownloadDialog.ON_SHOW));
}
if (m_disposeOnComplete)
dispose();
}
private void onStatusUpdate(Event event)
{
String message = (String) event.getData();
if (progressWindow != null)
progressWindow.statusUpdate(message);
}
@Override
public void lockUI(ProcessInfo pi) {
if (m_locked || Executions.getCurrent() == null)
return;
m_locked = true;
showBusyDialog();
}
public abstract void showBusyDialog();
@Override
public void unlockUI(ProcessInfo pi) {
if (!m_locked)
return;
m_locked = false;
if (Executions.getCurrent() == null)
{
Executions.schedule(getDesktop(), new EventListener<Event>()
{
@Override
public void onEvent(Event event) throws Exception {
doUnlockUI();
}
}, new Event("onUnLockUI"));
} else {
doUnlockUI();
}
}
private void doUnlockUI()
{
hideBusyDialog();
updateUI();
}
public abstract void hideBusyDialog();
public abstract void updateUI();
@Override
public boolean isUILocked() {
return m_locked;
}
@Override
public void statusUpdate(String message) {
Desktop desktop = getDesktop();
if (desktop != null && desktop.isAlive())
Executions.schedule(desktop, this, new Event(ON_STATUS_UPDATE, this, message));
}
@Override
public void ask(final String message, final Callback<Boolean> callback) {
Executions.schedule(getDesktop(), new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
FDialog.ask(getWindowNo(), null, message, callback);
}
}, new Event("onAsk"));
}
@Override
public void download(File file) {
downloadFiles.add(file);
}
/**
*
* @return ProcessInfo
*/
public ProcessInfo getProcessInfo() {
return m_pi;
}
public void setProcessInfo(ProcessInfo pi) {
m_pi = pi;
}
/**
* is dialog still valid
* @return boolean
*/
public boolean isValid()
{
return m_valid;
}
/**
* @return true if user have press the cancel button to close the dialog
*/
public boolean isCancel()
{
return m_cancel;
}
public Properties getCtx()
{
return m_ctx;
}
public int getWindowNo()
{
return m_WindowNo;
}
public int getAD_Process_ID()
{
return m_AD_Process_ID;
}
public Html getMessage()
{
return message;
}
public Panel getCenterPanel()
{
return centerPanel;
}
public ProcessParameterPanel getParameterPanel()
{
return parameterPanel;
}
public String getName()
{
return m_Name;
}
public StringBuffer getMessageText()
{
return m_messageText;
}
public void setMessageText(StringBuffer messageText)
{
this.m_messageText = messageText;
}
public String getShowHelp()
{
return m_ShowHelp;
}
public String getInitialMessage()
{
return initialMessage;
}
public boolean isBackgroundJob()
{
return runAsJobField != null && runAsJobField.isChecked();
}
public String getNotificationType()
{
return (String) notificationTypeField.getValue();
}
public List<File> getDownloadFiles()
{
return downloadFiles;
}
private class ProcessDialogRunnable extends ContextRunnable
{
private Trx m_trx;
private ProcessDialogRunnable(Trx trx)
{
super();
m_trx = trx;
}
protected void doRun()
{
ProcessInfo m_pi = getProcessInfo();
try {
if (log.isLoggable(Level.INFO))
log.log(Level.INFO, "Process Info=" + m_pi + " AD_Client_ID="+ Env.getAD_Client_ID(Env.getCtx()));
WProcessCtl.process(AbstractProcessDialog.this, getWindowNo(), getParameterPanel(), m_pi, m_trx);
} catch (Exception ex) {
m_pi.setError(true);
m_pi.setSummary(ex.getLocalizedMessage());
log.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
} finally {
Executions.schedule(getDesktop(), AbstractProcessDialog.this, new Event(ON_COMPLETE, AbstractProcessDialog.this, null));
}
}
}
private class BackgroundJobRunnable implements Runnable
{
private Properties m_ctx;
private BackgroundJobRunnable(Properties ctx)
{
super();
m_ctx = new Properties();
Env.setContext(m_ctx, "#AD_Client_ID", ctx.getProperty("#AD_Client_ID"));
Env.setContext(m_ctx, "#AD_Org_ID", ctx.getProperty("#AD_Org_ID"));
Env.setContext(m_ctx, "#AD_Role_ID", ctx.getProperty("#AD_Role_ID"));
Env.setContext(m_ctx, "#M_Warehouse_ID", ctx.getProperty("#M_Warehouse_ID"));
Env.setContext(m_ctx, "#AD_Language", ctx.getProperty("#AD_Language"));
Env.setContext(m_ctx, "#AD_User_ID", ctx.getProperty("#AD_User_ID"));
Env.setContext(m_ctx, "#Date", ctx.getProperty("#Date"));
}
@Override
public void run() {
try {
ServerContext.setCurrentInstance(m_ctx);
doRun();
} finally {
ServerContext.dispose();
}
}
private void doRun()
{
ProcessInfo m_pi = getProcessInfo();
m_pi.setIsBatch(true);
MPInstance instance = new MPInstance(m_ctx, m_pi.getAD_PInstance_ID(), null);
String notificationType = instance.getNotificationType();
boolean sendEmail = notificationType.equals(MPInstance.NOTIFICATIONTYPE_EMail) || notificationType.equals(MPInstance.NOTIFICATIONTYPE_EMailPlusNotice);
boolean createNotice = notificationType.equals(MPInstance.NOTIFICATIONTYPE_Notice) || notificationType.equals(MPInstance.NOTIFICATIONTYPE_EMailPlusNotice);
int AD_Client_ID = Env.getAD_Client_ID(m_ctx);
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);
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)
{
ReportEngine re = ReportEngine.get(m_ctx, m_pi);
if(re != null && re.getPrintFormat().getJasperProcess_ID() > 0)
{
ProcessInfo jasperpi = new ProcessInfo ("", re.getPrintFormat().getJasperProcess_ID());
jasperpi.setIsBatch(true);
ServerProcessCtl.process(jasperpi, null);
File report = jasperpi.getPDFReport();
if (report != null)
download(report);
}
else if (process.getJasperReport() != null)
{
download(m_pi.getPDFReport());
}
else
{
if (re == null)
log.log(Level.SEVERE, "Cannot create Report AD_Process_ID=" + process.getAD_Process_ID() + " - " + process.getName());
else
{
File report = re.getPDF();
if (report != null)
download(report);
}
}
}
File generatedFile = m_pi.isExport() ? m_pi.getExportFile() : m_pi.getPDFReport();
if (generatedFile != null)
download(generatedFile);
}
if (sendEmail)
{
MClient client = MClient.get(m_ctx, AD_Client_ID);
client.sendEMailAttachments(AD_User_ID, process.getName(), m_pi.getSummary() + " " + m_pi.getLogInfo(), getDownloadFiles());
}
if (createNotice)
{
MNote note = new MNote(m_ctx, "BackgroundJob", AD_User_ID, null);
note.setTextMsg(process.getName() + "\n" + m_pi.getSummary());
note.setRecord(MPInstance.Table_ID, m_pi.getAD_PInstance_ID());
note.saveEx();
MAttachment attachment = null;
if (getDownloadFiles().size() > 0)
{
attachment = note.createAttachment();
for (File downloadFile : getDownloadFiles())
attachment.addEntry(downloadFile);
}
String log = m_pi.getLogInfo(true);
if (log != null && log.trim().length() > 0) {
if (attachment == null)
attachment = note.createAttachment();
attachment.addEntry("ProcessLog.html", log.getBytes("UTF-8"));
}
if (attachment != null)
attachment.saveEx();
}
} catch (Exception e) {
log.log(Level.SEVERE, e.getLocalizedMessage());
} finally {
instance.setIsProcessing(false);
instance.saveEx();
MPInstance.publishChangedEvent(AD_User_ID);
}
}
}
}

View File

@ -1,91 +1,3 @@
package org.adempiere.webui.apps;
import static org.compiere.model.SystemIDs.PROCESS_C_INVOICE_GENERATE;
import static org.compiere.model.SystemIDs.PROCESS_M_INOUT_GENERATE;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Future;
import java.util.logging.Level;
import org.adempiere.util.Callback;
import org.adempiere.util.ContextRunnable;
import org.adempiere.util.IProcessUI;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.Combobox;
import org.adempiere.webui.component.ConfirmPanel;
import org.adempiere.webui.component.Grid;
import org.adempiere.webui.component.GridFactory;
import org.adempiere.webui.component.Label;
import org.adempiere.webui.component.Mask;
import org.adempiere.webui.component.Panel;
import org.adempiere.webui.component.Rows;
import org.adempiere.webui.component.Window;
import org.adempiere.webui.desktop.IDesktop;
import org.adempiere.webui.factory.ButtonFactory;
import org.adempiere.webui.panel.IHelpContext;
import org.adempiere.webui.part.WindowContainer;
import org.adempiere.webui.process.WProcessInfo;
import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.window.FDialog;
import org.adempiere.webui.window.MultiFileDownloadDialog;
import org.adempiere.webui.window.SimplePDFViewer;
import org.compiere.Adempiere;
import org.compiere.model.MPInstance;
import org.compiere.model.MPInstancePara;
import org.compiere.model.MProcess;
import org.compiere.model.X_AD_CtxHelp;
import org.compiere.print.ReportEngine;
import org.compiere.process.ProcessInfo;
import org.compiere.process.ProcessInfoLog;
import org.compiere.process.ProcessInfoUtil;
import org.compiere.util.AdempiereSystemError;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Util;
import org.zkoss.zhtml.Table;
import org.zkoss.zhtml.Td;
import org.zkoss.zhtml.Text;
import org.zkoss.zhtml.Tr;
import org.zkoss.zk.au.out.AuEcho;
import org.zkoss.zk.au.out.AuScript;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.A;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Center;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.Div;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Html;
import org.zkoss.zul.North;
import org.zkoss.zul.Row;
import org.zkoss.zul.South;
import com.lowagie.text.Document;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfWriter;
/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 2007 Low Heng Sin *
@ -100,8 +12,80 @@ import com.lowagie.text.pdf.PdfWriter;
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.webui.apps;
import static org.compiere.model.SystemIDs.PROCESS_C_INVOICE_GENERATE;
import static org.compiere.model.SystemIDs.PROCESS_M_INOUT_GENERATE;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.adempiere.util.Callback;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.Combobox;
import org.adempiere.webui.component.ConfirmPanel;
import org.adempiere.webui.component.Grid;
import org.adempiere.webui.component.GridFactory;
import org.adempiere.webui.component.Mask;
import org.adempiere.webui.component.Panel;
import org.adempiere.webui.component.Row;
import org.adempiere.webui.component.Rows;
import org.adempiere.webui.component.Window;
import org.adempiere.webui.desktop.IDesktop;
import org.adempiere.webui.factory.ButtonFactory;
import org.adempiere.webui.panel.IHelpContext;
import org.adempiere.webui.part.WindowContainer;
import org.adempiere.webui.process.WProcessInfo;
import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.window.FDialog;
import org.adempiere.webui.window.SimplePDFViewer;
import org.compiere.model.MPInstance;
import org.compiere.model.MPInstancePara;
import org.compiere.model.MProcess;
import org.compiere.model.X_AD_CtxHelp;
import org.compiere.print.ReportEngine;
import org.compiere.process.ProcessInfo;
import org.compiere.process.ProcessInfoLog;
import org.compiere.process.ProcessInfoUtil;
import org.compiere.util.AdempiereSystemError;
import org.compiere.util.CLogger;
import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Util;
import org.zkoss.zhtml.Table;
import org.zkoss.zhtml.Td;
import org.zkoss.zhtml.Text;
import org.zkoss.zhtml.Tr;
import org.zkoss.zk.au.out.AuEcho;
import org.zkoss.zk.au.out.AuScript;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.A;
import org.zkoss.zul.Borderlayout;
import org.zkoss.zul.Center;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.Div;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Label;
import org.zkoss.zul.North;
import org.zkoss.zul.South;
import com.lowagie.text.Document;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfWriter;
/**
* Dialog to Start process or report.
@ -113,20 +97,29 @@ import com.lowagie.text.pdf.PdfWriter;
* @author arboleda - globalqss
* - Implement ShowHelp option on processes and reports
*/
public class ProcessDialog extends Window implements EventListener<Event>, IProcessUI, IHelpContext
public class ProcessDialog extends AbstractProcessDialog implements EventListener<Event>, IHelpContext
{
/**
*
* generate serial version ID
*/
private static final long serialVersionUID = -899849696748614034L;
private static final long serialVersionUID = 3329046204196602797L;
private static final String MESSAGE_DIV_STYLE = "max-height: 150pt; overflow: auto; margin: 10px;";
/** Logger */
private static CLogger log = CLogger.getCLogger(ProcessDialog.class);
//
private Div messageDiv;
private Center center;
private Table logMessageTable;
private North north;
private List<File> downloadFiles;
private int[] m_ids = null;
private Button bOK = null;
private boolean isParameterPage = true;
private Mask mask;
private boolean showLastRun = false;
@ -147,20 +140,19 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
public ProcessDialog (int AD_Process_ID, boolean isSOTrx)
{
log.info("Process=" + AD_Process_ID );
m_ctx = Env.getCtx();
m_WindowNo = SessionManager.getAppDesktop().registerWindow(this);
this.setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, m_WindowNo);
m_AD_Process_ID = AD_Process_ID;
Env.setContext(Env.getCtx(), m_WindowNo, "IsSOTrx", isSOTrx ? "Y" : "N");
int WindowNo = SessionManager.getAppDesktop().registerWindow(this);
this.setAttribute(IDesktop.WINDOWNO_ATTRIBUTE, WindowNo);
Env.setContext(Env.getCtx(), WindowNo, "IsSOTrx", isSOTrx ? "Y" : "N");
try
{
MProcess process = new MProcess(m_ctx, m_AD_Process_ID, null);
MProcess process = MProcess.get(Env.getCtx(), AD_Process_ID);
int count = process.getParameters().length;
if (count > 0)
showLastRun = true;
initComponents();
init();
init(Env.getCtx(), WindowNo, AD_Process_ID, null, "70%", false, false);
querySaved();
addEventListener(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT, this);
}
catch(Exception ex)
@ -169,13 +161,26 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
}
} // ProcessDialog
private void querySaved()
{
//user query
savedParams = MPInstance.get(Env.getCtx(), getAD_Process_ID(), Env.getContextAsInt(Env.getCtx(), "#AD_User_ID"));
fSavedName.removeAllItems();
for (MPInstance instance : savedParams)
{
String queries = instance.get_ValueAsString("Name");
fSavedName.appendItem(queries);
}
fSavedName.setValue("");
}
private void initComponents() {
this.setStyle("position: absolute; width: 100%; height: 100%");
Borderlayout layout = new Borderlayout();
layout.setStyle("position: absolute; width: 100%; height: 100%; border: none;");
messageDiv = new Div();
message = new Html();
messageDiv.appendChild(message);
messageDiv.appendChild(getMessage());
messageDiv.setStyle(MESSAGE_DIV_STYLE);
messageDiv.setId("message");
@ -185,12 +190,11 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
north.setAutoscroll(true);
north.setStyle("border: none;");
centerPanel = new Panel();
center = new Center();
layout.appendChild(center);
center.appendChild(centerPanel);
centerPanel.setHflex("1");
centerPanel.setVflex("1");
center.appendChild(getCenterPanel());
getCenterPanel().setHflex("1");
getCenterPanel().setVflex("1");
center.setAutoscroll(true);
center.setStyle("border: none");
@ -199,6 +203,7 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
Hbox hBox = new Hbox();
lSaved = new Label(Msg.getMsg(Env.getCtx(), "SavedParameter"));
hBox.appendChild(lSaved);
fSavedName.addEventListener(Events.ON_CHANGE, this);
hBox.appendChild(fSavedName);
@ -218,8 +223,6 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
Panel confParaPanel =new Panel();
confParaPanel.setAlign("right");
@SuppressWarnings("unused")
String label = Msg.getMsg(Env.getCtx(), "Start");
// Invert - Unify OK/Cancel IDEMPIERE-77
bOK = ButtonFactory.createNamedButton(ConfirmPanel.A_OK, true, true);
bOK.setId("Ok");
@ -239,45 +242,14 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
this.appendChild(layout);
}
private int m_WindowNo;
private Properties m_ctx;
private int m_AD_Process_ID;
private String m_Name = null;
private int[] m_ids = null;
private StringBuffer m_messageText = new StringBuffer();
private String m_ShowHelp = null; // Determine if a Help Process Window is shown
private Panel centerPanel = null;
private Html message = null;
private Button bOK = null;
private Button bCancel = null;
private boolean valid = true;
/** Logger */
private static CLogger log = CLogger.getCLogger(ProcessDialog.class);
//
private ProcessParameterPanel parameterPanel = null;
private ProcessInfo m_pi = null;
private boolean m_isLocked = false;
private boolean isParameterPage = true;
private String initialMessage;
private BusyDialog progressWindow;
private Future<?> future;
private ProcessDialogRunnable processDialogRunnable;
private Mask mask;
private static final String ON_STATUS_UPDATE = "onStatusUpdate";
private static final String ON_COMPLETE = "onComplete";
//saved parameters
private Combobox fSavedName=new Combobox();
private Button bSave=ButtonFactory.createNamedButton("Save");
private Button bDelete=ButtonFactory.createNamedButton("Delete");
private List<MPInstance> savedParams;
private Label lSaved=new Label(Msg.getMsg(Env.getCtx(), "SavedParameter"));
private Label lSaved;
/**
* Set Visible
@ -294,154 +266,10 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
*/
public void dispose()
{
SessionManager.getAppDesktop().closeWindow(m_WindowNo);
valid = false;
super.dispose();
SessionManager.getAppDesktop().closeWindow(getWindowNo());
}// dispose
/**
* Dynamic Init
* @return true, if there is something to process (start from menu)
*/
public boolean init()
{
log.config("");
//
boolean trl = !Env.isBaseLanguage(m_ctx, "AD_Process");
String sql = "SELECT Name, Description, Help, IsReport, ShowHelp "
+ "FROM AD_Process "
+ "WHERE AD_Process_ID=?";
if (trl)
sql = "SELECT t.Name, t.Description, t.Help, p.IsReport, p.ShowHelp "
+ "FROM AD_Process p, AD_Process_Trl t "
+ "WHERE p.AD_Process_ID=t.AD_Process_ID"
+ " AND p.AD_Process_ID=? AND t.AD_Language=?";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(sql, null);
pstmt.setInt(1, m_AD_Process_ID);
if (trl)
pstmt.setString(2, Env.getAD_Language(m_ctx));
rs = pstmt.executeQuery();
if (rs.next())
{
m_Name = rs.getString(1);
m_ShowHelp = rs.getString(5);
//
m_messageText.append("<b>");
String s = rs.getString(2); // Description
if (rs.wasNull())
m_messageText.append(Msg.getMsg(m_ctx, "StartProcess?"));
else
m_messageText.append(s);
m_messageText.append("</b>");
s = rs.getString(3); // Help
if (!rs.wasNull())
m_messageText.append("<p>").append(s).append("</p>");
}
}
catch (SQLException e)
{
log.log(Level.SEVERE, sql, e);
return false;
}
finally
{
DB.close(rs, pstmt);
}
if (m_Name == null)
return false;
//
this.setTitle(m_Name);
initialMessage = m_messageText.toString();
message.setContent(initialMessage);
bOK.setLabel(Msg.getMsg(Env.getCtx(), "Start"));
// Move from APanel.actionButton
m_pi = new WProcessInfo(m_Name, m_AD_Process_ID);
m_pi.setAD_User_ID (Env.getAD_User_ID(Env.getCtx()));
m_pi.setAD_Client_ID(Env.getAD_Client_ID(Env.getCtx()));
parameterPanel = new ProcessParameterPanel(m_WindowNo, m_pi, "70%");
centerPanel.getChildren().clear();
if ( parameterPanel.init() ) {
centerPanel.appendChild(parameterPanel);
} else {
if (m_ShowHelp != null && m_ShowHelp.equals("N")) {
startProcess();
}
}
// Check if the process is a silent one
if(m_ShowHelp != null && m_ShowHelp.equals("S"))
{
startProcess();
}
querySaved();
return true;
} // init
private void querySaved()
{
//user query
savedParams = MPInstance.get(Env.getCtx(), m_AD_Process_ID, Env.getContextAsInt(Env.getCtx(), "#AD_User_ID"));
fSavedName.removeAllItems();
for (MPInstance instance : savedParams)
{
String queries = instance.get_ValueAsString("Name");
fSavedName.appendItem(queries);
}
fSavedName.setValue("");
}
public void startProcess()
{
m_pi.setPrintPreview(true);
this.lockUI(m_pi);
downloadFiles = new ArrayList<File>();
Clients.response(new AuEcho(this, "runProcess", null));
}
public void runProcess() {
processDialogRunnable = new ProcessDialogRunnable();
future = Adempiere.getThreadPoolExecutor().submit(new DesktopRunnable(processDialogRunnable, getDesktop()));
}
private void onComplete() {
if (future != null) {
try {
future.get();
} catch (Exception e) {
log.log(Level.SEVERE, e.getLocalizedMessage(), e);
if (!m_pi.isError()) {
m_pi.setSummary(e.getLocalizedMessage(), true);
}
}
}
future = null;
processDialogRunnable = null;
unlockUI(m_pi);
if (downloadFiles.size() > 0) {
MultiFileDownloadDialog downloadDialog = new MultiFileDownloadDialog(downloadFiles.toArray(new File[0]));
downloadDialog.setPage(this.getPage());
downloadDialog.setTitle(m_pi.getTitle());
Events.postEvent(downloadDialog, new Event(MultiFileDownloadDialog.ON_SHOW));
}
}
private void onStatusUpdate(Event event) {
String message = (String) event.getData();
if (progressWindow != null)
progressWindow.statusUpdate(message);
}
public void onEvent(Event event) {
Component component = event.getTarget();
@ -457,15 +285,13 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
} else if (component instanceof Button) {
Button element = (Button)component;
if ("Ok".equalsIgnoreCase(element.getId())) {
if (isParameterPage) {
if (!parameterPanel.validateParameters())
return;
this.startProcess();
}
if (isParameterPage)
startProcess();
else
restart();
} else if ("Cancel".equalsIgnoreCase(element.getId())) {
this.dispose();
cancelProcess();
} else if (event.getTarget().equals(bSave) && fSavedName != null
&& !lastRun) {
@ -473,13 +299,13 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
if (fSavedName.getSelectedIndex() > -1 && savedParams != null) {
for (int i = 0; i < savedParams.size(); i++) {
if (savedParams.get(i).getName().equals(saveName)) {
m_pi.setAD_PInstance_ID(savedParams.get(i)
getProcessInfo().setAD_PInstance_ID(savedParams.get(i)
.getAD_PInstance_ID());
for (MPInstancePara para : savedParams.get(i)
.getParameters()) {
para.deleteEx(true);
}
parameterPanel.saveParameters();
getParameterPanel().saveParameters();
}
}
}
@ -488,13 +314,13 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
MPInstance instance = null;
try {
instance = new MPInstance(Env.getCtx(),
m_pi.getAD_Process_ID(), m_pi.getRecord_ID());
getProcessInfo().getAD_Process_ID(), getProcessInfo().getRecord_ID());
instance.setName(saveName);
instance.saveEx();
m_pi.setAD_PInstance_ID(instance.getAD_PInstance_ID());
getProcessInfo().setAD_PInstance_ID(instance.getAD_PInstance_ID());
// Get Parameters
if (parameterPanel != null) {
if (!parameterPanel.saveParameters()) {
if (getParameterPanel() != null) {
if (!getParameterPanel().saveParameters()) {
throw new AdempiereSystemError(Msg.getMsg(
Env.getCtx(), "SaveParameterError"));
}
@ -520,12 +346,8 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
}
querySaved();
}
} else if (event.getName().equals(ON_STATUS_UPDATE)) {
onStatusUpdate(event);
} else if (event.getName().equals(ON_COMPLETE)) {
onComplete();
} else if (event.getName().equals(WindowContainer.ON_WINDOW_CONTAINER_SELECTION_CHANGED_EVENT)) {
SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Process, m_AD_Process_ID);
SessionManager.getAppDesktop().updateHelpContext(X_AD_CtxHelp.CTXTYPE_Process, getAD_Process_ID());
} else if (event.getTarget().equals(fSavedName)) {
if (savedParams != null && saveName != null) {
for (int i = 0; i < savedParams.size(); i++) {
@ -538,6 +360,8 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
bSave.setEnabled(enabled && !lastRun);
bDelete.setEnabled(enabled && fSavedName.getSelectedIndex() > -1
&& !lastRun);
} else {
super.onEvent(event);
}
}
@ -555,7 +379,7 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
}
private void loadSavedParams(MPInstance instance) {
parameterPanel.loadParameters(instance);
getParameterPanel().loadParameters(instance);
}
private void doOnClick(A btn) {
@ -575,19 +399,10 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
}
}
public void lockUI(ProcessInfo pi) {
if (m_isLocked || Executions.getCurrent() == null) return;
m_isLocked = true;
showBusyDialog();
}
private void showBusyDialog() {
progressWindow = new BusyDialog();
@Override
public void showBusyDialog() {
BusyDialog progressWindow = createBusyDialog();
progressWindow.setStyle("position: absolute;");
this.appendChild(progressWindow);
showBusyMask(progressWindow);
LayoutUtils.openOverlappedWindow(this, progressWindow, "middle_center");
}
@ -599,7 +414,7 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
return mask;
}
public void showBusyMask(Window window) {
private void showBusyMask(Window window) {
getParent().appendChild(getMask());
StringBuilder script = new StringBuilder("var w=zk.Widget.$('#");
script.append(getParent().getUuid()).append("');");
@ -611,15 +426,8 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
Clients.response(new AuScript(script.toString()));
}
public void unlockUI(ProcessInfo pi) {
if (!m_isLocked || Executions.getCurrent() == null) return;
m_isLocked = false;
hideBusyDialog();
updateUI(pi);
}
public void hideBusyMask() {
private void hideBusyMask()
{
if (mask != null && mask.getParent() != null) {
mask.detach();
StringBuilder script = new StringBuilder("var w=zk.Widget.$('#");
@ -628,20 +436,21 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
}
}
private void hideBusyDialog() {
@Override
public void hideBusyDialog()
{
hideBusyMask();
if (progressWindow != null) {
progressWindow.dispose();
progressWindow = null;
}
closeBusyDialog();
}
private void updateUI(ProcessInfo pi) {
@Override
public void updateUI() {
ProcessInfo pi = getProcessInfo();
ProcessInfoUtil.setLogFromDB(pi);
m_messageText.append("<p><font color=\"").append(pi.isError() ? "#FF0000" : "#0000FF").append("\">** ")
getMessageText().append("<p><font color=\"").append(pi.isError() ? "#FF0000" : "#0000FF").append("\">** ")
.append(pi.getSummary())
.append("</font></p>");
message.setContent(m_messageText.toString());
getMessage().setContent(getMessageText().toString());
// Add Log info with zoom on record id
appendRecordLogInfo(pi.getLogs());
@ -652,7 +461,7 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
m_ids = pi.getIDs();
//move message div to center to give more space to display potentially very long log info
centerPanel.detach();
getCenterPanel().detach();
messageDiv.detach();
messageDiv.setStyle("");
north.setVisible(false);
@ -747,8 +556,8 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
}
private void restart() {
m_messageText = new StringBuffer(initialMessage);
message.setContent(initialMessage);
setMessageText(new StringBuffer(getInitialMessage()));
getMessage().setContent(getInitialMessage());
north.setVisible(true);
messageDiv.detach();
@ -758,7 +567,7 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
messageDiv.setStyle(MESSAGE_DIV_STYLE);
north.appendChild(messageDiv);
center.appendChild(centerPanel);
center.appendChild(getCenterPanel());
isParameterPage = true;
@ -766,10 +575,11 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
bOK.setImage(ThemeManager.getThemeResource("images/Ok16.png"));
//recreate process info
m_pi = new WProcessInfo(m_Name, m_AD_Process_ID);
ProcessInfo m_pi = new WProcessInfo(getName(), getAD_Process_ID());
m_pi.setAD_User_ID (Env.getAD_User_ID(Env.getCtx()));
m_pi.setAD_Client_ID(Env.getAD_Client_ID(Env.getCtx()));
parameterPanel.setProcessInfo(m_pi);
setProcessInfo(m_pi);
getParameterPanel().setProcessInfo(m_pi);
m_ids = null;
@ -781,7 +591,7 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
//
if (!afterProcessTask()) {
// If the process is a silent one and no errors occured, close the dialog
if(m_ShowHelp != null && m_ShowHelp.equals("S"))
if(getShowHelp() != null && getShowHelp().equals("S"))
this.dispose();
}
}
@ -796,12 +606,12 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
{
log.config("");
// Print invoices
if (m_AD_Process_ID == PROCESS_C_INVOICE_GENERATE)
if (getAD_Process_ID() == PROCESS_C_INVOICE_GENERATE)
{
printInvoices();
return true;
}
else if (m_AD_Process_ID == PROCESS_M_INOUT_GENERATE)
else if (getAD_Process_ID() == PROCESS_M_INOUT_GENERATE)
{
printShipments();
return true;
@ -821,12 +631,12 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
{
if (m_ids == null)
return;
FDialog.ask(m_WindowNo, this, "PrintShipments", new Callback<Boolean>() {
FDialog.ask(getWindowNo(), this, "PrintShipments", new Callback<Boolean>() {
@Override
public void onCallback(Boolean result) {
if (result) {
m_messageText.append("<p>").append(Msg.getMsg(Env.getCtx(), "PrintShipments")).append("</p>");
message.setContent(m_messageText.toString());
getMessageText().append("<p>").append(Msg.getMsg(Env.getCtx(), "PrintShipments")).append("</p>");
getMessage().setContent(getMessageText().toString());
showBusyDialog();
Clients.response(new AuEcho(ProcessDialog.this, "onPrintShipments", null));
}
@ -872,7 +682,7 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
document.close();
hideBusyDialog();
Window win = new SimplePDFViewer(m_pi.getTitle(), new FileInputStream(outFile));
Window win = new SimplePDFViewer(getProcessInfo().getTitle(), new FileInputStream(outFile));
SessionManager.getAppDesktop().showWindow(win, "center");
} catch (Exception e) {
log.log(Level.SEVERE, e.getLocalizedMessage(), e);
@ -883,7 +693,7 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
} else if (pdfList.size() > 0) {
hideBusyDialog();
try {
Window win = new SimplePDFViewer(m_pi.getTitle(), new FileInputStream(pdfList.get(0)));
Window win = new SimplePDFViewer(getProcessInfo().getTitle(), new FileInputStream(pdfList.get(0)));
SessionManager.getAppDesktop().showWindow(win, "center");
} catch (Exception e)
{
@ -892,7 +702,7 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
}
// If the process is a silent one and no errors occured, close the dialog
if(m_ShowHelp != null && m_ShowHelp.equals("S"))
if(getShowHelp() != null && getShowHelp().equals("S"))
this.dispose();
}
@ -903,14 +713,14 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
{
if (m_ids == null)
return;
FDialog.ask(m_WindowNo, this, "PrintInvoices", new Callback<Boolean>() {
FDialog.ask(getWindowNo(), this, "PrintInvoices", new Callback<Boolean>() {
@Override
public void onCallback(Boolean result)
{
if (result)
{
m_messageText.append("<p>").append(Msg.getMsg(Env.getCtx(), "PrintInvoices")).append("</p>");
message.setContent(m_messageText.toString());
getMessageText().append("<p>").append(Msg.getMsg(Env.getCtx(), "PrintInvoices")).append("</p>");
getMessage().setContent(getMessageText().toString());
showBusyDialog();
Clients.response(new AuEcho(ProcessDialog.this, "onPrintInvoices", null));
}
@ -954,7 +764,7 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
document.close();
hideBusyDialog();
Window win = new SimplePDFViewer(m_pi.getTitle(), new FileInputStream(outFile));
Window win = new SimplePDFViewer(getProcessInfo().getTitle(), new FileInputStream(outFile));
SessionManager.getAppDesktop().showWindow(win, "center");
} catch (Exception e) {
log.log(Level.SEVERE, e.getLocalizedMessage(), e);
@ -965,7 +775,7 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
} else if (pdfList.size() > 0) {
hideBusyDialog();
try {
Window win = new SimplePDFViewer(m_pi.getTitle(), new FileInputStream(pdfList.get(0)));
Window win = new SimplePDFViewer(getProcessInfo().getTitle(), new FileInputStream(pdfList.get(0)));
SessionManager.getAppDesktop().showWindow(win, "center");
} catch (Exception e)
{
@ -974,52 +784,8 @@ public class ProcessDialog extends Window implements EventListener<Event>, IProc
}
// If the process is a silent one and no errors occured, close the dialog
if(m_ShowHelp != null && m_ShowHelp.equals("S"))
if(getShowHelp() != null && getShowHelp().equals("S"))
this.dispose();
}
public boolean isValid() {
return valid;
}
public boolean isUILocked() {
return m_isLocked;
}
class ProcessDialogRunnable extends ContextRunnable {
ProcessDialogRunnable() {
super();
}
protected void doRun() {
try {
if (log.isLoggable(Level.INFO))log.log(Level.INFO, "Process Info="+m_pi+" AD_Client_ID="+Env.getAD_Client_ID(Env.getCtx()));
WProcessCtl.process(ProcessDialog.this, m_WindowNo, parameterPanel, m_pi, null);
} finally {
Executions.schedule(getDesktop(), ProcessDialog.this, new Event(ON_COMPLETE, ProcessDialog.this, null));
}
}
}
@Override
public void statusUpdate(String message) {
Desktop desktop = getDesktop();
if (desktop != null && desktop.isAlive())
Executions.schedule(desktop, this, new Event(ON_STATUS_UPDATE, this, message));
}
@Override
public void ask(final String message, final Callback<Boolean> callback) {
Executions.schedule(getDesktop(), new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
FDialog.ask(m_WindowNo, null, message, callback);
}
}, new Event("onAsk"));
}
@Override
public void download(File file) {
downloadFiles.add(file);
}
} // ProcessDialog

View File

@ -16,45 +16,24 @@
*****************************************************************************/
package org.adempiere.webui.apps;
import java.io.File;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Future;
import java.util.logging.Level;
import org.adempiere.util.Callback;
import org.adempiere.util.ContextRunnable;
import org.adempiere.util.IProcessUI;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.component.Button;
import org.adempiere.webui.component.ConfirmPanel;
import org.adempiere.webui.component.Panel;
import org.adempiere.webui.component.VerticalBox;
import org.adempiere.webui.component.Window;
import org.adempiere.webui.event.DialogEvents;
import org.adempiere.webui.factory.ButtonFactory;
import org.adempiere.webui.window.FDialog;
import org.adempiere.webui.window.MultiFileDownloadDialog;
import org.compiere.Adempiere;
import org.compiere.process.ProcessInfo;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.zkoss.zk.au.out.AuEcho;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Div;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Html;
import org.zkoss.zul.Vlayout;
/**
@ -68,20 +47,18 @@ import org.zkoss.zul.Vlayout;
* @author arboleda - globalqss
* - Implement ShowHelp option on processes and reports
*/
public class ProcessModalDialog extends Window implements EventListener<Event>, IProcessUI, DialogEvents
public class ProcessModalDialog extends AbstractProcessDialog implements EventListener<Event>, DialogEvents
{
/**
*
*/
private static final long serialVersionUID = -3708004619583382450L;
private static final long serialVersionUID = -3260639688339379279L;
private static final String ON_STATUS_UPDATE = "onStatusUpdate";
private static final String ON_COMPLETE = "onComplete";
private boolean m_autoStart;
private VerticalBox dialogBody;
private List<File> downloadFiles;
/** Logger */
private static CLogger log = CLogger.getCLogger(ProcessModalDialog.class);
//
/**
* @param aProcess
@ -102,10 +79,7 @@ public class ProcessModalDialog extends Window implements EventListener<Event>,
*/
public ProcessModalDialog(EventListener<Event> listener, int WindowNo, ProcessInfo pi, boolean autoStart)
{
m_ctx = Env.getCtx();
m_WindowNo = WindowNo;
m_pi = pi;
m_autoStart = autoStart;
super();
if (listener != null)
{
@ -116,7 +90,7 @@ public class ProcessModalDialog extends Window implements EventListener<Event>,
try
{
initComponents();
init();
init(Env.getCtx(), WindowNo, pi.getAD_Process_ID(), pi, "100%", autoStart, true);
}
catch(Exception ex)
{
@ -172,12 +146,10 @@ public class ProcessModalDialog extends Window implements EventListener<Event>,
dialogBody.appendChild(dialogContent);
Div div = new Div();
div.setId("message");
message = new Html();
div.appendChild(message);
div.appendChild(getMessage());
div.setStyle("max-height: 150pt; overflow: auto;");
dialogContent.appendChild(div);
centerPanel = new Panel();
dialogContent.appendChild(centerPanel);
dialogContent.appendChild(getCenterPanel());
Hbox hbox = new Hbox();
hbox.setWidth("100%");
hbox.setSclass("dialog-footer");
@ -198,28 +170,6 @@ public class ProcessModalDialog extends Window implements EventListener<Event>,
}
private int m_WindowNo;
private Properties m_ctx;
private String m_Name = null;
private StringBuffer m_messageText = new StringBuffer();
private String m_ShowHelp = null; // Determine if a Help Process Window is shown
private boolean m_valid = true;
private boolean m_cancel = false;
private Panel centerPanel = null;
private Html message = null;
/** Logger */
private static CLogger log = CLogger.getCLogger(ProcessModalDialog.class);
//
private ProcessParameterPanel parameterPanel = null;
private ProcessInfo m_pi = null;
private BusyDialog progressWindow;
private boolean isLocked = false;
private org.adempiere.webui.apps.ProcessModalDialog.ProcessDialogRunnable processDialogRunnable;
private Future<?> future;
/**
* Set Visible
* (set focus to OK if visible)
@ -235,156 +185,37 @@ public class ProcessModalDialog extends Window implements EventListener<Event>,
*/
public void dispose()
{
parameterPanel.restoreContext();
m_valid = false;
super.dispose();
getParameterPanel().restoreContext();
this.detach();
} // dispose
/**
* is dialog still valid
* @return boolean
*/
public boolean isValid()
@Override
public void autoStart()
{
return m_valid;
this.getFirstChild().setVisible(false);
super.autoStart();
}
/**
* @return true if user have press the cancel button to close the dialog
*/
public boolean isCancel()
{
return m_cancel;
}
/**
* Dynamic Init
* @return true, if there is something to process (start from menu)
*/
public boolean init()
{
log.config("");
//
boolean trl = !Env.isBaseLanguage(m_ctx, "AD_Process");
String sql = "SELECT Name, Description, Help, IsReport, ShowHelp "
+ "FROM AD_Process "
+ "WHERE AD_Process_ID=?";
if (trl)
sql = "SELECT t.Name, t.Description, t.Help, p.IsReport, p.ShowHelp "
+ "FROM AD_Process p, AD_Process_Trl t "
+ "WHERE p.AD_Process_ID=t.AD_Process_ID"
+ " AND p.AD_Process_ID=? AND t.AD_Language=?";
PreparedStatement pstmt = null;
ResultSet rs = null;
try
{
pstmt = DB.prepareStatement(sql, null);
pstmt.setInt(1, m_pi.getAD_Process_ID());
if (trl)
pstmt.setString(2, Env.getAD_Language(m_ctx));
rs = pstmt.executeQuery();
if (rs.next())
{
m_Name = rs.getString(1);
m_ShowHelp = rs.getString(5);
//
m_messageText.append("<b>");
String s = rs.getString(2); // Description
if (rs.wasNull())
m_messageText.append(Msg.getMsg(m_ctx, "StartProcess?"));
else
m_messageText.append(s);
m_messageText.append("</b>");
s = rs.getString(3); // Help
if (!rs.wasNull())
m_messageText.append("<p>").append(s).append("</p>");
}
}
catch (SQLException e)
{
log.log(Level.SEVERE, sql, e);
return false;
}
finally
{
DB.close(rs, pstmt);
}
if (m_Name == null)
return false;
//
this.setTitle(m_Name);
message.setContent(m_messageText.toString());
// Move from APanel.actionButton
m_pi.setAD_User_ID (Env.getAD_User_ID(Env.getCtx()));
m_pi.setAD_Client_ID(Env.getAD_Client_ID(Env.getCtx()));
m_pi.setTitle(m_Name);
parameterPanel = new ProcessParameterPanel(m_WindowNo, m_pi);
centerPanel.getChildren().clear();
if ( parameterPanel.init() ) {
centerPanel.appendChild(parameterPanel);
} else {
if (m_ShowHelp != null && m_ShowHelp.equals("N")) {
m_autoStart = true;
}
if (m_autoStart) {
this.getFirstChild().setVisible(false);
startProcess();
return true;
}
}
// Check if the process is a silent one
if(isValid() && m_ShowHelp != null && m_ShowHelp.equals("S"))
{
this.getFirstChild().setVisible(false);
startProcess();
}
return true;
} // init
/**
* launch process
*/
private void startProcess()
{
m_pi.setPrintPreview(true);
lockUI(m_pi);
downloadFiles = new ArrayList<File>();
//use echo, otherwise lock ui wouldn't work
Clients.response(new AuEcho(this, "runProcess", null));
}
private void showBusyDialog() {
@Override
public void showBusyDialog() {
this.setBorder("none");
this.setTitle(null);
dialogBody.setVisible(false);
progressWindow = new BusyDialog();
this.appendChild(progressWindow);
BusyDialog progressWindow = createBusyDialog();
if (this.getParent() != null)
LayoutUtils.openOverlappedWindow(this.getParent(), progressWindow, "middle_center");
}
/**
* internal use, don't call this directly
*/
public void runProcess() {
processDialogRunnable = new ProcessDialogRunnable();
future = Adempiere.getThreadPoolExecutor().submit(new DesktopRunnable(processDialogRunnable, getDesktop()));
@Override
public void updateUI() {
}
private void hideBusyDialog() {
if (progressWindow != null) {
progressWindow.dispose();
progressWindow = null;
}
@Override
public void hideBusyDialog() {
closeBusyDialog();
}
/**
@ -394,138 +225,12 @@ public class ProcessModalDialog extends Window implements EventListener<Event>,
Component component = event.getTarget();
if (component instanceof Button) {
Button element = (Button)component;
if ("Ok".equalsIgnoreCase(element.getId())) {
onOK();
} else if ("Cancel".equalsIgnoreCase(element.getId())) {
onCancel();
}
} else if (event.getName().equals(ON_STATUS_UPDATE)) {
onStatusUpdate(event);
} else if (event.getName().equals(ON_COMPLETE)) {
onComplete();
}
}
private void onOK() {
if (!parameterPanel.validateParameters())
return;
this.startProcess();
}
private void onCancel() {
m_cancel = true;
this.dispose();
}
private void onStatusUpdate(Event event) {
String message = (String) event.getData();
if (progressWindow != null)
progressWindow.statusUpdate(message);
}
private void onComplete() {
if (future != null) {
try {
future.get();
} catch (Exception e) {
log.log(Level.SEVERE, e.getLocalizedMessage(), e);
if (!m_pi.isError()) {
m_pi.setSummary(e.getLocalizedMessage(), true);
}
}
}
future = null;
processDialogRunnable = null;
unlockUI(m_pi);
if (downloadFiles.size() > 0) {
MultiFileDownloadDialog downloadDialog = new MultiFileDownloadDialog(downloadFiles.toArray(new File[0]));
downloadDialog.setPage(this.getPage());
downloadDialog.setTitle(m_pi.getTitle());
Events.postEvent(downloadDialog, new Event(MultiFileDownloadDialog.ON_SHOW));
}
dispose();
}
@Override
public void lockUI(ProcessInfo pi) {
if (isLocked || Executions.getCurrent() == null)
return;
showBusyDialog();
isLocked = true;
}
@Override
public void unlockUI(ProcessInfo pi) {
if (!isLocked)
return;
if (Executions.getCurrent() == null) {
Executions.schedule(getDesktop(), new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
doUnlockUI();
}
}, new Event("onUnLockUI"));
if ("Ok".equalsIgnoreCase(element.getId()))
startProcess();
else if ("Cancel".equalsIgnoreCase(element.getId()))
cancelProcess();
} else {
doUnlockUI();
super.onEvent(event);
}
}
private void doUnlockUI() {
hideBusyDialog();
isLocked = false;
}
@Override
public boolean isUILocked() {
return isLocked;
}
@Override
public void statusUpdate(String message) {
Executions.schedule(getDesktop(), this, new Event(ON_STATUS_UPDATE, this, message));
}
/**
*
* @return ProcessInfo
*/
public ProcessInfo getProcessInfo() {
return m_pi;
}
class ProcessDialogRunnable extends ContextRunnable{
ProcessDialogRunnable() {
super();
}
protected void doRun() {
try {
if (log.isLoggable(Level.INFO))log.log(Level.INFO, "Process Info="+m_pi+" AD_Client_ID="+Env.getAD_Client_ID(Env.getCtx()));
WProcessCtl.process(ProcessModalDialog.this, m_WindowNo, parameterPanel, m_pi, null);
} catch (Exception ex) {
m_pi.setError(true);
m_pi.setSummary(ex.getLocalizedMessage());
log.log(Level.SEVERE, ex.getLocalizedMessage(), ex);
} finally {
Executions.schedule(getDesktop(), ProcessModalDialog.this, new Event(ON_COMPLETE, ProcessModalDialog.this, null));
}
}
}
@Override
public void ask(final String message, final Callback<Boolean> callback) {
Executions.schedule(getDesktop(), new EventListener<Event>() {
@Override
public void onEvent(Event event) throws Exception {
FDialog.ask(m_WindowNo, null, message, callback);
}
}, new Event("onAsk"));
}
@Override
public void download(File file) {
downloadFiles.add(file);
}
} // ProcessDialog

View File

@ -0,0 +1,282 @@
/******************************************************************************
* Copyright (C) 2014 Elaine Tan *
* Copyright (C) 2014 Trek Global
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. 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., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.webui.dashboard;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Properties;
import org.adempiere.base.Service;
import org.adempiere.base.event.EventManager;
import org.adempiere.webui.apps.AEnv;
import org.adempiere.webui.theme.ThemeManager;
import org.adempiere.webui.util.ServerPushTemplate;
import org.compiere.model.MPInstance;
import org.compiere.model.MProcess;
import org.compiere.model.Query;
import org.compiere.util.Env;
import org.compiere.util.Msg;
import org.compiere.util.Util;
import org.idempiere.distributed.IMessageService;
import org.idempiere.distributed.ITopic;
import org.idempiere.distributed.ITopicSubscriber;
import org.osgi.service.event.EventHandler;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Desktop;
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.zk.ui.util.DesktopCleanup;
import org.zkoss.zul.A;
import org.zkoss.zul.Box;
import org.zkoss.zul.Image;
import org.zkoss.zul.Panel;
import org.zkoss.zul.Panelchildren;
import org.zkoss.zul.Toolbar;
import org.zkoss.zul.Vbox;
public class DPRunningJobs extends DashboardPanel implements EventListener<Event>, EventHandler {
/**
*
*/
private static final long serialVersionUID = 1946438226234068194L;
private static final String AD_PINSTANCE_ID_ATTR = "AD_PInstance_ID";
private static TopicSubscriber topicSubscriber;
private Box bxJobs;
private int AD_User_ID;
private Properties ctx;
private WeakReference<Desktop> desktop;
private DesktopCleanup listener;
public DPRunningJobs()
{
super();
ctx = new Properties();
ctx.putAll(Env.getCtx());
AD_User_ID = Env.getAD_User_ID(ctx);
Panel panel = new Panel();
this.appendChild(panel);
Panelchildren jobsContent = new Panelchildren();
panel.appendChild(jobsContent);
bxJobs = new Vbox();
bxJobs.setHflex("1");
this.setSclass("recentitems-box");
jobsContent.appendChild(bxJobs);
createJobsPanel();
Toolbar jobsToolbar = new Toolbar();
this.appendChild(jobsToolbar);
Image imgr = new Image(ThemeManager.getThemeResource("images/Refresh24.png"));
jobsToolbar.appendChild(imgr);
imgr.setStyle("text-align: right; cursor: pointer; width:24px; height:24px;");
imgr.setTooltiptext(Util.cleanAmp(Msg.getMsg(ctx, "Refresh")));
imgr.addEventListener(Events.ON_CLICK, this);
createTopicSubscriber();
listener = new DesktopCleanup() {
@Override
public void cleanup(Desktop desktop) throws Exception {
DPRunningJobs.this.cleanup();
}
};
}
protected void cleanup()
{
EventManager.getInstance().unregister(this);
desktop = null;
}
private static synchronized void createTopicSubscriber()
{
if (topicSubscriber == null) {
topicSubscriber = new TopicSubscriber();
IMessageService service = Service.locator().locate(IMessageService.class).getService();
if (service != null) {
ITopic<Integer> topic = service.getTopic(MPInstance.ON_RUNNING_JOB_CHANGED_TOPIC);
topic.subscribe(topicSubscriber);
}
}
}
private void createJobsPanel()
{
refresh();
}
@Override
public void onEvent(Event event) throws Exception
{
Component comp = event.getTarget();
String eventName = event.getName();
if (eventName.equals(Events.ON_CLICK))
doOnClick(comp);
}
private void doOnClick(Component comp)
{
if (comp instanceof A)
{
A btn = (A) comp;
int AD_PInstance_ID = 0;
try
{
AD_PInstance_ID = Integer.valueOf((String)btn.getAttribute(AD_PINSTANCE_ID_ATTR));
}
catch (Exception e) {
}
if (AD_PInstance_ID > 0)
AEnv.zoom(MPInstance.Table_ID, AD_PInstance_ID);
}
if (comp instanceof Image) // Refresh button
{
refresh();
}
}
private synchronized void refresh()
{
// Please review here - is throwing NPE in some cases when user push repeatedly the refresh button
List<?> childs = bxJobs.getChildren();
int childCount = childs.size();
for (int c = childCount - 1; c >=0; c--) {
Component comp = (Component) childs.get(c);
if (comp instanceof A) {
comp.removeEventListener(Events.ON_CLICK, this);
}
bxJobs.removeChild(comp);
}
List<MPInstance> pis = getRunningJobForUser(ctx, AD_User_ID);
for (MPInstance pi : pis) {
MProcess process = new MProcess(pi.getCtx(), pi.getAD_Process_ID(), pi.get_TrxName());
String label = process.getName() + " [" + Msg.getElement(pi.getCtx(), "Created") + " = " + pi.getCreated() + "]";
A btnJob = new A();
btnJob.setAttribute(AD_PINSTANCE_ID_ATTR, String.valueOf(pi.getAD_PInstance_ID()));
bxJobs.appendChild(btnJob);
btnJob.setLabel(label);
btnJob.setImage(ThemeManager.getThemeResource(getIconFile()));
btnJob.addEventListener(Events.ON_CLICK, this);
btnJob.setSclass("menu-href");
btnJob.setHflex("1");
}
}
public static List<MPInstance> getRunningJobForUser(Properties ctx, int AD_User_ID)
{
List<MPInstance> pis = new Query(ctx, MPInstance.Table_Name, "Coalesce(AD_User_ID,0)=? AND IsProcessing='Y' AND IsRunAsJob='Y'", null)
.setOnlyActiveRecords(true)
.setClient_ID()
.setParameters(AD_User_ID)
.setOrderBy("Updated DESC")
.list();
return pis;
}
private String getIconFile()
{
return "images/mWindow.png";
}
@Override
public void refresh(ServerPushTemplate template)
{
template.executeAsync(this);
}
@Override
public void updateUI()
{
refresh();
bxJobs.invalidate();
updateDesktopReference();
}
/**
*
*/
protected void updateDesktopReference()
{
if ((desktop == null || desktop.get() == null) || (desktop.get() != null && desktop.get() != getDesktop())) {
if (desktop != null && desktop.get() != null)
desktop.get().removeListener(listener);
desktop = new WeakReference<Desktop>(getDesktop());
desktop.get().addListener(listener);
}
}
@Override
public void handleEvent(org.osgi.service.event.Event event)
{
if (event.getTopic().equals(MPInstance.ON_RUNNING_JOB_CHANGED_TOPIC) && event.getProperty("AD_User_ID") != null) {
Object property = event.getProperty("AD_User_ID");
if (property instanceof Number) {
int id = ((Number)property).intValue();
if (id == AD_User_ID) {
try {
if (desktop != null && desktop.get() != null && desktop.get().isAlive()) {
ServerPushTemplate template = new ServerPushTemplate(desktop.get());
refresh(template);
}
} catch (Exception e) {
EventManager.getInstance().unregister(this);
}
}
}
}
}
@Override
public void onPageAttached(Page newpage, Page oldpage)
{
super.onPageAttached(newpage, oldpage);
if (newpage != null) {
EventManager.getInstance().register(MPInstance.ON_RUNNING_JOB_CHANGED_TOPIC, this);
updateDesktopReference();
}
}
@Override
public void onPageDetached(Page page) {
super.onPageDetached(page);
cleanup();
}
static class TopicSubscriber implements ITopicSubscriber<Integer> {
@Override
public void onMessage(Integer message) {
MPInstance.postOnChangedEvent(message);
}
}
}

View File

@ -122,6 +122,7 @@ public class WAttachment extends Window implements EventListener<Event>
autoPreviewList.add("image/gif");
autoPreviewList.add("text/plain");
autoPreviewList.add("application/pdf");
autoPreviewList.add("text/html");
}
/**

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<window use="org.adempiere.webui.dashboard.DPRunningJobs"/>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<zk>
<zscript>
<![CDATA[
import org.adempiere.webui.theme.ThemeManager;
var path = ThemeManager.getThemeResource("zul/dashboard/runningJobs.zul");
]]>
</zscript>
<include src="${path}"/>
</zk>