diff --git a/base/src/org/compiere/model/MScheduler.java b/base/src/org/compiere/model/MScheduler.java index 984ee8a54c..32ea7bd1f9 100644 --- a/base/src/org/compiere/model/MScheduler.java +++ b/base/src/org/compiere/model/MScheduler.java @@ -222,14 +222,15 @@ public class MScheduler extends X_AD_Scheduler MUserRoles ur = urs[j]; if (!ur.isActive()) continue; - list.add(ur.getAD_User_ID()); + if (!list.contains(ur.getAD_User_ID())) + list.add(ur.getAD_User_ID()); } } } // Add Updater if (list.size() == 0) { - list.add(getUpdatedBy()); + list.add(getCreatedBy()); } // return list.toArray(new Integer[list.size()]); diff --git a/serverRoot/src/main/server/org/compiere/server/AdempiereServer.java b/serverRoot/src/main/server/org/compiere/server/AdempiereServer.java index 9464f745d6..d15467d74a 100644 --- a/serverRoot/src/main/server/org/compiere/server/AdempiereServer.java +++ b/serverRoot/src/main/server/org/compiere/server/AdempiereServer.java @@ -1,5 +1,5 @@ /****************************************************************************** - * Product: Adempiere ERP & CRM Smart Business Solution * + * Product: Adempiere ERP & CRM Smart Business Solution * * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * 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 * @@ -32,7 +32,6 @@ import org.compiere.model.MLdapProcessor; import org.compiere.model.MRequestProcessor; import org.compiere.model.MScheduler; import org.compiere.model.MSystem; -import org.compiere.model.X_R_RequestProcessor; import org.compiere.util.CLogger; import org.compiere.util.Env; import org.compiere.util.TimeUtil; @@ -86,7 +85,10 @@ public abstract class AdempiereServer extends Thread p_system = MSystem.get(m_ctx); p_client = MClient.get(m_ctx); Env.setContext(m_ctx, "#AD_Client_ID", p_client.getAD_Client_ID()); - m_initialNap = initialNap; + m_initialNap = initialNap; + Timestamp dateNextRun = getDateNextRun(true); + if (dateNextRun != null) + m_nextWork = dateNextRun.getTime(); // log.info(model.getName() + " - " + getThreadGroup()); } // ServerBase @@ -355,11 +357,11 @@ public abstract class AdempiereServer extends Thread long typeSec = 600; // 10 minutes if (frequencyType == null) typeSec = 300; // 5 minutes - else if (X_R_RequestProcessor.FREQUENCYTYPE_Minute.equals(frequencyType)) + else if (MRequestProcessor.FREQUENCYTYPE_Minute.equals(frequencyType)) typeSec = 60; - else if (X_R_RequestProcessor.FREQUENCYTYPE_Hour.equals(frequencyType)) + else if (MRequestProcessor.FREQUENCYTYPE_Hour.equals(frequencyType)) typeSec = 3600; - else if (X_R_RequestProcessor.FREQUENCYTYPE_Day.equals(frequencyType)) + else if (MRequestProcessor.FREQUENCYTYPE_Day.equals(frequencyType)) typeSec = 86400; // return typeSec * 1000 * frequency; // ms diff --git a/serverRoot/src/main/server/org/compiere/server/Scheduler.java b/serverRoot/src/main/server/org/compiere/server/Scheduler.java index a2f9e9f7fc..62afa43d85 100644 --- a/serverRoot/src/main/server/org/compiere/server/Scheduler.java +++ b/serverRoot/src/main/server/org/compiere/server/Scheduler.java @@ -1,5 +1,5 @@ /****************************************************************************** - * Product: Adempiere ERP & CRM Smart Business Solution * + * Product: Adempiere ERP & CRM Smart Business Solution * * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * 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 * @@ -22,14 +22,18 @@ import it.sauronsoftware.cron4j.SchedulingPattern; import java.io.File; import java.math.BigDecimal; import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.Properties; import java.util.logging.Level; import org.compiere.model.MAttachment; import org.compiere.model.MClient; import org.compiere.model.MNote; +import org.compiere.model.MOrgInfo; import org.compiere.model.MPInstance; import org.compiere.model.MPInstancePara; import org.compiere.model.MProcess; +import org.compiere.model.MRole; import org.compiere.model.MScheduler; import org.compiere.model.MSchedulerLog; import org.compiere.model.MSchedulerPara; @@ -71,6 +75,9 @@ public class Scheduler extends AdempiereServer private it.sauronsoftware.cron4j.Scheduler cronScheduler; private Predictor predictor; + + // ctx for the report/process + Properties m_schedulerctx = new Properties(); /** * Work @@ -79,15 +86,36 @@ public class Scheduler extends AdempiereServer { m_summary = new StringBuffer(m_model.toString()) .append(" - "); - // - MProcess process = m_model.getProcess(); + + // Prepare a ctx for the report/process - BF [1966880] + m_schedulerctx.clear(); + MClient schedclient = MClient.get(getCtx(), m_model.getAD_Client_ID()); + Env.setContext(m_schedulerctx, "#AD_Client_ID", schedclient.getAD_Client_ID()); + Env.setContext(m_schedulerctx, "#AD_Language", schedclient.getAD_Language()); + Env.setContext(m_schedulerctx, "#AD_Org_ID", m_model.getAD_Org_ID()); + if (m_model.getAD_Org_ID() != 0) { + MOrgInfo schedorg = MOrgInfo.get(getCtx(), m_model.getAD_Org_ID()); + if (schedorg.getM_Warehouse_ID() > 0) + Env.setContext(m_schedulerctx, "#M_Warehouse_ID", schedorg.getM_Warehouse_ID()); + } + Env.setContext(m_schedulerctx, "#AD_User_ID", getAD_User_ID()); + Env.setContext(m_schedulerctx, "#SalesRep_ID", getAD_User_ID()); + // TODO: It can be convenient to add AD_Scheduler.AD_Role_ID + MUser scheduser = MUser.get(getCtx(), getAD_User_ID()); + MRole[] schedroles = scheduser.getRoles(m_model.getAD_Org_ID()); + if (schedroles != null && schedroles.length > 0) + Env.setContext(m_schedulerctx, "#AD_Role_ID", schedroles[0].getAD_Role_ID()); // first role, ordered by AD_Role_ID + Timestamp ts = new Timestamp(System.currentTimeMillis()); + SimpleDateFormat dateFormat4Timestamp = new SimpleDateFormat("yyyy-MM-dd"); + Env.setContext(m_schedulerctx, "#Date", dateFormat4Timestamp.format(ts)+" 00:00:00" ); // JDBC format + Properties currentctx = Env.getCtx(); + Env.setCtx(m_schedulerctx); + + MProcess process = new MProcess(m_schedulerctx, m_model.getAD_Process_ID(), null); try { m_trx = Trx.get(Trx.createTrxName("Scheduler"), true); - if (process.isReport()) - m_summary.append(runReport(process)); - else - m_summary.append(runProcess(process)); + m_summary.append(runProcess(process)); m_trx.commit(true); } catch (Exception e) @@ -102,10 +130,13 @@ public class Scheduler extends AdempiereServer if (m_trx != null) m_trx.close(); } + + // Restore system context + Env.setCtx(currentctx); // int no = m_model.deleteLog(); - m_summary.append("Logs deleted=").append(no); + m_summary.append(" Logs deleted=").append(no); // MSchedulerLog pLog = new MSchedulerLog(m_model, m_summary.toString()); pLog.setReference("#" + String.valueOf(p_runCount) @@ -114,76 +145,7 @@ public class Scheduler extends AdempiereServer } // doWork /** - * Run Report - * @param process - * @return summary - * @throws Exception - */ - private String runReport(MProcess process) throws Exception - { log.info(process.toString()); - if (!process.isReport() || process.getAD_ReportView_ID() == 0) - return "Not a Report AD_Process_ID=" + process.getAD_Process_ID() - + " - " + process.getName(); - // Process - int AD_Table_ID = 0; - int Record_ID = 0; - // - MPInstance pInstance = new MPInstance(process, Record_ID); - fillParameter(pInstance); - // - ProcessInfo pi = new ProcessInfo (process.getName(), process.getAD_Process_ID(), - AD_Table_ID, Record_ID); - pi.setAD_User_ID(getAD_User_ID()); - pi.setAD_Client_ID(m_model.getAD_Client_ID()); - pi.setAD_PInstance_ID(pInstance.getAD_PInstance_ID()); - if (!process.processIt(pi, m_trx) && pi.getClassName() != null) - return "Process failed: (" + pi.getClassName() + ") " + pi.getSummary(); - - // Report - ReportEngine re = ReportEngine.get(getCtx(), pi); - if (re == null) - return "Cannot create Report AD_Process_ID=" + process.getAD_Process_ID() - + " - " + process.getName(); - File report = re.getPDF(); - // Notice - int AD_Message_ID = 884; // HARDCODED SchedulerResult - MUser from = new MUser(getCtx(), pi.getAD_User_ID(), null); - Integer[] userIDs = m_model.getRecipientAD_User_IDs(); - 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(); - - if (notice) - { - MNote note = new MNote(getCtx(), - AD_Message_ID, userIDs[i].intValue(), m_trx.getTrxName()); - note.setClientOrg(m_model.getAD_Client_ID(), m_model.getAD_Org_ID()); - note.setTextMsg(m_model.getName()); - note.setDescription(m_model.getDescription()); - note.setRecord(AD_Table_ID, Record_ID); - note.save(); - // Attachment - MAttachment attachment = new MAttachment (getCtx(), - MNote.Table_ID, note.getAD_Note_ID(), m_trx.getTrxName()); - attachment.setClientOrg(m_model.getAD_Client_ID(), m_model.getAD_Org_ID()); - attachment.addEntry(report); - attachment.setTextMsg(m_model.getName()); - attachment.save(); - } - if (email) - { - MClient client = MClient.get(m_model.getCtx(), m_model.getAD_Client_ID()); - client.sendEMail(from, user, m_model.getName(), m_model.getDescription(), report); - } - } - // - return pi.getSummary(); - } // runReport - - /** - * Run Process + * Run Process or Report * @param process process * @return summary * @throws Exception @@ -191,6 +153,9 @@ public class Scheduler extends AdempiereServer private String runProcess(MProcess process) throws Exception { log.info(process.toString()); + + boolean isReport = (process.isReport() || process.getAD_ReportView_ID() > 0); + // Process (see also MWFActivity.performWork int AD_Table_ID = 0; int Record_ID = 0; @@ -198,18 +163,15 @@ public class Scheduler extends AdempiereServer MPInstance pInstance = new MPInstance(process, Record_ID); fillParameter(pInstance); // - ProcessInfo pi = new ProcessInfo (process.getName(), process.getAD_Process_ID(), - AD_Table_ID, Record_ID); - int AD_User_ID = getAD_User_ID(); - - pi.setAD_User_ID(AD_User_ID); + ProcessInfo pi = new ProcessInfo (process.getName(), process.getAD_Process_ID(), AD_Table_ID, Record_ID); + pi.setAD_User_ID(getAD_User_ID()); pi.setAD_Client_ID(m_model.getAD_Client_ID()); pi.setAD_PInstance_ID(pInstance.getAD_PInstance_ID()); MUser from = new MUser(getCtx(), pi.getAD_User_ID(), null); - //notify supervisor if error - if ( !process.processIt(pi, m_trx) ) + if ( !process.processIt(pi, m_trx) ) // note, this call close the transaction, don't use m_trx below { + // notify supervisor if error int supervisor = m_model.getSupervisor_ID(); if (supervisor > 0) { @@ -226,9 +188,8 @@ public class Scheduler extends AdempiereServer client.sendEMail(from, user, process.getName(), pi.getSummary() + " " + pi.getLogInfo(), null); } if (notice) { - int AD_Message_ID = 442; //ProcessRunError - MNote note = new MNote(getCtx(), - AD_Message_ID, supervisor, null); + int AD_Message_ID = 442; // HARDCODED ProcessRunError + 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(); @@ -239,6 +200,7 @@ public class Scheduler extends AdempiereServer } else { + // notify recipients on success Integer[] userIDs = m_model.getRecipientAD_User_IDs(); if (userIDs.length > 0) { @@ -246,24 +208,57 @@ public class Scheduler extends AdempiereServer 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(); - + boolean email = user.isNotificationEMail(); + boolean notice = user.isNotificationNote(); + + File report = null; + if (isReport) { + // Report + ReportEngine re = ReportEngine.get(m_schedulerctx, pi); + 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) + AD_Message_ID = 884; // HARDCODED SchedulerResult + MNote note = new MNote(getCtx(), AD_Message_ID, userIDs[i].intValue(), null); + note.setClientOrg(m_model.getAD_Client_ID(), m_model.getAD_Org_ID()); + if (isReport) { + note.setTextMsg(m_model.getName()); + note.setDescription(m_model.getDescription()); + note.setRecord(AD_Table_ID, Record_ID); + } else { + note.setTextMsg(pi.getSummary()); + // note.setDescription(); + note.setRecord(MPInstance.Table_ID, pi.getAD_PInstance_ID()); + } + if (note.save()) { + if (isReport) { + // Attachment + 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.addEntry(report); + attachment.setTextMsg(m_model.getName()); + attachment.save(); + } + } + } + if (email) { MClient client = MClient.get(m_model.getCtx(), m_model.getAD_Client_ID()); - client.sendEMail(from, user, process.getName(), pi.getSummary() + " " + pi.getLogInfo(), null); - } - if (notice) { - int AD_Message_ID = 441; //ProcessOK - MNote note = new MNote(getCtx(), - AD_Message_ID, userIDs[i].intValue(), 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.save(); + if (isReport) { + client.sendEMail(from, user, m_model.getName(), m_model.getDescription(), report); + } else { + client.sendEMail(from, user, process.getName(), pi.getSummary() + " " + pi.getLogInfo(), null); + } } + } } } @@ -274,10 +269,10 @@ public class Scheduler extends AdempiereServer int AD_User_ID; if (m_model.getSupervisor_ID() > 0) AD_User_ID = m_model.getSupervisor_ID(); - else if (m_model.getUpdatedBy() > 0) - AD_User_ID = m_model.getUpdatedBy(); else if (m_model.getCreatedBy() > 0) AD_User_ID = m_model.getCreatedBy(); + else if (m_model.getUpdatedBy() > 0) + AD_User_ID = m_model.getUpdatedBy(); else AD_User_ID = 100; //fall back to SuperUser return AD_User_ID; @@ -306,7 +301,7 @@ public class Scheduler extends AdempiereServer if (variable == null || (variable != null && variable.length() == 0)) value = null; - else if (variable.indexOf('@') != -1) // we have a variable + else if (variable.startsWith("@") && variable.endsWith("@")) // we have a variable / BF [1926032] { // Strip int index = variable.indexOf('@'); @@ -320,7 +315,9 @@ public class Scheduler extends AdempiereServer } columnName = columnName.substring(0, index); // try Env - String env = Env.getContext(getCtx(), columnName); + String env = Env.getContext(m_schedulerctx, columnName); + if (env == null || env.length() == 0) + env = Env.getContext(getCtx(), columnName); if (env.length() == 0) { log.warning(sPara.getColumnName()