added finance API methods

This commit is contained in:
2023-06-04 22:21:15 -04:00
parent b684b80ea9
commit ffaea04b86
5 changed files with 537 additions and 456 deletions

View File

@@ -111,10 +111,10 @@ public class EventApi {
@POST @POST
@Path("/document/{documentId}/send") @Path("/document/{documentId}/send")
@RolesAllowed( @RolesAllowed(
Constants.EVENT_ROLE_PREFIX Constants.EVENT_ROLE_PREFIX
+ "communicate" + "communicate"
) )
@Produces(Constants.V1_JSON) @Produces(Constants.V1_JSON)
@Operation( @Operation(
summary = "Sends the specified document.", summary = "Sends the specified document.",
@@ -144,10 +144,10 @@ public class EventApi {
@POST @POST
@Path("/document/{documentId}/sendTest/{personId}") @Path("/document/{documentId}/sendTest/{personId}")
@RolesAllowed( @RolesAllowed(
Constants.EVENT_ROLE_PREFIX Constants.EVENT_ROLE_PREFIX
+ "communicate" + "communicate"
) )
@Produces(Constants.V1_JSON) @Produces(Constants.V1_JSON)
@Operation( @Operation(
summary = "Sends the specified document to the specified person.", summary = "Sends the specified document to the specified person.",

View File

@@ -15,6 +15,7 @@ import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path; import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam; import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces; import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.WebApplicationException; import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Context; import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.SecurityContext; import jakarta.ws.rs.core.SecurityContext;
@@ -48,7 +49,7 @@ public class EventFinanceApi {
) )
@Produces(Constants.V1_JSON) @Produces(Constants.V1_JSON)
@SecurityRequirement(name = "basic") @SecurityRequirement(name = "basic")
@Operation(summary = "Retrieves the balances of all participants in an event.") @Operation(summary = "Retrieves the balances of all persons associated with an event.")
@ApiResponses({ @ApiResponses({
@ApiResponse(responseCode = "200", description = "Success"), @ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "401", description = "Not authenticated"), @ApiResponse(responseCode = "401", description = "Not authenticated"),
@@ -56,8 +57,11 @@ public class EventFinanceApi {
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found") @ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
}) })
public List<Map<String, Object>> getBalanceByPersonsAsJson(@Context public List<Map<String, Object>> getBalanceByPersonsAsJson(@Context
SecurityContext securityContext) throws JsonProcessingException { SecurityContext securityContext, @QueryParam("minBalance")
Map<Long, DataSet> personsBalances = this.eventFinanceService.getPersonsBalances(this.eventId); Float minBalance, @QueryParam("maxBalance")
Float maxBalance) throws JsonProcessingException {
Map<Long, DataSet> personsBalances = this.eventFinanceService.getPersonsBalances(this.eventId, minBalance,
maxBalance);
List<Map<String, Object>> personsBalancesJson = new ArrayList<>(personsBalances.size()); List<Map<String, Object>> personsBalancesJson = new ArrayList<>(personsBalances.size());
for (DataSet personBalance : personsBalances.values()) { for (DataSet personBalance : personsBalances.values()) {
@@ -80,7 +84,7 @@ public class EventFinanceApi {
) )
@Produces("text/csv") @Produces("text/csv")
@SecurityRequirement(name = "basic") @SecurityRequirement(name = "basic")
@Operation(summary = "Retrieves the balances of all participants in an event.") @Operation(summary = "Retrieves the balances of all persons associated with an event.")
@ApiResponses({ @ApiResponses({
@ApiResponse(responseCode = "200", description = "Success"), @ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "401", description = "Not authenticated"), @ApiResponse(responseCode = "401", description = "Not authenticated"),
@@ -115,4 +119,68 @@ public class EventFinanceApi {
}; };
} }
@GET
@Path("/balance/person/{personId}")
@RolesAllowed(
Constants.EVENT_ROLE_PREFIX
+ "member"
)
@Produces(Constants.V1_JSON)
@SecurityRequirement(name = "basic")
@Operation(summary = "Retrieves the balance of a person in an event.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "401", description = "Not authenticated"),
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
@ApiResponse(
responseCode = "404",
description = "An event or person with the specified IDs could not be found"
)
})
public Map<String, Object> getBalanceByPersonsAsJson(@Context
SecurityContext securityContext, @PathParam("personId")
long personId) throws JsonProcessingException {
DataSet personBalance = this.eventFinanceService.getPersonBalance(this.eventId, personId);
Map<String, Object> personBalanceJson = new HashMap<>(5);
personBalanceJson.put("personId", personBalance.getLong("personID"));
personBalanceJson.put("expense", personBalance.getFloat("expense"));
personBalanceJson.put("paid", personBalance.getFloat("paid"));
personBalanceJson.put("balance", personBalance.getFloat("balance"));
return personBalanceJson;
}
@GET
@Path("/series/balance/persons")
@RolesAllowed(
Constants.EVENT_ROLE_PREFIX
+ "member"
)
@Produces(Constants.V1_JSON)
@SecurityRequirement(name = "basic")
@Operation(summary = "Retrieves the cumulative balances of all persons associated with a series prior to an event.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "Success"),
@ApiResponse(responseCode = "401", description = "Not authenticated"),
@ApiResponse(responseCode = "403", description = "Authenticated, but not permitted"),
@ApiResponse(responseCode = "404", description = "An event with the specified ID could not be found")
})
public List<Map<String, Object>> getSeriesBalanceByPersonsAsJson(@Context
SecurityContext securityContext) throws JsonProcessingException {
Map<Long, DataSet> personsBalances = this.eventFinanceService.getSeriesPersonsPreviousBalances(this.eventId);
List<Map<String, Object>> personsBalancesJson = new ArrayList<>(personsBalances.size());
for (DataSet personBalance : personsBalances.values()) {
Map<String, Object> personBalanceJson = new HashMap<>(5);
personBalanceJson.put("personId", personBalance.getLong("personID"));
personBalanceJson.put("expense", personBalance.getFloat("expense"));
personBalanceJson.put("paid", personBalance.getFloat("paid"));
personBalanceJson.put("balance", personBalance.getFloat("balance"));
personsBalancesJson.add(personBalanceJson);
}
return personsBalancesJson;
}
} }

View File

@@ -1,79 +1,81 @@
package com.poststats.golf.service; package com.poststats.golf.service;
import java.util.Map;
import com.brianlong.sql.DataSet; import com.brianlong.sql.DataSet;
import java.util.Map;
/** /**
* This service provides financial metadata about the event, series, associated * This service provides financial metadata about the event, series, associated
* people, or a combination of those. * people, or a combination of those.
* *
* The balance metadata includes money `paid`, `expenses`, and `balance`. The * The balance metadata includes money `paid`, `expenses`, and `balance`. The
* balance numerically consistent with the perspective of the person, not the * balance numerically consistent with the perspective of the person, not the
* event organizers. That means it is positive when the person paid more than * event organizers. That means it is positive when the person paid more than
* they should owe and negative if they owe money. * they should owe and negative if they owe money.
* *
* @author brian * @author brian
*/ */
public interface EventFinanceService { public interface EventFinanceService {
/** /**
* Computes and retrieves the person balances for those associated with the * Computes and retrieves the person balances for those associated with the
* specified event. * specified event.
* *
* @param eventId The unique identifier of an event. * @param eventId The unique identifier of an event.
* @return A map of `personId` to balance metadata. * @return A map of `personId` to balance metadata.
*/ */
Map<Long, DataSet> getPersonsBalances(long eventId); Map<Long, DataSet> getPersonsBalances(long eventId);
/** /**
* Computes and retrieves the person balances for those associated with the * Computes and retrieves the person balances for those associated with the
* specified event. * specified event.
* *
* @param eventId The unique identifier of an event. * @param eventId The unique identifier of an event.
* @param minBalance The minimum balance for returned balances; `0.01` for those that have paid more than they owe; `null` for no constraint. * @param minBalance The minimum balance for returned balances; `0.01` for those
* @param maxBalance The maximum balance for returned balances; `-0.01` for those that owe; `null` for no constraint. * that have paid more than they owe; `null` for no
* @return A map of `personId` to balance metadata. * constraint.
*/ * @param maxBalance The maximum balance for returned balances; `-0.01` for
* those that owe; `null` for no constraint.
* @return A map of `personId` to balance metadata.
*/
Map<Long, DataSet> getPersonsBalances(long eventId, Float minBalance, Float maxBalance); Map<Long, DataSet> getPersonsBalances(long eventId, Float minBalance, Float maxBalance);
/** /**
* Computes and retrieves the specified person's balance for the specified * Computes and retrieves the specified person's balance for the specified
* event. * event.
* *
* @param eventId The unique identifier of an event. * @param eventId The unique identifier of an event.
* @param personId The unique identifier of a person. * @param personId The unique identifier of a person.
* @return Balance metadata. * @return Balance metadata.
*/ */
DataSet getPersonBalance(long eventId, long personId); DataSet getPersonBalance(long eventId, long personId);
/** /**
* Computes and retrieves all associated persons' cumulative balance for * Computes and retrieves all associated persons' cumulative balance for all
* all events in the series before the specified event. * events in the series before the specified event.
* *
* @param eventId The unique identifier of an event. * @param eventId The unique identifier of an event.
* @return A map of `personId` to balance metadata. * @return A map of `personId` to balance metadata.
*/ */
Map<Long, DataSet> getSeriesPersonsBalances(long eventId); Map<Long, DataSet> getSeriesPersonsPreviousBalances(long eventId);
/** /**
* Computes and retrieves the specified person's balances for all events in * Computes and retrieves the specified person's balances for all events in the
* the specified series. * specified series.
* *
* @param seriesId The unique identifier of a series. * @param seriesId The unique identifier of a series.
* @param personId The unique identifier of a person. * @param personId The unique identifier of a person.
* @return A map of `eventId` to balance metadata. * @return A map of `eventId` to balance metadata.
*/ */
Map<Long, DataSet> getSeriesPersonBalances(int seriesId, long personId); Map<Long, DataSet> getSeriesPersonBalances(int seriesId, long personId);
/** /**
* Computes and retrieves the specified person's balances for all events in * Computes and retrieves the specified person's balances for all events in the
* the series before the specified event. * series before the specified event.
* *
* @param eventId The unique identifier of an event. * @param eventId The unique identifier of an event.
* @param personId The unique identifier of a person. * @param personId The unique identifier of a person.
* @return A map of `eventId` to balance metadata. * @return A map of `eventId` to balance metadata.
*/ */
Map<Long, DataSet> getSeriesPersonPreviousBalances(long eventId, long personId); Map<Long, DataSet> getSeriesPersonPreviousBalances(long eventId, long personId);
} }

View File

@@ -1,9 +1,5 @@
package com.poststats.golf.service.db; package com.poststats.golf.service.db;
import java.sql.SQLException;
import java.time.LocalDate;
import java.util.Map;
import com.brianlong.sql.DataSet; import com.brianlong.sql.DataSet;
import com.brianlong.sql.FlexPreparedStatement; import com.brianlong.sql.FlexPreparedStatement;
import com.brianlong.util.FlexMap; import com.brianlong.util.FlexMap;
@@ -14,20 +10,22 @@ import com.poststats.provider.NonTransactionalProvider;
import com.poststats.provider.Statement; import com.poststats.provider.Statement;
import com.poststats.provider.StatementProvider; import com.poststats.provider.StatementProvider;
import com.poststats.service.ServiceException; import com.poststats.service.ServiceException;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject; import jakarta.inject.Inject;
import java.sql.SQLException;
import java.time.LocalDate;
import java.util.Map;
@ApplicationScoped @ApplicationScoped
public class EventFinanceServiceDAO implements EventFinanceService { public class EventFinanceServiceDAO implements EventFinanceService {
@Inject
private EventService eventService;
@Override @Inject
public Map<Long, DataSet> getPersonsBalances(long eventId) { private EventService eventService;
return this.getPersonsBalances(eventId, null, null);
} @Override
public Map<Long, DataSet> getPersonsBalances(long eventId) {
return this.getPersonsBalances(eventId, null, null);
}
@Override @Override
public Map<Long, DataSet> getPersonsBalances(long eventId, Float minBalance, Float maxBalance) { public Map<Long, DataSet> getPersonsBalances(long eventId, Float minBalance, Float maxBalance) {
@@ -36,8 +34,8 @@ public class EventFinanceServiceDAO implements EventFinanceService {
try { try {
for (int i = 1; i <= 5; i++) for (int i = 1; i <= 5; i++)
fps.setIntegerU(i, eventId); fps.setIntegerU(i, eventId);
fps.setFloat(6, minBalance == null ? Float.NEGATIVE_INFINITY : minBalance); fps.setFloat(6, minBalance == null ? -1e20f : minBalance);
fps.setFloat(7, maxBalance == null ? Float.POSITIVE_INFINITY : maxBalance); fps.setFloat(7, maxBalance == null ? 1e20f : maxBalance);
return fps.executeQuery().getAllRows("personID", Long.class); return fps.executeQuery().getAllRows("personID", Long.class);
} finally { } finally {
fps.close(); fps.close();
@@ -47,124 +45,124 @@ public class EventFinanceServiceDAO implements EventFinanceService {
} }
} }
@Override @Override
public DataSet getPersonBalance(long eventId, long personId) { public DataSet getPersonBalance(long eventId, long personId) {
try { try {
FlexPreparedStatement fps = this.sqlSelectPersonBalances.buildPreparedStatement(); FlexPreparedStatement fps = this.sqlSelectPersonBalances.buildPreparedStatement();
try { try {
for (int i = 1; i <= 10; i += 2) { for (int i = 1; i <= 10; i += 2) {
fps.setIntegerU(i, eventId); fps.setIntegerU(i, eventId);
fps.setIntegerU(i+1, personId); fps.setIntegerU(i + 1, personId);
} }
return fps.executeQuery().getNextRow(); return fps.executeQuery().getNextRow();
} finally { } finally {
fps.close(); fps.close();
} }
} catch (SQLException se) { } catch (SQLException se) {
throw new ServiceException(se); throw new ServiceException(se);
} }
} }
@Override @Override
public Map<Long, DataSet> getSeriesPersonsBalances(long eventId) { public Map<Long, DataSet> getSeriesPersonsPreviousBalances(long eventId) {
FlexMap event = this.eventService.get(eventId); FlexMap event = this.eventService.get(eventId);
int seriesId = event.getInteger("seriesID"); int seriesId = event.getInteger("seriesID");
LocalDate liveline = event.getDate("liveline"); LocalDate liveline = event.getDate("liveline");
try {
FlexPreparedStatement fps = this.sqlSelectSeriesBalances.buildPreparedStatement();
try {
for (int i = 1; i <= 15; i += 3) {
fps.setSmallintU(i, seriesId);
fps.setIntegerU(i+1, eventId);
fps.setDate(i+2, liveline);
}
return fps.executeQuery().getAllRows("personID", Long.class);
} finally {
fps.close();
}
} catch (SQLException se) {
throw new ServiceException(se);
}
}
@Override try {
public Map<Long, DataSet> getSeriesPersonBalances(int seriesId, long personId) { FlexPreparedStatement fps = this.sqlSelectSeriesBalances.buildPreparedStatement();
return this.getSeriesPersonBalances(seriesId, null, null, personId); try {
} for (int i = 1; i <= 15; i += 3) {
fps.setSmallintU(i, seriesId);
fps.setIntegerU(i + 1, eventId);
fps.setDate(i + 2, liveline);
}
return fps.executeQuery().getAllRows("personID", Long.class);
} finally {
fps.close();
}
} catch (SQLException se) {
throw new ServiceException(se);
}
}
@Override @Override
public Map<Long, DataSet> getSeriesPersonPreviousBalances(long eventId, long personId) { public Map<Long, DataSet> getSeriesPersonBalances(int seriesId, long personId) {
FlexMap event = this.eventService.get(eventId); return this.getSeriesPersonBalances(seriesId, null, null, personId);
int seriesId = event.getInteger("seriesID"); }
LocalDate liveline = event.getDate("liveline");
return this.getSeriesPersonBalances(seriesId, eventId, liveline, personId);
}
private Map<Long, DataSet> getSeriesPersonBalances(int seriesId, Long eventId, LocalDate liveline, long personId) {
if (eventId == null)
eventId = -1L;
if (liveline == null)
liveline = LocalDate.now().plusYears(10L);
try {
FlexPreparedStatement fps = this.sqlSelectSeriesPersonEventBalances.buildPreparedStatement();
try {
for (int i = 1; i <= 20; i += 4) {
fps.setSmallintU(i, seriesId);
fps.setIntegerU(i+1, eventId);
fps.setDate(i+2, liveline);
fps.setIntegerU(i+3, personId);
}
return fps.executeQuery().getAllRows("personID", Long.class);
} finally {
fps.close();
}
} catch (SQLException se) {
throw new ServiceException(se);
}
}
@Inject @Override
@NonTransactionalProvider public Map<Long, DataSet> getSeriesPersonPreviousBalances(long eventId, long personId) {
@GolfProvider FlexMap event = this.eventService.get(eventId);
@Statement( int seriesId = event.getInteger("seriesID");
sql = "SELECT TT.personID, TT.epersonID, SUM(TT.expenses) expenses, SUM(TT.paid) paid, (SUM(TT.paid)-SUM(TT.expenses)) balance " LocalDate liveline = event.getDate("liveline");
+ "FROM (" return this.getSeriesPersonBalances(seriesId, eventId, liveline, personId);
+ " SELECT ALL EP.personID, EP.epersonID, IF(EB.projectedValue IS NULL, 0, EB.projectedValue) expenses, 0 paid " }
+ " FROM ~g~.EventPerson EP "
+ " LEFT JOIN ~g~.EventBudget EB ON (EP.eventID=EB.eventID) " private Map<Long, DataSet> getSeriesPersonBalances(int seriesId, Long eventId, LocalDate liveline, long personId) {
+ " WHERE EP.eventID=? " if (eventId == null)
+ " UNION ALL " eventId = -1L;
+ " SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid " if (liveline == null)
+ " FROM ~g~.EventPerson EP " liveline = LocalDate.now().plusYears(10L);
+ " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) "
+ " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) " try {
+ " WHERE EP.eventID=? AND EPO.answer='Y' AND EO.amount IS NOT NULL AND EO.waive IS FALSE " FlexPreparedStatement fps = this.sqlSelectSeriesPersonEventBalances.buildPreparedStatement();
+ " UNION ALL " try {
+ " SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid " for (int i = 1; i <= 20; i += 4) {
+ " FROM ~g~.EventPerson EP " fps.setSmallintU(i, seriesId);
+ " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) " fps.setIntegerU(i + 1, eventId);
+ " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) " fps.setDate(i + 2, liveline);
+ " WHERE EP.eventID=? AND EPO.itemID IS NOT NULL " fps.setIntegerU(i + 3, personId);
+ " AND (EO.multiple IS FALSE OR EO.funded='option' OR EO.static IS NOT NULL) " }
+ " AND EO.amount IS NOT NULL AND EO.waive IS FALSE " return fps.executeQuery().getAllRows("personID", Long.class);
+ " UNION ALL " } finally {
+ " SELECT ALL EP.personID, EP.epersonID, EOI.amount expenses, 0 paid " fps.close();
+ " FROM ~g~.EventPerson EP " }
+ " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) " } catch (SQLException se) {
+ " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) " throw new ServiceException(se);
+ " INNER JOIN ~g~.EventOptionItem EOI ON (EPO.itemID=EOI.itemID) " }
+ " WHERE EP.eventID=? AND EO.waive IS FALSE AND EO.funded='selection' AND EOI.amount IS NOT NULL " }
+ " UNION ALL "
+ " SELECT ALL EPP.personID, EP.epersonID, 0 expenses, EPP.amount paid " @Inject
+ " FROM ~g~.EventPersonPayment EPP " @NonTransactionalProvider
+ " LEFT JOIN ~g~.EventPerson EP ON (EPP.eventID=EP.eventID AND EPP.personID=EP.personID) " @GolfProvider
+ " WHERE EPP.eventID=?) TT " @Statement(
+ "GROUP BY TT.personID " sql = "SELECT TT.personID, TT.epersonID, SUM(TT.expenses) expenses, SUM(TT.paid) paid, (SUM(TT.paid)-SUM(TT.expenses)) balance "
+ "HAVING (SUM(TT.paid)-SUM(TT.expenses))>=? AND (SUM(TT.paid)-SUM(TT.expenses))<=? " + "FROM ("
) + " SELECT ALL EP.personID, EP.epersonID, IF(EB.projectedValue IS NULL, 0, EB.projectedValue) expenses, 0 paid "
private StatementProvider sqlSelectBalances; + " FROM ~g~.EventPerson EP "
+ " LEFT JOIN ~g~.EventBudget EB ON (EP.eventID=EB.eventID) "
+ " WHERE EP.eventID=? "
+ " UNION ALL "
+ " SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid "
+ " FROM ~g~.EventPerson EP "
+ " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) "
+ " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) "
+ " WHERE EP.eventID=? AND EPO.answer='Y' AND EO.amount IS NOT NULL AND EO.waive IS FALSE "
+ " UNION ALL "
+ " SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid "
+ " FROM ~g~.EventPerson EP "
+ " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) "
+ " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) "
+ " WHERE EP.eventID=? AND EPO.itemID IS NOT NULL "
+ " AND (EO.multiple IS FALSE OR EO.funded='option' OR EO.static IS NOT NULL) "
+ " AND EO.amount IS NOT NULL AND EO.waive IS FALSE "
+ " UNION ALL "
+ " SELECT ALL EP.personID, EP.epersonID, EOI.amount expenses, 0 paid "
+ " FROM ~g~.EventPerson EP "
+ " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) "
+ " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) "
+ " INNER JOIN ~g~.EventOptionItem EOI ON (EPO.itemID=EOI.itemID) "
+ " WHERE EP.eventID=? AND EO.waive IS FALSE AND EO.funded='selection' AND EOI.amount IS NOT NULL "
+ " UNION ALL "
+ " SELECT ALL EPP.personID, EP.epersonID, 0 expenses, EPP.amount paid "
+ " FROM ~g~.EventPersonPayment EPP "
+ " LEFT JOIN ~g~.EventPerson EP ON (EPP.eventID=EP.eventID AND EPP.personID=EP.personID) "
+ " WHERE EPP.eventID=?) TT "
+ "GROUP BY TT.personID "
+ "HAVING (SUM(TT.paid)-SUM(TT.expenses))>=? AND (SUM(TT.paid)-SUM(TT.expenses))<=? "
)
private StatementProvider sqlSelectBalances;
@Inject @Inject
@NonTransactionalProvider @NonTransactionalProvider
@@ -205,96 +203,96 @@ public class EventFinanceServiceDAO implements EventFinanceService {
) )
private StatementProvider sqlSelectPersonBalances; private StatementProvider sqlSelectPersonBalances;
@Inject @Inject
@NonTransactionalProvider @NonTransactionalProvider
@GolfProvider @GolfProvider
@Statement( @Statement(
sql = "SELECT TT.personID, TT.epersonID, SUM(TT.expenses) expenses, SUM(TT.paid) paid, (SUM(TT.paid)-SUM(TT.expenses)) balance " sql = "SELECT TT.personID, TT.epersonID, SUM(TT.expenses) expenses, SUM(TT.paid) paid, (SUM(TT.paid)-SUM(TT.expenses)) balance "
+ "FROM (" + "FROM ("
+ " SELECT ALL EP.personID, EP.epersonID, IF(EB.projectedValue IS NULL, 0, EB.projectedValue) expenses, 0 paid " + " SELECT ALL EP.personID, EP.epersonID, IF(EB.projectedValue IS NULL, 0, EB.projectedValue) expenses, 0 paid "
+ " FROM ~g~.Event E " + " FROM ~g~.Event E "
+ " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) " + " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) "
+ " INNER JOIN ~g~.EventBudget EB ON (EP.eventID=EB.eventID) " + " INNER JOIN ~g~.EventBudget EB ON (EP.eventID=EB.eventID) "
+ " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? " + " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? "
+ " UNION ALL " + " UNION ALL "
+ " SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid " + " SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid "
+ " FROM ~g~.Event E " + " FROM ~g~.Event E "
+ " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) " + " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) "
+ " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) " + " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) "
+ " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) " + " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) "
+ " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EPO.answer='Y' AND EO.amount IS NOT NULL AND EO.waive IS FALSE " + " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EPO.answer='Y' AND EO.amount IS NOT NULL AND EO.waive IS FALSE "
+ " UNION ALL " + " UNION ALL "
+ " SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid " + " SELECT ALL EP.personID, EP.epersonID, EO.amount expenses, 0 paid "
+ " FROM ~g~.Event E " + " FROM ~g~.Event E "
+ " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) " + " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) "
+ " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) " + " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) "
+ " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) " + " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) "
+ " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EPO.itemID IS NOT NULL " + " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EPO.itemID IS NOT NULL "
+ " AND (EO.multiple IS FALSE OR EO.funded='option' OR EO.static IS NOT NULL) " + " AND (EO.multiple IS FALSE OR EO.funded='option' OR EO.static IS NOT NULL) "
+ " AND EO.amount IS NOT NULL AND EO.waive IS FALSE " + " AND EO.amount IS NOT NULL AND EO.waive IS FALSE "
+ " UNION ALL " + " UNION ALL "
+ " SELECT ALL EP.personID, EP.epersonID, EOI.amount expenses, 0 paid " + " SELECT ALL EP.personID, EP.epersonID, EOI.amount expenses, 0 paid "
+ " FROM ~g~.Event E " + " FROM ~g~.Event E "
+ " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) " + " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) "
+ " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) " + " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) "
+ " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) " + " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) "
+ " INNER JOIN ~g~.EventOptionItem EOI ON (EPO.itemID=EOI.itemID) " + " INNER JOIN ~g~.EventOptionItem EOI ON (EPO.itemID=EOI.itemID) "
+ " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EO.waive IS FALSE AND EO.funded='selection' AND EOI.amount IS NOT NULL " + " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EO.waive IS FALSE AND EO.funded='selection' AND EOI.amount IS NOT NULL "
+ " UNION ALL " + " UNION ALL "
+ " SELECT ALL EPP.personID, EP.epersonID, 0 expenses, EPP.amount paid " + " SELECT ALL EPP.personID, EP.epersonID, 0 expenses, EPP.amount paid "
+ " FROM ~g~.Event E " + " FROM ~g~.Event E "
+ " INNER JOIN ~g~.EventPersonPayment EPP ON (E.eventID=EPP.eventID) " + " INNER JOIN ~g~.EventPersonPayment EPP ON (E.eventID=EPP.eventID) "
+ " LEFT JOIN ~g~.EventPerson EP ON (EPP.eventID=EP.eventID AND EPP.personID=EP.personID) " + " LEFT JOIN ~g~.EventPerson EP ON (EPP.eventID=EP.eventID AND EPP.personID=EP.personID) "
+ " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<?) TT " + " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<?) TT "
+ "GROUP BY TT.personID" + "GROUP BY TT.personID"
) )
private StatementProvider sqlSelectSeriesBalances; private StatementProvider sqlSelectSeriesBalances;
@Inject @Inject
@NonTransactionalProvider @NonTransactionalProvider
@GolfProvider @GolfProvider
@Statement( @Statement(
sql = "SELECT TT.eventID, TT.epersonID, SUM(TT.expenses) expenses, SUM(TT.paid) paid, (SUM(TT.paid)-SUM(TT.expenses)) balance " sql = "SELECT TT.eventID, TT.epersonID, SUM(TT.expenses) expenses, SUM(TT.paid) paid, (SUM(TT.paid)-SUM(TT.expenses)) balance "
+ "FROM (" + "FROM ("
+ " SELECT ALL E.eventID, EP.epersonID, IF(EB.projectedValue IS NULL, 0, EB.projectedValue) expenses, 0 paid " + " SELECT ALL E.eventID, EP.epersonID, IF(EB.projectedValue IS NULL, 0, EB.projectedValue) expenses, 0 paid "
+ " FROM ~g~.Event E " + " FROM ~g~.Event E "
+ " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) " + " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) "
+ " INNER JOIN ~g~.EventBudget EB ON (EP.eventID=EB.eventID) " + " INNER JOIN ~g~.EventBudget EB ON (EP.eventID=EB.eventID) "
+ " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EP.personID=? " + " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EP.personID=? "
+ " UNION ALL " + " UNION ALL "
+ " SELECT ALL E.eventID, EP.epersonID, EO.amount expenses, 0 paid " + " SELECT ALL E.eventID, EP.epersonID, EO.amount expenses, 0 paid "
+ " FROM ~g~.Event E " + " FROM ~g~.Event E "
+ " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) " + " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) "
+ " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) " + " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) "
+ " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) " + " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) "
+ " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EP.personID=? " + " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EP.personID=? "
+ " AND EPO.answer='Y' AND EO.amount IS NOT NULL AND EO.waive IS FALSE " + " AND EPO.answer='Y' AND EO.amount IS NOT NULL AND EO.waive IS FALSE "
+ " UNION ALL " + " UNION ALL "
+ " SELECT ALL E.eventID, EP.epersonID, EO.amount expenses, 0 paid " + " SELECT ALL E.eventID, EP.epersonID, EO.amount expenses, 0 paid "
+ " FROM ~g~.Event E " + " FROM ~g~.Event E "
+ " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) " + " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) "
+ " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) " + " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) "
+ " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) " + " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) "
+ " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EP.personID=? AND EPO.itemID IS NOT NULL " + " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EP.personID=? AND EPO.itemID IS NOT NULL "
+ " AND (EO.multiple IS FALSE OR EO.funded='option' OR EO.static IS NOT NULL) " + " AND (EO.multiple IS FALSE OR EO.funded='option' OR EO.static IS NOT NULL) "
+ " AND EO.amount IS NOT NULL AND EO.waive IS FALSE " + " AND EO.amount IS NOT NULL AND EO.waive IS FALSE "
+ " UNION ALL " + " UNION ALL "
+ " SELECT ALL E.eventID, EP.epersonID, EOI.amount expenses, 0 paid " + " SELECT ALL E.eventID, EP.epersonID, EOI.amount expenses, 0 paid "
+ " FROM ~g~.Event E " + " FROM ~g~.Event E "
+ " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) " + " INNER JOIN ~g~.EventPerson EP ON (E.eventID=EP.eventID) "
+ " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) " + " INNER JOIN ~g~.EventPersonOption EPO ON (EP.epersonID=EPO.epersonID) "
+ " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) " + " INNER JOIN ~g~.EventOption EO ON (EPO.optionID=EO.optionID) "
+ " INNER JOIN ~g~.EventOptionItem EOI ON (EPO.itemID=EOI.itemID) " + " INNER JOIN ~g~.EventOptionItem EOI ON (EPO.itemID=EOI.itemID) "
+ " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EP.personID=? " + " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EP.personID=? "
+ " AND EO.waive IS FALSE AND EO.funded='selection' AND EOI.amount IS NOT NULL " + " AND EO.waive IS FALSE AND EO.funded='selection' AND EOI.amount IS NOT NULL "
+ " UNION ALL " + " UNION ALL "
+ " SELECT ALL E.eventID, EP.epersonID, 0 expenses, EPP.amount paid " + " SELECT ALL E.eventID, EP.epersonID, 0 expenses, EPP.amount paid "
+ " FROM ~g~.Event E " + " FROM ~g~.Event E "
+ " INNER JOIN ~g~.EventPersonPayment EPP ON (E.eventID=EPP.eventID) " + " INNER JOIN ~g~.EventPersonPayment EPP ON (E.eventID=EPP.eventID) "
+ " LEFT JOIN ~g~.EventPerson EP ON (EPP.eventID=EP.eventID AND EPP.personID=EP.personID) " + " LEFT JOIN ~g~.EventPerson EP ON (EPP.eventID=EP.eventID AND EPP.personID=EP.personID) "
+ " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EPP.personID=?) TT " + " WHERE E.seriesID=? AND E.eventID<>? AND E.liveline<? AND EPP.personID=?) TT "
+ "GROUP BY TT.eventID" + "GROUP BY TT.eventID"
) )
private StatementProvider sqlSelectSeriesPersonEventBalances; private StatementProvider sqlSelectSeriesPersonEventBalances;
} }

View File

@@ -1,14 +1,5 @@
package com.poststats.golf.service.db; package com.poststats.golf.service.db;
import java.math.BigInteger;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.brianlong.sql.DataSet; import com.brianlong.sql.DataSet;
import com.brianlong.sql.FlexPreparedStatement; import com.brianlong.sql.FlexPreparedStatement;
import com.brianlong.util.FlexMap; import com.brianlong.util.FlexMap;
@@ -21,16 +12,23 @@ import com.poststats.provider.StatementProvider;
import com.poststats.service.ServiceException; import com.poststats.service.ServiceException;
import com.poststats.service.db.CacheableServiceDAO; import com.poststats.service.db.CacheableServiceDAO;
import com.poststats.util.Contact; import com.poststats.util.Contact;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject; import jakarta.inject.Inject;
import jakarta.mail.MessagingException; import jakarta.mail.MessagingException;
import java.math.BigInteger;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ApplicationScoped @ApplicationScoped
public class EventPersonServiceDAO extends CacheableServiceDAO<BigInteger> implements EventPersonService { public class EventPersonServiceDAO extends CacheableServiceDAO<BigInteger> implements EventPersonService {
@Inject @Inject
private EventFinanceService eventFinanceService; private EventFinanceService eventFinanceService;
@Override @Override
public FlexMap get(long eventId, long personId) { public FlexMap get(long eventId, long personId) {
@@ -185,173 +183,188 @@ public class EventPersonServiceDAO extends CacheableServiceDAO<BigInteger> imple
+ "WHERE ECL.eventID=? AND ECL.listID=? " + "WHERE ECL.eventID=? AND ECL.listID=? "
) )
private StatementProvider sqlSelectByListId; private StatementProvider sqlSelectByListId;
public List<? extends FlexMap> getByAutolist(long eventId, String autolist) {
switch (autolist) {
case "balance":
Map<Long, DataSet> balances = this.eventFinanceService.getPersonsBalances(eventId, null, -0.01f);
return new ArrayList<>(balances.values());
default:
}
StatementProvider statementProvider = this.getStatementProviderByAutolist(autolist);
try {
FlexPreparedStatement fps = this.getStatementByAutolist(statementProvider, eventId, autolist);
try {
return fps.executeQuery().getAllRows();
} finally {
fps.close();
}
} catch (SQLException se) {
throw new ServiceException(se);
}
}
private StatementProvider getStatementProviderByAutolist(String autolist) { public List<? extends FlexMap> getByAutolist(long eventId, String autolist) {
switch (autolist) { switch (autolist) {
case "all": case "balance":
return this.sqlSelectEventAllIds; Map<Long, DataSet> balances = this.eventFinanceService.getPersonsBalances(eventId, null, -0.01f);
case "signed": return new ArrayList<>(balances.values());
return this.sqlSelectEventParticipantIds; default:
case "unsigned": }
return this.sqlSelectEventRumormillIds;
case "rookies":
return this.sqlSelectEventRookieIds;
case "rookies-refs":
return this.sqlSelectEventRookieReferralIds;
case "options":
return this.sqlSelectEventParticipantIdsWithUnansweredOptions;
default:
}
if (autolist.startsWith("previous")) { StatementProvider statementProvider = this.getStatementProviderByAutolist(autolist);
if (autolist.length() > "previous".length()) { try {
return this.sqlSelectRecentSeriesParticipantIds; FlexPreparedStatement fps = this.getStatementByAutolist(statementProvider, eventId, autolist);
} else { try {
return this.sqlSelectSeriesParticipantIds; return fps.executeQuery().getAllRows();
} } finally {
} else { fps.close();
throw new IllegalArgumentException(); }
} } catch (SQLException se) {
} throw new ServiceException(se);
}
}
private FlexPreparedStatement getStatementByAutolist(StatementProvider statementProvider, long eventId, String autolist) throws SQLException { private StatementProvider getStatementProviderByAutolist(String autolist) {
int weeks = -1; switch (autolist) {
if (autolist.startsWith("previous") && autolist.length() > "previous".length()) case "all":
weeks = Integer.parseInt(autolist.substring("previous".length() + 1)); return this.sqlSelectEventAllIds;
case "signed":
return this.sqlSelectEventParticipantIds;
case "unsigned":
return this.sqlSelectEventRumormillIds;
case "rookies":
return this.sqlSelectEventRookieIds;
case "rookies-refs":
return this.sqlSelectEventRookieReferralIds;
case "options":
return this.sqlSelectEventParticipantIdsWithUnansweredOptions;
default:
}
FlexPreparedStatement fps = statementProvider.buildPreparedStatement(); if (autolist.startsWith("previous")) {
try { if (autolist.length() > "previous".length()) {
int c = 1; return this.sqlSelectRecentSeriesParticipantIds;
fps.setIntegerU(c++, eventId); } else {
if (weeks >= 0) { return this.sqlSelectSeriesParticipantIds;
fps.setIntegerU(c++, eventId); }
fps.setSmallintU(c++, weeks); } else {
fps.setSmallintU(c++, weeks); throw new IllegalArgumentException();
} }
if (autolist.equals("all") || autolist.equals("rookies-refs") || autolist.startsWith("previous")) { }
fps.setIntegerU(c++, eventId);
}
return fps;
} catch (SQLException se) {
fps.close();
throw se;
}
}
@Inject private FlexPreparedStatement getStatementByAutolist(StatementProvider statementProvider, long eventId,
@NonTransactionalProvider String autolist) throws SQLException {
@GolfProvider int weeks = -1;
@Statement(sql = "SELECT personID, epersonID FROM ~g~.EventPerson WHERE eventID=?") if (autolist.startsWith("previous") && autolist.length() > "previous".length())
private StatementProvider sqlSelectEventParticipantIds; weeks = Integer.parseInt(autolist.substring("previous".length() + 1));
@Inject FlexPreparedStatement fps = statementProvider.buildPreparedStatement();
@NonTransactionalProvider try {
@GolfProvider int c = 1;
@Statement(sql = "SELECT personID, NULL epersonID FROM ~g~.EventPersonContract WHERE eventID=?") fps.setIntegerU(c++, eventId);
private StatementProvider sqlSelectEventRumormillIds; if (weeks >= 0) {
fps.setIntegerU(c++, eventId);
fps.setSmallintU(c++, weeks);
fps.setSmallintU(c++, weeks);
}
if (autolist.equals("all") || autolist.equals("rookies-refs") || autolist.startsWith("previous")) {
fps.setIntegerU(c++, eventId);
}
@Inject return fps;
@NonTransactionalProvider } catch (SQLException se) {
@GolfProvider fps.close();
@Statement(sql = "SELECT personID, epersonID FROM ~g~.EventPerson WHERE eventID=? " throw se;
+ "UNION " }
+ "SELECT personID, NULL epersonID FROM ~g~.EventPersonContract WHERE eventID=? ") }
private StatementProvider sqlSelectEventAllIds;
@Inject @Inject
@NonTransactionalProvider @NonTransactionalProvider
@GolfProvider @GolfProvider
@Statement(sql = "SELECT DISTINCT EP.personID, EP.epersonID " @Statement(sql = "SELECT personID, epersonID FROM ~g~.EventPerson WHERE eventID=?")
+ "FROM ~g~.EventPerson EP " private StatementProvider sqlSelectEventParticipantIds;
+ " LEFT JOIN ~g~.EventPerson EP2 ON (EP.eventID<>EP2.eventID AND EP.personID=EP2.personID) "
+ "WHERE EP.eventID=? AND EP2.epersonID IS NULL")
private StatementProvider sqlSelectEventRookieIds;
@Inject @Inject
@NonTransactionalProvider @NonTransactionalProvider
@GolfProvider @GolfProvider
@Statement(sql = "SELECT DISTINCT EP.personID " @Statement(sql = "SELECT personID, NULL epersonID FROM ~g~.EventPersonContract WHERE eventID=?")
+ "FROM ~g~.EventPerson EP " private StatementProvider sqlSelectEventRumormillIds;
+ " LEFT JOIN ~g~.EventPerson EP2 ON (EP.eventID<>EP2.eventID AND EP.personID=EP2.personID) "
+ "WHERE EP.eventID=? AND EP2.epersonID IS NULL "
+ "UNION "
+ "SELECT DISTINCT P.referralPersonID "
+ "FROM ~g~.EventPerson EP "
+ " LEFT JOIN ~g~.EventPerson EP2 ON (EP.eventID<>EP2.eventID AND EP.personID=EP2.personID) "
+ " INNER JOIN ~p~.Person P ON (EP.personID=P.personID) "
+ "WHERE EP.eventID=? AND EP2.epersonID IS NULL AND P.referralPersonID IS NOT NULL")
private StatementProvider sqlSelectEventRookieReferralIds;
@Inject @Inject
@NonTransactionalProvider @NonTransactionalProvider
@GolfProvider @GolfProvider
@Statement(sql = "SELECT EP.personID, EP.epersonID " @Statement(
+ "FROM ~g~.EventPerson EP " sql = "SELECT personID, epersonID FROM ~g~.EventPerson WHERE eventID=? "
+ " INNER JOIN ?TT? TT1 ON (EP.personID=TT1.personID) " + "UNION "
+ "WHERE EP.eventID=? " + "SELECT personID, NULL epersonID FROM ~g~.EventPersonContract WHERE eventID=? "
+ "GROUP BY EP.personID HAVING SUM(TT1.balance) < 0 ") )
private StatementProvider sqlSelectEventParticipantIdsWithBalance; private StatementProvider sqlSelectEventAllIds;
@Inject @Inject
@NonTransactionalProvider @NonTransactionalProvider
@GolfProvider @GolfProvider
@Statement(sql = "SELECT DISTINCT EP.personID, EP.epersonID " @Statement(
+ "FROM ~g~.EventOption EO " sql = "SELECT DISTINCT EP.personID, EP.epersonID "
+ " INNER JOIN ~g~.EventPerson EP ON (EO.eventID=EP.eventID) " + "FROM ~g~.EventPerson EP "
+ " LEFT JOIN ~g~.EventPersonOption EPO ON (EO.optionID=EPO.optionID AND EP.epersonID=EPO.epersonID) " + " LEFT JOIN ~g~.EventPerson EP2 ON (EP.eventID<>EP2.eventID AND EP.personID=EP2.personID) "
+ "WHERE EO.eventID=? " + "WHERE EP.eventID=? AND EP2.epersonID IS NULL"
+ " AND (EO.liveline IS NULL OR EO.liveline<=CURRENT_DATE) " )
+ " AND (EO.deadline IS NULL OR EO.deadline>=CURRENT_DATE) " private StatementProvider sqlSelectEventRookieIds;
+ " AND EPO.optionID IS NULL ")
private StatementProvider sqlSelectEventParticipantIdsWithUnansweredOptions;
@Inject @Inject
@NonTransactionalProvider @NonTransactionalProvider
@GolfProvider @GolfProvider
@Statement(sql = "SELECT DISTINCT EP.personID " @Statement(
+ "FROM ~g~.Event E " sql = "SELECT DISTINCT EP.personID "
+ " INNER JOIN ~g~.Event E2 ON (E.seriesID=E2.seriesID) " + "FROM ~g~.EventPerson EP "
+ " INNER JOIN ~g~.EventPerson EP ON (E2.eventID=EP.eventID) " + " LEFT JOIN ~g~.EventPerson EP2 ON (EP.eventID<>EP2.eventID AND EP.personID=EP2.personID) "
+ "WHERE E.eventID=? AND E2.eventID<>? " + "WHERE EP.eventID=? AND EP2.epersonID IS NULL "
+ "UNION DISTINCT " + "UNION "
+ "SELECT personID FROM ~g~.EventPersonContract WHERE eventID=? ") + "SELECT DISTINCT P.referralPersonID "
private StatementProvider sqlSelectSeriesParticipantIds; + "FROM ~g~.EventPerson EP "
+ " LEFT JOIN ~g~.EventPerson EP2 ON (EP.eventID<>EP2.eventID AND EP.personID=EP2.personID) "
+ " INNER JOIN ~p~.Person P ON (EP.personID=P.personID) "
+ "WHERE EP.eventID=? AND EP2.epersonID IS NULL AND P.referralPersonID IS NOT NULL"
)
private StatementProvider sqlSelectEventRookieReferralIds;
@Inject @Inject
@NonTransactionalProvider @NonTransactionalProvider
@GolfProvider @GolfProvider
@Statement(sql = "SELECT DISTINCT EP.personID " @Statement(
+ "FROM ~g~.Event E " sql = "SELECT EP.personID, EP.epersonID "
+ " INNER JOIN ~g~.Event E2 ON (E.seriesID=E2.seriesID) " + "FROM ~g~.EventPerson EP "
+ " INNER JOIN ~g~.EventPerson EP ON (E2.eventID=EP.eventID) " + " INNER JOIN ?TT? TT1 ON (EP.personID=TT1.personID) "
+ "WHERE E.eventID=? AND E2.eventID<>? " + "WHERE EP.eventID=? "
+ " AND ((E2.deadline IS NOT NULL AND DATE_ADD(E2.deadline, INTERVAL ? WEEK)>=CURRENT_DATE) " + "GROUP BY EP.personID HAVING SUM(TT1.balance) < 0 "
+ " OR (E2.liveline IS NOT NULL AND DATE_ADD(E2.liveline, INTERVAL ? WEEK)>=CURRENT_DATE)) " )
+ "UNION DISTINCT " private StatementProvider sqlSelectEventParticipantIdsWithBalance;
+ "SELECT personID FROM ~g~.EventPersonContract WHERE eventID=? ")
private StatementProvider sqlSelectRecentSeriesParticipantIds; @Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = "SELECT DISTINCT EP.personID, EP.epersonID "
+ "FROM ~g~.EventOption EO "
+ " INNER JOIN ~g~.EventPerson EP ON (EO.eventID=EP.eventID) "
+ " LEFT JOIN ~g~.EventPersonOption EPO ON (EO.optionID=EPO.optionID AND EP.epersonID=EPO.epersonID) "
+ "WHERE EO.eventID=? "
+ " AND (EO.liveline IS NULL OR EO.liveline<=CURRENT_DATE) "
+ " AND (EO.deadline IS NULL OR EO.deadline>=CURRENT_DATE) "
+ " AND EPO.optionID IS NULL "
)
private StatementProvider sqlSelectEventParticipantIdsWithUnansweredOptions;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = "SELECT DISTINCT EP.personID "
+ "FROM ~g~.Event E "
+ " INNER JOIN ~g~.Event E2 ON (E.seriesID=E2.seriesID) "
+ " INNER JOIN ~g~.EventPerson EP ON (E2.eventID=EP.eventID) "
+ "WHERE E.eventID=? AND E2.eventID<>? "
+ "UNION DISTINCT "
+ "SELECT personID FROM ~g~.EventPersonContract WHERE eventID=? "
)
private StatementProvider sqlSelectSeriesParticipantIds;
@Inject
@NonTransactionalProvider
@GolfProvider
@Statement(
sql = "SELECT DISTINCT EP.personID "
+ "FROM ~g~.Event E "
+ " INNER JOIN ~g~.Event E2 ON (E.seriesID=E2.seriesID) "
+ " INNER JOIN ~g~.EventPerson EP ON (E2.eventID=EP.eventID) "
+ "WHERE E.eventID=? AND E2.eventID<>? "
+ " AND ((E2.deadline IS NOT NULL AND DATE_ADD(E2.deadline, INTERVAL ? WEEK)>=CURRENT_DATE) "
+ " OR (E2.liveline IS NOT NULL AND DATE_ADD(E2.liveline, INTERVAL ? WEEK)>=CURRENT_DATE)) "
+ "UNION DISTINCT "
+ "SELECT personID FROM ~g~.EventPersonContract WHERE eventID=? "
)
private StatementProvider sqlSelectRecentSeriesParticipantIds;
@Override @Override
protected DataSet fetchOne(BigInteger epersonId) throws SQLException { protected DataSet fetchOne(BigInteger epersonId) throws SQLException {