Fix bug [1966880] - Scheduled Processes only run in System client
https://sourceforge.net/tracker/index.php?func=detail&aid=1966880&group_id=176962&atid=879332 Fix bug [1926032] - Schedule incorrectly identified variables https://sourceforge.net/tracker/index.php?func=detail&aid=1926032&group_id=176962&atid=879332 See additional documentation on http://www.adempiere.com/index.php/ManPageW_Scheduler#Contributions
This commit is contained in:
parent
976bee6dd0
commit
a8d4ee3e05
|
@ -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()]);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue