initial commit

This commit is contained in:
2021-10-03 17:07:01 +02:00
commit 456332f24e
246 changed files with 24590 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>de.bstly.we</groupId>
<artifactId>webstly-main</artifactId>
<version>${revision}</version>
</parent>
<name>membership</name>
<artifactId>webstly-membership</artifactId>
<dependencies>
<dependency>
<groupId>de.bstly.we</groupId>
<artifactId>webstly-core</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,816 @@
/**
*
*/
package de.bstly.we.membership.businesslogic;
import java.io.IOException;
import java.io.Writer;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.Period;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import com.beust.jcommander.internal.Lists;
import com.beust.jcommander.internal.Maps;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import de.bstly.we.businesslogic.PretixManager;
import de.bstly.we.businesslogic.SystemPropertyManager;
import de.bstly.we.businesslogic.support.InstantHelper;
/**
* @author _bastler@bstly.de
*
*/
@Component
public class MembershipManager {
@Autowired
private PretixManager pretixManager;
@Autowired
private SystemPropertyManager systemPropertyManager;
private Logger logger = LoggerFactory.getLogger(MembershipManager.class);
private DateFormat pretixDateFormat = new SimpleDateFormat("yyyy-MM-dd");
/**
*
*/
public void generateMembershipIds() {
String membershipItemId = systemPropertyManager
.get(PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIP_ITEM, "");
int membershipInternalIdQuestion = systemPropertyManager.getInteger(
PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIP_INTERNAL_ID_QUESTION, 0);
int membershipIdQuestion = systemPropertyManager
.getInteger(PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIP_ID_QUESTION, 0);
if (!StringUtils.hasText(membershipItemId) || membershipInternalIdQuestion == 0
|| membershipIdQuestion == 0) {
logger.warn("Required system properties for 'generateMembershipIds' not set!");
return;
}
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
queryParams.add("ordering", "order__datetime");
queryParams.add("item", membershipItemId);
queryParams.add("order__status", "p");
List<JsonObject> orderPositions = fetchAllOrderPositions(
String.format("/api/v1/organizers/%s/events/%s/orderpositions/",
pretixManager.getOrganizer(), pretixManager.getEvent()),
queryParams, Lists.newArrayList());
Map<Instant, JsonObject> newMembershipPositions = new TreeMap<Instant, JsonObject>();
int nextMembershipId = 1;
for (JsonObject orderPosition : orderPositions) {
JsonArray answers = new JsonArray();
if (orderPosition.has("answers")) {
answers = orderPosition.getAsJsonArray("answers");
}
boolean hasInternalMembershipId = false;
int internalMembershipId = getNumberAnswer(orderPosition, membershipInternalIdQuestion);
if (internalMembershipId > 0) {
if (internalMembershipId >= nextMembershipId) {
nextMembershipId = internalMembershipId + 1;
}
hasInternalMembershipId = true;
}
if (!hasInternalMembershipId) {
newMembershipPositions.put(pretixManager.getLastPaymentDateForOrder(
orderPosition.get("order").getAsString()), orderPosition);
} else {
boolean writeMembershipId = true;
JsonObject membershipIdAnswer = getAnswerObject(orderPosition,
membershipIdQuestion);
if (membershipIdAnswer != null) {
int membershipId = Integer.valueOf(membershipIdAnswer.get("answer").getAsInt());
if (internalMembershipId == membershipId) {
writeMembershipId = false;
logger.trace("Order '" + orderPosition.get("order").getAsString()
+ "' already processed, membership id: '" + membershipId + "'");
}
}
if (writeMembershipId) {
if (membershipIdAnswer == null) {
membershipIdAnswer = new JsonObject();
membershipIdAnswer.addProperty("question", membershipIdQuestion);
membershipIdAnswer.add("options", new JsonArray());
membershipIdAnswer.add("option_identifiers", new JsonArray());
answers.add(membershipIdAnswer);
}
membershipIdAnswer.addProperty("answer", internalMembershipId);
JsonObject payload = new JsonObject();
payload.add("answers", answers);
logger.debug(
"Write membershipId for '" + orderPosition.get("order").getAsString()
+ "': " + internalMembershipId);
pretixManager.request(
String.format("/api/v1/organizers/%s/events/%s/orderpositions/%s/",
pretixManager.getOrganizer(), pretixManager.getEvent(),
orderPosition.get("id").getAsString()),
HttpMethod.PATCH, payload);
}
}
}
Iterator<Entry<Instant, JsonObject>> iterator = newMembershipPositions.entrySet()
.iterator();
while (iterator.hasNext()) {
Map.Entry<Instant, JsonObject> entry = iterator.next();
JsonObject orderPosition = entry.getValue();
JsonArray answers = new JsonArray();
if (orderPosition.has("answers")) {
answers = orderPosition.getAsJsonArray("answers");
}
JsonObject membershipInternalIdAnswer = new JsonObject();
membershipInternalIdAnswer.addProperty("question", membershipInternalIdQuestion);
membershipInternalIdAnswer.add("options", new JsonArray());
membershipInternalIdAnswer.add("option_identifiers", new JsonArray());
membershipInternalIdAnswer.addProperty("answer", nextMembershipId);
answers.add(membershipInternalIdAnswer);
JsonObject membershipIdAnswer = new JsonObject();
membershipIdAnswer.addProperty("question", membershipIdQuestion);
membershipIdAnswer.add("options", new JsonArray());
membershipIdAnswer.add("option_identifiers", new JsonArray());
membershipIdAnswer.addProperty("answer", nextMembershipId);
answers.add(membershipIdAnswer);
JsonObject payload = new JsonObject();
payload.add("answers", answers);
logger.debug("Create membershipId for '" + orderPosition.get("order").getAsString()
+ "': " + nextMembershipId);
pretixManager
.request(
String.format("/api/v1/organizers/%s/events/%s/orderpositions/%s/",
pretixManager.getOrganizer(), pretixManager.getEvent(),
orderPosition.get("id").getAsString()),
HttpMethod.PATCH, payload);
nextMembershipId++;
}
}
/**
*
*/
public void activeMemberships() {
String membershipItemId = systemPropertyManager
.get(PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIP_ITEM, "");
String membershipFeeItemId = systemPropertyManager
.get(PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIPFEE_ITEM, "");
int membershipInternalIdQuestion = systemPropertyManager.getInteger(
PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIP_INTERNAL_ID_QUESTION, 0);
int membershipFeeReferenceQuestion = systemPropertyManager.getInteger(
PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIPFEE_REFERENCE_QUESTION, 0);
int membershipActiveQuestion = systemPropertyManager
.getInteger(PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIP_ACTIVE_QUESTION, 0);
if (!StringUtils.hasText(membershipItemId) || !StringUtils.hasText(membershipFeeItemId)
|| membershipInternalIdQuestion == 0 || membershipFeeReferenceQuestion == 0
|| membershipActiveQuestion == 0) {
logger.warn("Required system properties for 'activeMemberships' not set!");
return;
}
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
queryParams.add("ordering", "order__datetime");
queryParams.add("item", membershipItemId);
queryParams.add("order__status", "p");
List<JsonObject> membershipOrderPositions = fetchAllOrderPositions(
String.format("/api/v1/organizers/%s/events/%s/orderpositions/",
pretixManager.getOrganizer(), pretixManager.getEvent()),
queryParams, Lists.newArrayList());
queryParams.remove("item");
queryParams.add("item", membershipFeeItemId);
List<JsonObject> membershipfeeOrderPositions = fetchAllOrderPositions(
String.format("/api/v1/organizers/%s/events/%s/orderpositions/",
pretixManager.getOrganizer(), pretixManager.getEvent()),
queryParams, Lists.newArrayList());
Map<Integer, List<JsonObject>> membershipfeeOrderPositionMap = Maps.newHashMap();
for (JsonObject membershipFeeOrderPosition : membershipfeeOrderPositions) {
int membershipReference = getNumberAnswer(membershipFeeOrderPosition,
membershipFeeReferenceQuestion);
if (!membershipfeeOrderPositionMap.containsKey(membershipReference)) {
membershipfeeOrderPositionMap.put(membershipReference, Lists.newArrayList());
}
membershipfeeOrderPositionMap.get(membershipReference).add(membershipFeeOrderPosition);
}
for (JsonObject membershipOrderPosition : membershipOrderPositions) {
JsonArray answers = new JsonArray();
if (membershipOrderPosition.has("answers")) {
answers = membershipOrderPosition.getAsJsonArray("answers");
}
JsonObject membershipActiveAnswer = getAnswerObject(membershipOrderPosition,
membershipActiveQuestion);
int membershipId = getNumberAnswer(membershipOrderPosition,
membershipInternalIdQuestion);
if (membershipId == 0) {
logger.warn("No membership number found for '"
+ membershipOrderPosition.get("order").getAsString() + "'!");
continue;
}
Instant membershipStart = pretixManager
.getLastPaymentDateForOrder(membershipOrderPosition.get("order").getAsString());
if (membershipStart == null) {
logger.warn("No last payment found for '"
+ membershipOrderPosition.get("order").getAsString() + "'!");
continue;
}
int years = 1;
if (membershipfeeOrderPositionMap.containsKey(membershipId)) {
years += membershipfeeOrderPositionMap.get(membershipId).size();
}
Instant active = InstantHelper.truncate(
InstantHelper.plus(membershipStart, years, ChronoUnit.YEARS), ChronoUnit.YEARS);
String activeAnswer = pretixDateFormat.format(Date.from(active));
if (membershipActiveAnswer == null) {
membershipActiveAnswer = new JsonObject();
membershipActiveAnswer.addProperty("question", membershipActiveQuestion);
membershipActiveAnswer.add("options", new JsonArray());
membershipActiveAnswer.add("option_identifiers", new JsonArray());
answers.add(membershipActiveAnswer);
}
if (!membershipActiveAnswer.has("answer")
|| !activeAnswer.equals(membershipActiveAnswer.get("answer").getAsString())) {
membershipActiveAnswer.addProperty("answer", activeAnswer);
JsonObject payload = new JsonObject();
payload.add("answers", answers);
pretixManager.request(
String.format("/api/v1/organizers/%s/events/%s/orderpositions/%s/",
pretixManager.getOrganizer(), pretixManager.getEvent(),
membershipOrderPosition.get("id").getAsString()),
HttpMethod.PATCH, payload);
logger.debug("Write active state for '"
+ membershipOrderPosition.get("order").getAsString() + "': "
+ activeAnswer);
} else {
logger.trace("Order active state for '"
+ membershipOrderPosition.get("order").getAsString() + "' already set: "
+ activeAnswer);
}
}
}
/**
*
*/
public void createMembershipExtension() {
String membershipItemId = systemPropertyManager
.get(PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIP_ITEM, "");
String membershipFeeItemId = systemPropertyManager
.get(PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIPFEE_ITEM, "");
int membershipInternalIdQuestion = systemPropertyManager.getInteger(
PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIP_INTERNAL_ID_QUESTION, 0);
int membershipFeeReferenceQuestion = systemPropertyManager.getInteger(
PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIPFEE_REFERENCE_QUESTION, 0);
int membershipFeeCodeQuestion = systemPropertyManager
.getInteger(PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIPFEE_CODE_QUESTION, 0);
int membershipActiveQuestion = systemPropertyManager
.getInteger(PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIP_ACTIVE_QUESTION, 0);
int membershipfeeOrderDays = systemPropertyManager
.getInteger(PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIPFEE_ORDER_DAYS, 0);
int membershipfeeReminderDays = systemPropertyManager
.getInteger(PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIPFEE_REMINDER_DAYS, 0);
int membershipfeeReminderQuestion = systemPropertyManager.getInteger(
PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIPFEE_REMINDER_QUESTION, 0);
boolean orderSendmail = systemPropertyManager
.getBoolean(PretixManager.SYSTEM_PROPERTY_PRETIX_ORDER_SENDMAIL, false);
boolean orderTestmode = systemPropertyManager
.getBoolean(PretixManager.SYSTEM_PROPERTY_PRETIX_ORDER_TESTMODE, true);
boolean orderSimulate = systemPropertyManager
.getBoolean(PretixManager.SYSTEM_PROPERTY_PRETIX_ORDER_SIMULATE, false);
if (!StringUtils.hasText(membershipItemId) || !StringUtils.hasText(membershipFeeItemId)
|| membershipInternalIdQuestion == 0 || membershipFeeReferenceQuestion == 0
|| membershipFeeCodeQuestion == 0 || membershipActiveQuestion == 0
|| membershipfeeOrderDays == 0) {
logger.warn("Required system properties for 'createMembershipExtension' not set!");
return;
}
MultiValueMap<String, String> queryMembershipParams = new LinkedMultiValueMap<String, String>();
queryMembershipParams.add("ordering", "order__datetime");
queryMembershipParams.add("item", membershipItemId);
queryMembershipParams.add("order__status", "p");
List<JsonObject> membershipOrderPositions = fetchAllOrderPositions(
String.format("/api/v1/organizers/%s/events/%s/orderpositions/",
pretixManager.getOrganizer(), pretixManager.getEvent()),
queryMembershipParams, Lists.newArrayList());
List<JsonObject> expireMemberships = Lists.newArrayList();
for (JsonObject membershipOrderPosition : membershipOrderPositions) {
Instant active = getDateAnswer(membershipOrderPosition, membershipActiveQuestion);
if (active.isAfter(InstantHelper.truncate(Instant.now(), ChronoUnit.YEARS))
&& InstantHelper.minus(active, membershipfeeOrderDays, ChronoUnit.DAYS)
.isBefore(Instant.now())) {
expireMemberships.add(membershipOrderPosition);
} else {
logger.trace("Membership '" + membershipOrderPosition.get("order").getAsString()
+ "' not expiring in next " + membershipfeeOrderDays + " days.");
}
}
MultiValueMap<String, String> queryMembershipFeeParams = new LinkedMultiValueMap<String, String>();
queryMembershipFeeParams.add("ordering", "order__datetime");
queryMembershipFeeParams.add("item", membershipFeeItemId);
queryMembershipFeeParams.add("order__status__in", "n,e,c");
List<JsonObject> membershipfeeOrderPositions = fetchAllOrderPositions(
String.format("/api/v1/organizers/%s/events/%s/orderpositions/",
pretixManager.getOrganizer(), pretixManager.getEvent()),
queryMembershipFeeParams, Lists.newArrayList());
Map<Integer, List<JsonObject>> membershipfeeOrderPositionMap = Maps.newHashMap();
for (JsonObject membershipfeeOrderPosition : membershipfeeOrderPositions) {
int membershipReference = getNumberAnswer(membershipfeeOrderPosition,
membershipFeeReferenceQuestion);
JsonObject membershipFeeOrder = pretixManager
.getOrder(membershipfeeOrderPosition.get("order").getAsString());
Instant membershipFeeOrderDatetime = OffsetDateTime
.parse(membershipFeeOrder.get("datetime").getAsString()).toInstant();
if (membershipFeeOrderDatetime
.isAfter(InstantHelper.truncate(Instant.now(), ChronoUnit.YEARS))) {
if (!membershipfeeOrderPositionMap.containsKey(membershipReference)) {
membershipfeeOrderPositionMap.put(membershipReference, Lists.newArrayList());
}
membershipfeeOrderPositionMap.get(membershipReference)
.add(membershipfeeOrderPosition);
}
}
for (JsonObject membershipOrderPosition : expireMemberships) {
int membershipId = getNumberAnswer(membershipOrderPosition,
membershipInternalIdQuestion);
Instant active = getDateAnswer(membershipOrderPosition, membershipActiveQuestion);
if (membershipId == 0) {
logger.warn("No membership number found for '"
+ membershipOrderPosition.get("order").getAsString() + "'!");
continue;
}
if (!membershipfeeOrderPositionMap.containsKey(membershipId)
|| membershipfeeOrderPositionMap.get(membershipId).isEmpty()) {
JsonObject membershipOrder = pretixManager
.getOrder(membershipOrderPosition.get("order").getAsString());
JsonObject membershipFeeOrder = new JsonObject();
membershipFeeOrder.add("email", membershipOrder.get("email"));
membershipFeeOrder.add("locale", membershipOrder.get("locale"));
JsonArray membershipFeeOrderPositions = new JsonArray();
JsonObject membershipFeeOrderPosition = new JsonObject();
membershipFeeOrderPosition.addProperty("item", membershipFeeItemId);
JsonArray membershipFeeOrderPositionAnswers = new JsonArray();
JsonObject membershipFeeReferenceAnswer = new JsonObject();
membershipFeeReferenceAnswer.addProperty("question",
membershipFeeReferenceQuestion);
membershipFeeReferenceAnswer.add("options", new JsonArray());
membershipFeeReferenceAnswer.add("option_identifiers", new JsonArray());
membershipFeeReferenceAnswer.addProperty("answer", membershipId);
membershipFeeOrderPositionAnswers.add(membershipFeeReferenceAnswer);
JsonObject membershipFeeCodeAnswer = new JsonObject();
membershipFeeCodeAnswer.addProperty("question",
membershipFeeCodeQuestion);
membershipFeeCodeAnswer.add("options", new JsonArray());
membershipFeeCodeAnswer.add("option_identifiers", new JsonArray());
membershipFeeCodeAnswer.addProperty("answer", membershipOrderPosition.get("order").getAsString());
membershipFeeOrderPositionAnswers.add(membershipFeeCodeAnswer);
membershipFeeOrderPosition.add("answers", membershipFeeOrderPositionAnswers);
membershipFeeOrderPositions.add(membershipFeeOrderPosition);
membershipFeeOrder.add("locale", membershipOrder.get("locale"));
membershipFeeOrder.add("positions", membershipFeeOrderPositions);
if (membershipOrder.has("payments")
&& membershipOrder.getAsJsonArray("payments").size() > 0) {
JsonObject payment = membershipOrder.getAsJsonArray("payments").get(0)
.getAsJsonObject();
membershipFeeOrder.add("payment_provider", payment.get("provider"));
}
membershipFeeOrder.addProperty("send_email", orderSendmail);
membershipFeeOrder.addProperty("testmode", orderTestmode);
membershipFeeOrder.addProperty("simulate", orderSimulate);
membershipFeeOrder = pretixManager.createOrder(membershipFeeOrder);
JsonObject expire = new JsonObject();
Instant expires = InstantHelper.minus(InstantHelper.truncate(
InstantHelper.plus(Instant.now(), 1, ChronoUnit.YEARS), ChronoUnit.YEARS),
1, ChronoUnit.DAYS);
expire.addProperty("expires", pretixDateFormat.format(Date.from(expires)));
membershipFeeOrder = pretixManager
.extendOrder(membershipFeeOrder.get("code").getAsString(), expire);
logger.debug("Create membership fee order: " + membershipFeeOrder.toString());
} else
// send reminder mail for membership fee order
if (membershipfeeReminderDays > 0 && membershipfeeReminderQuestion > 0
&& active.isAfter(InstantHelper.truncate(Instant.now(), ChronoUnit.YEARS))
&& InstantHelper.minus(active, membershipfeeReminderDays, ChronoUnit.DAYS)
.isBefore(Instant.now())) {
for (JsonObject membershipfeeOrderPosition : membershipfeeOrderPositionMap
.get(membershipId)) {
JsonObject membershipFeeOrder = pretixManager
.getOrder(membershipfeeOrderPosition.get("order").getAsString());
if (!"c".equals(membershipFeeOrder.get("status").getAsString())) {
JsonArray membershipfeeAnswers = new JsonArray();
if (membershipfeeOrderPosition.has("answers")) {
membershipfeeAnswers = membershipfeeOrderPosition
.getAsJsonArray("answers");
}
JsonObject membershipReminderAnswer = getAnswerObject(
membershipfeeOrderPosition, membershipfeeReminderQuestion);
if (membershipReminderAnswer == null) {
membershipReminderAnswer = new JsonObject();
membershipReminderAnswer.addProperty("question",
membershipfeeReminderQuestion);
membershipReminderAnswer.add("options", new JsonArray());
membershipReminderAnswer.add("option_identifiers", new JsonArray());
membershipReminderAnswer.addProperty("answer", "false");
membershipfeeAnswers.add(membershipReminderAnswer);
}
if (!membershipReminderAnswer.get("answer").getAsBoolean()) {
membershipReminderAnswer.addProperty("answer", "true");
pretixManager.sendEmail(
membershipfeeOrderPosition.get("order").getAsString());
JsonObject payload = new JsonObject();
payload.add("answers", membershipfeeAnswers);
pretixManager.request(
String.format(
"/api/v1/organizers/%s/events/%s/orderpositions/%s/",
pretixManager.getOrganizer(), pretixManager.getEvent(),
membershipfeeOrderPosition.get("id").getAsString()),
HttpMethod.PATCH, payload);
logger.debug("Send reminder for membership fee order: "
+ membershipfeeOrderPosition.get("order").getAsString());
} else {
logger.debug("Reminder for Membership fee order of'"
+ membershipfeeOrderPosition.get("order").getAsString()
+ "' already created.");
}
} else {
logger.debug("Membership fee order for'"
+ membershipfeeOrderPosition.get("order").getAsString()
+ "' is canceled, no reminder.");
}
}
} else {
logger.debug("Membership fee order for '"
+ membershipOrderPosition.get("order").getAsString()
+ "' already created, no reminder.");
}
}
}
/**
*
*/
public void calculatePrice() {
int membershipItemId = systemPropertyManager
.getInteger(PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIP_ITEM, 0);
String discountPeriod = systemPropertyManager
.get(PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIP_DISCOUNT_PERIOD, "");
if (!StringUtils.hasText(discountPeriod) || membershipItemId == 0) {
logger.warn("Required system properties for 'calculatePrice' not set!");
return;
}
try {
int position = -1;
Period period = Period.parse(discountPeriod);
Period oneYear = Period.ofYears(1);
long variations = InstantHelper.plus(Instant.ofEpochMilli(0), oneYear).getEpochSecond()
/ InstantHelper.plus(Instant.ofEpochMilli(0), period).getEpochSecond();
Instant compare = InstantHelper.truncate(Instant.now(), ChronoUnit.YEARS);
while (compare.isBefore(Instant.now())) {
compare = InstantHelper.plus(compare, period);
position++;
}
JsonObject defaultVariation = new JsonObject();
defaultVariation.addProperty("active", true);
int defaultVariationId = 0;
boolean applyDefault = true;
for (JsonElement variationElement : pretixManager.getVariations(membershipItemId)) {
JsonObject variation = variationElement.getAsJsonObject();
JsonObject variationUpdate = new JsonObject();
int variationId = variation.get("id").getAsInt();
int variationPosition = variation.get("position").getAsInt();
if (variationPosition < variations) {
variationUpdate.addProperty("active", false);
if (variationPosition == 0) {
defaultVariationId = variationId;
}
if (variationPosition == position) {
variationUpdate.addProperty("active", true);
applyDefault = false;
}
pretixManager.updateVariation(membershipItemId, variationId, variationUpdate);
}
}
if (applyDefault && defaultVariationId > 0) {
pretixManager.updateVariation(membershipItemId, defaultVariationId,
defaultVariation);
}
} catch (DateTimeParseException e) {
logger.error("Error in parsing 'pretix.membership.discount.period'!", e);
}
}
/**
*
* @param writer
* @param includeInactive
* @return
*/
public JsonArray membershipCsvExport(Writer writer, boolean includeInactive) {
String membershipItemId = systemPropertyManager
.get(PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIP_ITEM, "0");
int membershipActiveQuestion = systemPropertyManager
.getInteger(PretixManager.SYSTEM_PROPERTY_PRETIX_MEMBERSHIP_ACTIVE_QUESTION, 0);
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
queryParams.add("item", membershipItemId);
queryParams.add("order__status", "p");
JsonArray members = new JsonArray();
List<String> answerHeaders = Lists.newArrayList();
List<JsonObject> orderPositions = fetchAllOrderPositions(
String.format("/api/v1/organizers/%s/events/%s/orderpositions/",
pretixManager.getOrganizer(), pretixManager.getEvent()),
queryParams, Lists.newArrayList());
for (JsonObject orderPosition : orderPositions) {
JsonObject order = pretixManager
.request(
String.format("/api/v1/organizers/%s/events/%s/orders/%s/",
pretixManager.getOrganizer(), pretixManager.getEvent(),
orderPosition.get("order").getAsString()),
HttpMethod.GET, queryParams)
.getAsJsonObject();
JsonObject member = new JsonObject();
member.addProperty("email", order.get("email").getAsString());
JsonObject answers = new JsonObject();
Instant active = null;
if (orderPosition.has("answers")) {
for (JsonElement answerElement : orderPosition.getAsJsonArray("answers")) {
JsonObject answer = answerElement.getAsJsonObject();
String question_identifier = answer.get("question_identifier").getAsString();
if (!answerHeaders.contains(question_identifier)) {
answerHeaders.add(question_identifier);
}
answers.addProperty(question_identifier, answer.get("answer").getAsString());
if (membershipActiveQuestion == answer.get("question").getAsInt()
&& answer.has("answer")) {
Date date;
try {
date = pretixDateFormat.parse(answer.get("answer").getAsString());
active = date.toInstant();
} catch (ParseException e) {
logger.error("Error on parsing active date for '"
+ orderPosition.get("order").getAsString() + "'!", e);
}
}
}
}
member.add("answers", answers);
if (includeInactive || active != null
&& active.isAfter(InstantHelper.truncate(Instant.now(), ChronoUnit.YEARS))) {
members.add(member);
}
}
try (CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT)) {
List<String> csvHeaders = Lists.newArrayList();
csvHeaders.add("email");
csvHeaders.addAll(answerHeaders);
csvPrinter.printRecord(csvHeaders);
for (JsonElement memberElement : members) {
JsonObject member = memberElement.getAsJsonObject();
JsonObject answers = member.getAsJsonObject("answers");
List<String> records = Lists.newArrayList();
records.add(member.get("email").getAsString());
for (String answer : answerHeaders) {
if (answers.has(answer)) {
records.add(answers.get(answer).getAsString());
} else {
records.add(null);
}
}
csvPrinter.printRecord(records);
}
} catch (IOException e) {
e.printStackTrace();
}
return members;
}
/**
*
*/
@Scheduled(cron = "${we.bstly.membership.cron:0 0 0 * * * }")
public void cron() {
generateMembershipIds();
activeMemberships();
createMembershipExtension();
calculatePrice();
}
/**
*
* @param path
* @param queryParams
* @param result
* @return
*/
protected List<JsonObject> fetchAllOrderPositions(String path,
MultiValueMap<String, String> queryParams, List<JsonObject> result) {
JsonObject orderPositions = pretixManager.request(path, HttpMethod.GET, queryParams)
.getAsJsonObject();
for (JsonElement element : orderPositions.getAsJsonArray("results")) {
JsonObject orderPosition = element.getAsJsonObject();
result.add(orderPosition);
}
if (orderPositions.has("next") && !orderPositions.get("next").isJsonNull()) {
return fetchAllOrderPositions(orderPositions.get("next").getAsString(), queryParams,
result);
}
return result;
}
/**
*
* @param orderPosition
* @param question
* @return
*/
protected JsonObject getAnswerObject(JsonObject orderPosition, int question) {
if (orderPosition.has("answers")) {
for (JsonElement answerElement : orderPosition.getAsJsonArray("answers")) {
JsonObject answer = answerElement.getAsJsonObject();
if (question == answer.get("question").getAsInt()) {
return answer;
}
}
}
return null;
}
/**
*
* @param orderPosition
* @param question
* @return
*/
protected int getNumberAnswer(JsonObject orderPosition, int question) {
JsonObject answer = getAnswerObject(orderPosition, question);
if (answer != null && answer.has("answer")) {
return answer.get("answer").getAsInt();
}
return 0;
}
/**
*
* @param orderPosition
* @param question
* @return
*/
protected Instant getDateAnswer(JsonObject orderPosition, int question) {
JsonObject answer = getAnswerObject(orderPosition, question);
if (answer != null && answer.has("answer")) {
try {
return pretixDateFormat.parse(answer.get("answer").getAsString()).toInstant();
} catch (ParseException e) {
logger.error("Error on parsing active date for '"
+ orderPosition.get("order").getAsString() + "' in question '" + question
+ "'!", e);
}
}
return null;
}
}
@@ -0,0 +1,129 @@
/**
*
*/
package de.bstly.we.membership.controller;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import de.bstly.we.controller.BaseController;
import de.bstly.we.controller.support.EntityResponseStatusException;
import de.bstly.we.membership.businesslogic.MembershipManager;
/**
* @author _bastler@bstly.de
*
*/
@RestController
@RequestMapping("/membership")
public class MembershipController extends BaseController {
@Autowired
private MembershipManager membershipManager;
@Value("${we.bstly.pretix.webhook.key:}")
private String WEBHOOK_KEY;
/**
*
* @param response
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PostMapping("/cron")
public void cron(HttpServletResponse response) {
membershipManager.cron();
}
/**
*
* @param response
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PostMapping("/ids")
public void generateMembershipIds(HttpServletResponse response) {
membershipManager.generateMembershipIds();
}
/**
*
* @param response
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PostMapping("/active")
public void activeMemberships(HttpServletResponse response) {
membershipManager.activeMemberships();
}
/**
*
* @param response
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PostMapping("/extension")
public void createMembershipExtension(HttpServletResponse response) {
membershipManager.createMembershipExtension();
}
/**
*
* @param response
*/
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PostMapping("/calculateprice")
public void calculatePrice(HttpServletResponse response) {
membershipManager.calculatePrice();
}
@PreAuthorize("hasRole('ROLE_ADMIN')")
@GetMapping("/export")
public void getMemberMailList(
@RequestParam("includeInactive") Optional<Boolean> includeInactive,
HttpServletResponse response) throws IOException {
response.setContentType("text/csv");
response.setCharacterEncoding(StandardCharsets.UTF_8.name());
membershipManager.membershipCsvExport(response.getWriter(),
includeInactive.isPresent() && includeInactive.get());
}
/**
*
* @param webhookKey
* @param payload
*/
@PostMapping("/pretix/webhook")
public void webhook(@RequestParam("key") String webhookKey, @RequestBody String payload) {
if (!StringUtils.hasText(webhookKey) || !webhookKey.equals(WEBHOOK_KEY)) {
throw new EntityResponseStatusException(HttpStatus.UNAUTHORIZED);
}
JsonObject event = JsonParser.parseString(payload).getAsJsonObject();
if (event.has("action")
&& "pretix.event.order.paid".equals(event.get("action").getAsString())) {
membershipManager.generateMembershipIds();
membershipManager.activeMemberships();
} else {
throw new EntityResponseStatusException(HttpStatus.NO_CONTENT);
}
}
}