/*
jBilling - The Enterprise Open Source Billing System
Copyright (C) 2003-2011 Enterprise jBilling Software Ltd. and Emiliano Conde
This file is part of jbilling.
jbilling is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
jbilling 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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with jbilling. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Created on Mar 26, 2004
*/
package com.sapienter.jbilling.server.process;
import com.sapienter.jbilling.common.SessionInternalError;
import com.sapienter.jbilling.server.pluggableTask.admin.PluggableTaskException;
import com.sapienter.jbilling.server.pluggableTask.admin.PluggableTaskManager;
import com.sapienter.jbilling.server.process.db.AgeingEntityStepDAS;
import com.sapienter.jbilling.server.process.db.AgeingEntityStepDTO;
import com.sapienter.jbilling.server.process.task.IAgeingTask;
import com.sapienter.jbilling.server.user.EntityBL;
import com.sapienter.jbilling.server.user.UserDTOEx;
import com.sapienter.jbilling.server.user.db.CompanyDTO;
import com.sapienter.jbilling.server.user.db.UserDAS;
import com.sapienter.jbilling.server.user.db.UserDTO;
import com.sapienter.jbilling.server.user.db.UserStatusDAS;
import com.sapienter.jbilling.server.user.db.UserStatusDTO;
import com.sapienter.jbilling.server.util.Constants;
import com.sapienter.jbilling.server.util.audit.EventLogger;
import org.apache.log4j.Logger;
import javax.naming.NamingException;
import java.sql.SQLException;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* @author Emil
*/
public class AgeingBL {
private static final Logger LOG = Logger.getLogger(AgeingBL.class);
private AgeingEntityStepDAS ageingDas = null;
private AgeingEntityStepDTO ageing = null;
private EventLogger eLogger = null;
private static final ConcurrentMap<Integer, Boolean> running = new ConcurrentHashMap<Integer, Boolean>();
public AgeingBL(Integer ageingId) {
init();
set(ageingId);
}
public AgeingBL() {
init();
}
private void init() {
eLogger = EventLogger.getInstance();
ageingDas = new AgeingEntityStepDAS();
}
public AgeingEntityStepDTO getEntity() {
return ageing;
}
public void set(Integer id) {
ageing = ageingDas.find(id);
}
public void reviewAll(Integer entityId, Date today) throws NamingException, SessionInternalError, SQLException {
running.putIfAbsent(entityId, Boolean.FALSE);
if (running.get(entityId)) {
LOG.warn("Failed to trigger ageing review process at " + today + ", another process is already running.");
return;
} else {
running.put(entityId, Boolean.TRUE);
}
CompanyDTO company = new EntityBL(entityId).getEntity();
try {
PluggableTaskManager<IAgeingTask> taskManager
= new PluggableTaskManager<IAgeingTask>(entityId, Constants.PLUGGABLE_TASK_AGEING);
IAgeingTask task = taskManager.getNextClass();
while (task != null) {
task.reviewAllUsers(company.getId(), company.getAgeingEntitySteps(), today, null);
task = taskManager.getNextClass();
}
} catch (PluggableTaskException e) {
throw new SessionInternalError("Ageing task exception while running ageing review.", e);
} finally {
running.put(entityId, Boolean.FALSE);
}
}
public void out(UserDTO user, Integer excludedInvoiceId) {
try {
PluggableTaskManager<IAgeingTask> taskManager
= new PluggableTaskManager<IAgeingTask>(user.getCompany().getId(), Constants.PLUGGABLE_TASK_AGEING);
IAgeingTask task = taskManager.getNextClass();
while (task != null) {
task.removeUser(user, excludedInvoiceId, null);
task = taskManager.getNextClass();
}
} catch (PluggableTaskException e) {
throw new SessionInternalError("Ageing task exception when removing user from ageing.", e);
}
}
public void setUserStatus(Integer executorId, Integer userId, Integer statusId, Date today) {
UserDTO user = new UserDAS().find(userId);
UserStatusDTO userStatus = new UserStatusDAS().find(statusId);
try {
PluggableTaskManager<IAgeingTask> taskManager
= new PluggableTaskManager<IAgeingTask>(user.getCompany().getId(), Constants.PLUGGABLE_TASK_AGEING);
IAgeingTask task = taskManager.getNextClass();
while (task != null) {
task.setUserStatus(user, userStatus, today, executorId);
task = taskManager.getNextClass();
}
} catch (PluggableTaskException e) {
throw new SessionInternalError("Ageing task exception when setting user status.", e);
}
}
public String getWelcome(Integer entityId, Integer languageId, Integer statusId) throws NamingException {
AgeingEntityStepDTO step = new AgeingEntityStepDAS().findStep(entityId, statusId);
ageing = ageingDas.find(step.getId());
return ageing.getWelcomeMessage(languageId);
}
public AgeingDTOEx[] getSteps(Integer entityId, Integer executorLanguageId, Integer languageId) throws NamingException {
AgeingDTOEx[] result = new AgeingDTOEx[UserDTOEx.STATUS_DELETED.intValue()];
// go over all the steps
for (int step = UserDTOEx.STATUS_ACTIVE.intValue(); step <= UserDTOEx.STATUS_DELETED.intValue(); step++) {
AgeingDTOEx newStep = new AgeingDTOEx();
newStep.setStatusId(new Integer(step));
UserStatusDTO statusRow = new UserStatusDAS().find(step);
newStep.setStatusStr(statusRow.getDescription(executorLanguageId));
newStep.setCanLogin(statusRow.getCanLogin());
AgeingEntityStepDTO myStep = new AgeingEntityStepDAS().findStep(entityId, new Integer(step));
if (myStep != null) { // it doesn't have to be there
ageing = ageingDas.find(myStep.getId());
newStep.setDays(ageing.getDays());
newStep.setFailedLoginMessage(ageing.getFailedLoginMessage(languageId));
newStep.setInUse(true);
newStep.setWelcomeMessage(ageing.getWelcomeMessage(languageId));
} else {
newStep.setInUse(false);
}
result[step-1] = newStep;
}
return result;
}
public AgeingDTOEx[] validate(AgeingDTOEx[] steps) throws SessionInternalError {
int lastSelected = 0;
for (int f = 1; f < steps.length; f++) {
AgeingDTOEx line = steps[f];
if (line.getInUse()) {
lastSelected = f;
}
}
for (int f = 0; f < steps.length; f++) {
//Active Step cannot be set to not-in-use
if (steps[f].getStatusId().equals(UserDTOEx.STATUS_ACTIVE)) {
steps[f].setInUse(true);
}
if (steps[f].getInUse()) {
//if the Step is not deleted, welcome message may not be null
if (!steps[f].getStatusId().equals(UserDTOEx.STATUS_DELETED) &&
steps[f].getWelcomeMessage() == null ) {
SessionInternalError exception = new SessionInternalError("Welcome message may not be null for a step");
exception.setErrorMessages(new String[] {"AgeingWS,welcomeMessage,config.ageing.error.null.message,null"});
throw exception;
}
//for inUse steps (NOT ACTIVE or DELETE Step) , days may not be zero
if ( ! ( steps[f].getStatusId().equals(UserDTOEx.STATUS_ACTIVE) ||
steps[f].getStatusId().equals(UserDTOEx.STATUS_DELETED) )
&& f != lastSelected ) {
if (steps[f].getDays() <= 0 ) {
SessionInternalError exception = new SessionInternalError("Days cannot be zero for an 'in use' step");
exception.setErrorMessages(new String[] {"AgeingWS,days,config.ageing.error.zero.days,0"});
throw exception;
}
}
//set days to zero by default for the last Selected Step
if (f == lastSelected ) {
if (steps[f].getDays() > 0) {
SessionInternalError exception = new SessionInternalError("The days for the last selected step has to be 0");
exception.setErrorMessages(new String[] {"AgeingWS,days,config.ageing.error.lastDay," + steps[f].getDays()});
throw exception;
}
else {steps[f].setDays(0);}
}
}
}
return steps;
}
public void setSteps(Integer entityId, Integer languageId, AgeingDTOEx[] steps) throws NamingException {
for (AgeingDTOEx step : steps) {
// get the existing data for this step
AgeingEntityStepDTO myStep = new AgeingEntityStepDAS().findStep(entityId, step.getStatusId());
if (myStep != null) {
ageing = ageingDas.find(myStep.getId());
} else {
ageing = null;
}
if (!step.getInUse()) {
// delete if not in use
if (ageing != null) {
ageingDas.delete(ageing);
}
} else {
// in use, create or update
if (ageing == null) {
// create
ageingDas.create(entityId,
step.getStatusId(),
step.getWelcomeMessage(),
step.getFailedLoginMessage(),
languageId,
step.getDays());
} else {
// update
ageing.setDays(step.getDays());
ageing.setFailedLoginMessage(languageId, step.getFailedLoginMessage());
ageing.setWelcomeMessage(languageId, step.getWelcomeMessage());
}
}
}
}
public AgeingWS getWS(AgeingDTOEx dto) {
return null == dto ? null : new AgeingWS(dto);
}
public AgeingDTOEx getDTOEx(AgeingWS ws) {
AgeingDTOEx dto= new AgeingDTOEx();
dto.setStatusId(ws.getStatusId());
dto.setStatusStr(ws.getStatusStr());
dto.setInUse(null == ws.getInUse() ? Boolean.FALSE : ws.getInUse());
dto.setDays(null == ws.getDays() ? 0 : ws.getDays().intValue());
dto.setWelcomeMessage(ws.getWelcomeMessage());
dto.setFailedLoginMessage(ws.getFailedLoginMessage());
return dto;
}
}