package in.partake.controller.api.user;
import in.partake.base.PartakeException;
import in.partake.base.TimeUtil;
import in.partake.base.Util;
import in.partake.controller.api.AbstractPartakeAPI;
import in.partake.model.IPartakeDAOs;
import in.partake.model.UserEx;
import in.partake.model.access.DBAccess;
import in.partake.model.dao.DAOException;
import in.partake.model.dao.PartakeConnection;
import in.partake.model.dao.access.IUserTicketAccess;
import in.partake.model.dao.access.IEventAccess;
import in.partake.model.dao.auxiliary.EventFilterCondition;
import in.partake.model.dao.auxiliary.EventStatus;
import in.partake.model.daofacade.UserDAOFacade;
import in.partake.model.dto.Event;
import in.partake.model.dto.EventTicket;
import in.partake.model.dto.UserPreference;
import in.partake.model.dto.auxiliary.ParticipationStatus;
import in.partake.resource.UserErrorCode;
import java.util.ArrayList;
import java.util.List;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.JsonNodeFactory;
import org.codehaus.jackson.node.ObjectNode;
import play.mvc.Result;
public class GetEventsAPI extends AbstractPartakeAPI {
public static Result get() throws DAOException, PartakeException {
return new GetEventsAPI().execute();
}
@Override
protected Result doExecute() throws DAOException, PartakeException {
String userId = getValidUserIdParameter();
String queryType = getParameter("queryType");
int offset = optIntegerParameter("offset", 0);
offset = Util.ensureRange(offset, 0, Integer.MAX_VALUE);
int limit = optIntegerParameter("limit", 10);
limit = Util.ensureRange(limit, 0, 100);
GetEventsTransaction transaction = new GetEventsTransaction(userId, queryType, offset, limit);
transaction.execute();
ArrayNode statuses = new ArrayNode(JsonNodeFactory.instance);
for (EventStatus status : transaction.getEventStatuses())
statuses.add(status.toSafeJSON());
ObjectNode obj = new ObjectNode(JsonNodeFactory.instance);
obj.put("totalEventCount", transaction.getNumTotalEvents());
obj.put("eventStatuses", statuses);
return renderOK(obj);
}
}
//TODO: We should not read all events here.
class GetEventsTransaction extends DBAccess<Void> {
// TODO: Since we use 'screenname' to check editor's privileges, we have to have UserEx here.
// We should have only userId here.
private String userId;
private UserEx user;
private String queryType;
private int offset;
private int limit;
private List<Event> eventsRetrieved;
private int numTotalEvents;
private List<EventStatus> eventStatuses;
public GetEventsTransaction(String userId, String queryType, int offset, int limit) {
this.userId = userId;
this.queryType = queryType;
this.offset = offset;
this.limit = limit;
}
@Override
protected Void doExecute(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
if (!daos.getUserAccess().exists(con, userId))
throw new PartakeException(UserErrorCode.INVALID_USER_ID);
// If |user| does not publish their events, return immediately.
UserPreference pref = daos.getUserPreferenceAccess().find(con, userId);
if (pref == null)
pref = UserPreference.getDefaultPreference(userId);
if (!pref.isProfilePublic())
throw new PartakeException(UserErrorCode.INVALID_USER_PRIVATE);
user = UserDAOFacade.getUserEx(con, daos, userId);
getEventsFromDB(con, daos);
IUserTicketAccess enrollmentAccess = daos.getEnrollmentAccess();
this.eventStatuses = new ArrayList<EventStatus>();
for (Event event : eventsRetrieved) {
if (event == null)
continue;
List<EventTicket> tickets = daos.getEventTicketAccess().findEventTicketsByEventId(con, event.getId());
boolean isBeforeDeadline = event.acceptsSomeTicketsTill(tickets).isBefore(TimeUtil.getCurrentDateTime());
int numEnrolledUsers = enrollmentAccess.countByEventId(con, event.getId(), ParticipationStatus.ENROLLED);
int numReservedUsers = enrollmentAccess.countByEventId(con, event.getId(), ParticipationStatus.RESERVED);
int numCancelledUsers = enrollmentAccess.countByEventId(con, event.getId(), ParticipationStatus.CANCELLED);
int amount = 0;
boolean isAmountInfinite = false;
for (EventTicket ticket : tickets) {
isAmountInfinite |= ticket.isAmountInfinite();
amount += ticket.getAmount();
}
eventStatuses.add(new EventStatus(event, isAmountInfinite, amount, isBeforeDeadline, numEnrolledUsers, numReservedUsers, numCancelledUsers));
}
return null;
}
private void getEventsFromDB(PartakeConnection con, IPartakeDAOs daos) throws DAOException, PartakeException {
IEventAccess eventDao = daos.getEventAccess();
if ("owner".equalsIgnoreCase(queryType)) {
this.numTotalEvents = eventDao.countEventsByOwnerId(con, user.getId(), EventFilterCondition.PUBLISHED_PUBLIC_EVENT_ONLY);
this.eventsRetrieved = eventDao.findByOwnerId(con, user.getId(), EventFilterCondition.PUBLISHED_PUBLIC_EVENT_ONLY, offset, limit);
} else if ("editor".equalsIgnoreCase(queryType)) {
this.numTotalEvents = eventDao.countByEditorUserId(con, user.getId(), EventFilterCondition.PUBLISHED_PUBLIC_EVENT_ONLY);
this.eventsRetrieved = eventDao.findByEditorUserId(con, user.getId(), EventFilterCondition.PUBLISHED_PUBLIC_EVENT_ONLY, offset, limit);
} else {
throw new PartakeException(UserErrorCode.INVALID_ARGUMENT);
}
}
public int getNumTotalEvents() {
return numTotalEvents;
}
public List<EventStatus> getEventStatuses() {
return this.eventStatuses;
}
}