Skip to content

Commit 71ba070

Browse files
committed
Progress in the order management rewrite
1 parent eda4b6b commit 71ba070

File tree

9 files changed

+310
-2
lines changed

9 files changed

+310
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
package net.furizon.backend.feature.pretix.order;
2+
3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.core.type.TypeReference;
5+
import com.fasterxml.jackson.databind.ObjectMapper;
6+
import lombok.Builder;
7+
import lombok.Data;
8+
import lombok.RequiredArgsConstructor;
9+
import lombok.extern.slf4j.Slf4j;
10+
import net.furizon.backend.db.entities.pretix.Event;
11+
import net.furizon.backend.db.entities.users.User;
12+
import net.furizon.backend.infrastructure.pretix.Const;
13+
import net.furizon.backend.infrastructure.pretix.model.ExtraDays;
14+
import net.furizon.backend.infrastructure.pretix.model.OrderStatus;
15+
import net.furizon.backend.infrastructure.pretix.model.Sponsorship;
16+
import net.furizon.backend.infrastructure.pretix.service.PretixInformation;
17+
import org.jetbrains.annotations.NotNull;
18+
import org.jetbrains.annotations.Nullable;
19+
20+
import java.time.LocalDate;
21+
import java.time.LocalTime;
22+
import java.time.ZonedDateTime;
23+
import java.util.ArrayList;
24+
import java.util.HashMap;
25+
import java.util.List;
26+
import java.util.Map;
27+
import java.util.Set;
28+
import java.util.TreeSet;
29+
30+
@RequiredArgsConstructor
31+
@Data
32+
@Builder
33+
@Slf4j
34+
public class Order {
35+
36+
@NotNull
37+
private String code;
38+
39+
@NotNull
40+
private OrderStatus orderStatus;
41+
42+
@NotNull
43+
private Sponsorship sponsorship = Sponsorship.NONE;
44+
45+
@NotNull
46+
private ExtraDays extraDays = ExtraDays.NONE;
47+
48+
@NotNull
49+
private final Set<Integer> dailyDays;
50+
51+
private int roomCapacity = 0; // 0 = has no room
52+
53+
@Nullable
54+
private String hotelLocation;
55+
56+
@NotNull
57+
private String pretixOrderSecret;
58+
59+
private boolean hasMembership = false;
60+
61+
private int answersMainPositionId = -1;
62+
63+
private User orderOwner; //TODO load from db! (lazy load?)
64+
65+
private Event orderEvent; //TODO load from db! (lazy load?)
66+
67+
@NotNull
68+
private Map<String, Object> answers;
69+
70+
public boolean isDaily() {
71+
return !dailyDays.isEmpty();
72+
}
73+
74+
public boolean hasDay(int day) {
75+
return dailyDays.contains(day);
76+
}
77+
78+
@NotNull
79+
public String getAnswersJson(PretixInformation pi) {
80+
List<PretixAnswer> answers = new ArrayList<>();
81+
for (String key : this.answers.keySet()) {
82+
Object o = this.answers.get(key);
83+
var identifierOpt = pi.getQuestionIdFromIdentifier(key);
84+
if (identifierOpt.isPresent()) {
85+
int id = identifierOpt.get();
86+
var type = pi.getQuestionTypeFromId(id);
87+
if (type.isPresent()) {
88+
String out = switch (type.get()) {
89+
case NUMBER -> String.valueOf(o);
90+
case STRING_ONE_LINE -> (String) o;
91+
case STRING_MULTI_LINE -> (String) o;
92+
case BOOLEAN -> ((boolean) o) ? "true" : "false";
93+
case LIST_SINGLE_CHOICE -> (String) o;
94+
case LIST_MULTIPLE_CHOICE -> (String) o;
95+
case FILE -> (String) o;
96+
case DATE -> o.toString();
97+
case TIME -> o.toString();
98+
case DATE_TIME -> o.toString();
99+
case COUNTRY_CODE -> (String) o;
100+
case PHONE_NUMBER -> (String) o;
101+
};
102+
103+
if (out != null && !(out = out.strip()).isEmpty()) {
104+
answers.add(new PretixAnswer(id, out));
105+
}
106+
}
107+
}
108+
}
109+
110+
ObjectMapper om = new ObjectMapper();
111+
try {
112+
return om.writeValueAsString(answers);
113+
} catch (JsonProcessingException e) {
114+
log.error("Error while serializing answers for order {}", getCode(), e);
115+
return "[]";
116+
}
117+
}
118+
119+
public static class OrderBuilder {
120+
121+
public OrderBuilder dailyDays(long days) {
122+
dailyDays = new TreeSet<>();
123+
for (int i = 0; i < 63; i++) {
124+
if ((days & (1L << i)) != 0L) {
125+
dailyDays.add(i);
126+
}
127+
}
128+
return this;
129+
}
130+
131+
public OrderBuilder answers(@NotNull String answersStr, @NotNull PretixInformation pi) {
132+
this.answers = new HashMap<String, Object>();
133+
try {
134+
ObjectMapper om = new ObjectMapper();
135+
List<PretixAnswer> answers = om.readValue(answersStr, new TypeReference<List<PretixAnswer>>() {});
136+
for (PretixAnswer answer : answers) {
137+
int questionId = answer.getQuestionId();
138+
var identifier = pi.getQuestionIdentifierFromId(questionId);
139+
if (identifier.isPresent()) {
140+
String answerIdentifier = identifier.get();
141+
String value = answer.getAnswer();
142+
if (value != null) {
143+
var type = pi.getQuestionTypeFromId(questionId);
144+
if (type.isPresent()) {
145+
Object o = switch (type.get()) {
146+
case NUMBER -> Float.parseFloat(value);
147+
case STRING_ONE_LINE -> value;
148+
case STRING_MULTI_LINE -> value;
149+
case BOOLEAN -> value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes");
150+
case LIST_SINGLE_CHOICE -> value;
151+
case LIST_MULTIPLE_CHOICE -> value;
152+
case FILE -> Const.QUESTIONS_FILE_KEEP;
153+
case DATE -> LocalDate.parse(value);
154+
case TIME -> LocalTime.parse(value);
155+
case DATE_TIME -> ZonedDateTime.parse(value);
156+
case COUNTRY_CODE -> value;
157+
case PHONE_NUMBER -> value;
158+
};
159+
this.answers.put(answerIdentifier, o);
160+
}
161+
}
162+
}
163+
}
164+
} catch (JsonProcessingException e) {
165+
log.error("Unable to parse answers json", e);
166+
}
167+
return this;
168+
}
169+
}
170+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package net.furizon.backend.feature.pretix.order;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import lombok.Data;
5+
import org.jetbrains.annotations.Nullable;
6+
7+
@Data
8+
public class PretixAnswer {
9+
10+
@JsonProperty("question")
11+
private final int questionId;
12+
13+
@Nullable
14+
private final String answer;
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package net.furizon.backend.feature.pretix.order;
2+
3+
import lombok.Data;
4+
import org.jetbrains.annotations.NotNull;
5+
6+
import java.util.List;
7+
8+
@Data
9+
public class PretixOrder {
10+
11+
@NotNull
12+
private final String code;
13+
14+
@NotNull
15+
private final String secret;
16+
17+
@NotNull
18+
private final String status;
19+
20+
@NotNull
21+
private final List<PretixPosition> positions;
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package net.furizon.backend.feature.pretix.order;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import lombok.Data;
5+
import org.jetbrains.annotations.NotNull;
6+
7+
import java.util.List;
8+
9+
@Data
10+
public class PretixPosition {
11+
12+
@JsonProperty("item")
13+
private final int itemId;
14+
15+
@JsonProperty("id")
16+
private final int positionId;
17+
18+
@JsonProperty("variation")
19+
private final int variationId;
20+
21+
@NotNull
22+
private final List<PretixAnswer> answers;
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package net.furizon.backend.feature.pretix.order.finder;
2+
3+
public interface OrderFinder {
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package net.furizon.backend.feature.pretix.order.mapper;
2+
3+
import net.furizon.backend.feature.pretix.order.Order;
4+
import net.furizon.backend.infrastructure.pretix.Const;
5+
import net.furizon.backend.infrastructure.pretix.model.ExtraDays;
6+
import net.furizon.backend.infrastructure.pretix.model.OrderStatus;
7+
import net.furizon.backend.infrastructure.pretix.model.Sponsorship;
8+
import net.furizon.backend.infrastructure.pretix.service.PretixInformation;
9+
import org.jetbrains.annotations.NotNull;
10+
import org.jooq.Record;
11+
import org.json.JSONArray;
12+
import org.json.JSONObject;
13+
14+
import java.time.LocalDate;
15+
import java.time.LocalTime;
16+
import java.time.ZonedDateTime;
17+
import java.util.HashMap;
18+
import java.util.Map;
19+
import java.util.Set;
20+
import java.util.TreeSet;
21+
22+
import static net.furizon.jooq.generated.Tables.ORDERS;
23+
24+
public class JooqProductMapper {
25+
@NotNull
26+
public static Order map(Record record, PretixInformation pi) {
27+
return Order.builder()
28+
.code(record.get(ORDERS.ORDER_CODE))
29+
.orderStatus(OrderStatus.values()[record.get(ORDERS.ORDER_STATUS)])
30+
.sponsorship(Sponsorship.values()[record.get(ORDERS.ORDER_SPONSORSHIP_TYPE)])
31+
.extraDays(ExtraDays.values()[record.get(ORDERS.EXTRA_DAYS)])
32+
.dailyDays(record.get(ORDERS.ORDER_DAILY_DAYS))
33+
.roomCapacity(record.get(ORDERS.ROOM_CAPACITY)) //TODO change after db regeneration
34+
.hotelLocation(record.get(ORDERS.HOTEL_LOCATION))
35+
.pretixOrderSecret(record.get(ORDERS.PRETIX_ORDER_SECRET))
36+
.hasMembership(record.get(ORDERS.HAS_MEMBERSHIP))
37+
.answersMainPositionId(record.get(ORDERS.ANSWERS_MAIN_POSITION_ID))
38+
//.orderOwner() TODO
39+
//.orderEvent() TODO
40+
.answers(record.get(ORDERS.ORDER_ANSWERS), pi)
41+
.build();
42+
}
43+
}

application/src/main/java/net/furizon/backend/infrastructure/pretix/service/CachedPretixInformation.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,30 @@ public int getQuestionSecretId() {
8181

8282
@NotNull
8383
@Override
84-
public Optional<QuestionType> getQuestionTypeById(int id) {
84+
public Optional<QuestionType> getQuestionTypeFromId(int id) {
8585
return Optional.ofNullable(questionIdToType.getIfPresent(id));
8686
}
8787

88+
@NotNull
89+
@Override
90+
public Optional<QuestionType> getQuestionTypeFromIdentifier(@NotNull String identifier) {
91+
return Optional.ofNullable(
92+
questionIdToType.getIfPresent(questionIdentifierToId.getIfPresent(identifier))
93+
);
94+
}
95+
96+
@NotNull
97+
@Override
98+
public Optional<String> getQuestionIdentifierFromId(int id) {
99+
return Optional.ofNullable(questionIdToIdentifier.getIfPresent(id));
100+
}
101+
102+
@NotNull
103+
@Override
104+
public Optional<Integer> getQuestionIdFromIdentifier(@NotNull String identifier) {
105+
return Optional.ofNullable(questionIdentifierToId.getIfPresent(identifier));
106+
}
107+
88108
@Override
89109
public void resetCache() {
90110
log.info("[PRETIX] Resetting cache for pretix information");

application/src/main/java/net/furizon/backend/infrastructure/pretix/service/PretixInformation.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,16 @@ public interface PretixInformation {
1313
int getQuestionSecretId();
1414

1515
@NotNull
16-
Optional<QuestionType> getQuestionTypeById(int id);
16+
Optional<QuestionType> getQuestionTypeFromId(int id);
17+
18+
@NotNull
19+
Optional<QuestionType> getQuestionTypeFromIdentifier(@NotNull String identifier);
20+
21+
@NotNull
22+
Optional<String> getQuestionIdentifierFromId(int id);
23+
24+
@NotNull
25+
Optional<Integer> getQuestionIdFromIdentifier(@NotNull String identifier);
1726

1827
void resetCache();
1928
}

db/migrations/000001_model.up.sql

+2
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ CREATE TABLE IF NOT EXISTS orders (
107107
order_answers_main_position_id int4 NOT NULL,
108108
order_daily_days int8 NOT NULL,
109109
order_extra_days_type int2 NULL,
110+
order_room_capacity int2 NULL,
111+
order_hotel_location varchar(255),
110112
has_membership bool NOT NULL,
111113
order_secret varchar(32) NULL,
112114
order_sponsorship_type int2 NULL,

0 commit comments

Comments
 (0)