diff --git a/srv/pom.xml b/srv/pom.xml
index f0ab50e7..df053511 100644
--- a/srv/pom.xml
+++ b/srv/pom.xml
@@ -235,6 +235,7 @@
cds.gen
true
true
+ true
diff --git a/srv/src/main/java/my/bookshop/RatingCalculator.java b/srv/src/main/java/my/bookshop/RatingCalculator.java
index 0539c905..a983da84 100644
--- a/srv/src/main/java/my/bookshop/RatingCalculator.java
+++ b/srv/src/main/java/my/bookshop/RatingCalculator.java
@@ -2,21 +2,18 @@
import static cds.gen.my.bookshop.Bookshop_.BOOKS;
+import cds.gen.my.bookshop.Books;
+import cds.gen.my.bookshop.Reviews;
+import com.sap.cds.Result;
+import com.sap.cds.ql.Select;
+import com.sap.cds.ql.Update;
+import com.sap.cds.services.persistence.PersistenceService;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.OptionalDouble;
import java.util.stream.Stream;
-
import org.springframework.stereotype.Component;
-import com.sap.cds.Result;
-import com.sap.cds.ql.Select;
-import com.sap.cds.ql.Update;
-import com.sap.cds.services.persistence.PersistenceService;
-
-import cds.gen.my.bookshop.Books;
-import cds.gen.my.bookshop.Reviews;
-
/**
* Takes care of calculating the average rating of a book based on its review
* ratings.
@@ -34,8 +31,8 @@ public class RatingCalculator {
* Initializes the ratings for all existing books based on their reviews.
*/
public void initBookRatings() {
- Result result = db.run(Select.from(BOOKS).columns(b -> b.ID()));
- for (Books book : result.listOf(Books.class)) {
+ var result = db.run(Select.from(BOOKS).columns(b -> b.ID()));
+ for (Books book : result) {
setBookRating(book.getId());
}
}
diff --git a/srv/src/main/java/my/bookshop/handlers/AdminServiceAddressHandler.java b/srv/src/main/java/my/bookshop/handlers/AdminServiceAddressHandler.java
index a669f658..240e1025 100644
--- a/srv/src/main/java/my/bookshop/handlers/AdminServiceAddressHandler.java
+++ b/srv/src/main/java/my/bookshop/handlers/AdminServiceAddressHandler.java
@@ -2,16 +2,13 @@
import static cds.gen.adminservice.AdminService_.ADDRESSES;
-import java.time.Duration;
-import java.util.Optional;
-import java.util.stream.Stream;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.stereotype.Component;
-
-import com.sap.cds.Result;
+import cds.gen.adminservice.Addresses;
+import cds.gen.adminservice.Addresses_;
+import cds.gen.adminservice.AdminService_;
+import cds.gen.adminservice.Orders;
+import cds.gen.api_business_partner.ApiBusinessPartner;
+import cds.gen.api_business_partner.ApiBusinessPartner_;
+import cds.gen.api_business_partner.BusinessPartnerChangedContext;
import com.sap.cds.ql.CQL;
import com.sap.cds.ql.Insert;
import com.sap.cds.ql.Predicate;
@@ -33,15 +30,14 @@
import com.sap.cloud.sdk.cloudplatform.resilience.ResilienceConfiguration;
import com.sap.cloud.sdk.cloudplatform.resilience.ResilienceConfiguration.TimeLimiterConfiguration;
import com.sap.cloud.sdk.cloudplatform.resilience.ResilienceDecorator;
-
-import cds.gen.adminservice.Addresses;
-import cds.gen.adminservice.Addresses_;
-import cds.gen.adminservice.AdminService_;
-import cds.gen.adminservice.Orders;
-import cds.gen.api_business_partner.ApiBusinessPartner;
-import cds.gen.api_business_partner.ApiBusinessPartner_;
-import cds.gen.api_business_partner.BusinessPartnerChangedContext;
+import java.time.Duration;
+import java.util.Optional;
+import java.util.stream.Stream;
import my.bookshop.MessageKeys;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
/**
* Custom handler for the Admin Service Addresses, which come from a remote S/4 System
@@ -107,13 +103,13 @@ public void patchAddressId(EventContext context, Stream orders) {
orders.filter(o -> o.getShippingAddressId() != null).forEach(order -> {
String addressId = order.getShippingAddressId();
- Result replica = db.run(Select.from(ADDRESSES).where(a -> a.businessPartner().eq(businessPartner).and(a.ID().eq(addressId))));
+ var replica = db.run(Select.from(ADDRESSES).where(a -> a.businessPartner().eq(businessPartner).and(a.ID().eq(addressId))));
// check if the address was not yet replicated
if(replica.rowCount() < 1) {
logger.info("Replicating Address '{}' from S/4 service", addressId);
Addresses remoteAddress = bupa.run(Select.from(ADDRESSES)
.where(a -> a.businessPartner().eq(businessPartner).and(a.ID().eq(addressId))))
- .single(Addresses.class);
+ .single();
remoteAddress.setTombstone(false);
db.run(Insert.into(ADDRESSES).entry(remoteAddress));
@@ -128,15 +124,15 @@ public void updateBusinessPartnerAddresses(BusinessPartnerChangedContext context
String businessPartner = context.getData().getBusinessPartner();
// fetch affected entries from local replicas
- Result replicas = db.run(Select.from(ADDRESSES).where(a -> a.businessPartner().eq(businessPartner)));
+ var replicas = db.run(Select.from(ADDRESSES).where(a -> a.businessPartner().eq(businessPartner)));
if(replicas.rowCount() > 0) {
logger.info("Updating Addresses for BusinessPartner '{}'", businessPartner);
// fetch changed data from S/4 -> might be less than local due to deletes
- Result remoteAddresses = bupa.run(Select.from(ADDRESSES).where(a -> a.businessPartner().eq(businessPartner)));
+ var remoteAddresses = bupa.run(Select.from(ADDRESSES).where(a -> a.businessPartner().eq(businessPartner)));
// update replicas or add tombstone if external address was deleted
- replicas.streamOf(Addresses.class).forEach(rep -> {
+ replicas.stream().forEach(rep -> {
Optional matching = remoteAddresses
- .streamOf(Addresses.class)
+ .stream()
.filter(ext -> ext.getId().equals(rep.getId()))
.findFirst();
diff --git a/srv/src/main/java/my/bookshop/handlers/AdminServiceAuditHandler.java b/srv/src/main/java/my/bookshop/handlers/AdminServiceAuditHandler.java
index b8837772..c9ed7176 100644
--- a/srv/src/main/java/my/bookshop/handlers/AdminServiceAuditHandler.java
+++ b/srv/src/main/java/my/bookshop/handlers/AdminServiceAuditHandler.java
@@ -2,13 +2,9 @@
import static cds.gen.adminservice.AdminService_.ORDERS;
-import java.util.Arrays;
-import java.util.Optional;
-import java.util.stream.Stream;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.stereotype.Component;
-
+import cds.gen.adminservice.AdminService_;
+import cds.gen.adminservice.Orders;
+import cds.gen.adminservice.Orders_;
import com.sap.cds.ql.Select;
import com.sap.cds.ql.cqn.CqnDelete;
import com.sap.cds.services.EventContext;
@@ -24,10 +20,11 @@
import com.sap.cds.services.handler.annotations.Before;
import com.sap.cds.services.handler.annotations.ServiceName;
import com.sap.cds.services.persistence.PersistenceService;
-
-import cds.gen.adminservice.AdminService_;
-import cds.gen.adminservice.Orders;
-import cds.gen.adminservice.Orders_;
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.stream.Stream;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Component;
/**
* A custom handler that creates AuditLog messages.
@@ -74,7 +71,7 @@ public void beforeUpdateOrUpsertOrder(EventContext context, Stream order
});
}
- @Before(event = { CqnService.EVENT_DELETE }, entity = { Orders_.CDS_NAME })
+ @Before(entity = { Orders_.CDS_NAME })
public void beforeDelete(CdsDeleteEventContext context) {
// prepare a select statement to read old currency code
Select> ordersSelect = toSelect(context.getCqn());
@@ -95,11 +92,11 @@ private void auditCfgChange(final Action action, final ConfigChange cfgChange, E
private Optional readOldOrders(String ordersId) {
// prepare a select statement to read old order number
- Select ordersSelect = Select.from(ORDERS).columns(Orders_::OrderNo)
+ var ordersSelect = Select.from(ORDERS).columns(Orders_::OrderNo)
.where(o -> o.ID().eq(ordersId).and(o.IsActiveEntity().eq(true)));
// read old orders from DB
- return this.db.run(ordersSelect).first(Orders.class);
+ return this.db.run(ordersSelect).first();
}
private static ConfigChange createConfigChange(Orders orders, Orders oldOrders) {
diff --git a/srv/src/main/java/my/bookshop/handlers/AdminServiceHandler.java b/srv/src/main/java/my/bookshop/handlers/AdminServiceHandler.java
index c517f493..a7245171 100644
--- a/srv/src/main/java/my/bookshop/handlers/AdminServiceHandler.java
+++ b/srv/src/main/java/my/bookshop/handlers/AdminServiceHandler.java
@@ -1,22 +1,20 @@
package my.bookshop.handlers;
import static cds.gen.adminservice.AdminService_.ORDERS;
-import static cds.gen.adminservice.AdminService_.ORDER_ITEMS;
import static cds.gen.my.bookshop.Bookshop_.BOOKS;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.UUID;
-import java.util.function.Supplier;
-import java.util.stream.Stream;
-import org.springframework.stereotype.Component;
-import com.sap.cds.Result;
+import cds.gen.adminservice.AdminService;
+import cds.gen.adminservice.AdminService_;
+import cds.gen.adminservice.Books;
+import cds.gen.adminservice.BooksAddToOrderContext;
+import cds.gen.adminservice.BooksCovers;
+import cds.gen.adminservice.Books_;
+import cds.gen.adminservice.OrderItems;
+import cds.gen.adminservice.OrderItems_;
+import cds.gen.adminservice.Orders;
+import cds.gen.adminservice.Upload;
+import cds.gen.adminservice.Upload_;
+import cds.gen.my.bookshop.Bookshop_;
import com.sap.cds.ql.Select;
import com.sap.cds.ql.Update;
import com.sap.cds.ql.Upsert;
@@ -37,20 +35,18 @@
import com.sap.cds.services.handler.annotations.ServiceName;
import com.sap.cds.services.messages.Messages;
import com.sap.cds.services.persistence.PersistenceService;
-
-import cds.gen.adminservice.AdminService;
-import cds.gen.adminservice.AdminService_;
-import cds.gen.adminservice.Books;
-import cds.gen.adminservice.BooksAddToOrderContext;
-import cds.gen.adminservice.BooksCovers;
-import cds.gen.adminservice.Books_;
-import cds.gen.adminservice.OrderItems;
-import cds.gen.adminservice.OrderItems_;
-import cds.gen.adminservice.Orders;
-import cds.gen.adminservice.Upload;
-import cds.gen.adminservice.Upload_;
-import cds.gen.my.bookshop.Bookshop_;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+import java.util.stream.Stream;
import my.bookshop.MessageKeys;
+import org.springframework.stereotype.Component;
/**
* Custom business logic for the "Admin Service" (see admin-service.cds)
@@ -100,11 +96,11 @@ public void beforeCreateOrder(Stream orders, EventContext context) {
// calculate the actual quantity difference
// FIXME this should handle book changes, currently only quantity changes are handled
int diffQuantity = quantity - db.run(Select.from(Bookshop_.ORDER_ITEMS).columns(i -> i.quantity()).byId(orderItem.getId()))
- .first(OrderItems.class).map(i -> i.getQuantity()).orElse(0);
+ .first().map(i -> i.getQuantity()).orElse(0);
// check if enough books are available
- Result result = db.run(Select.from(BOOKS).columns(b -> b.ID(), b -> b.stock(), b -> b.price()).byId(bookId));
- result.first(Books.class).ifPresent(book -> {
+ var result = db.run(Select.from(BOOKS).columns(b -> b.ID(), b -> b.stock(), b -> b.price()).byId(bookId));
+ result.first().ifPresent(book -> {
if (book.getStock() < diffQuantity) {
// Tip: you can have localized messages and use parameters in your messages
messages.error(MessageKeys.BOOK_REQUIRE_STOCK, book.getStock())
@@ -128,38 +124,31 @@ public void beforeCreateOrder(Stream orders, EventContext context) {
});
}
- /**
+ /*
* Calculate the total order value preview when editing an order item
- *
- * @param context
- * @param orderItem
*/
- @Before(event = DraftService.EVENT_DRAFT_PATCH)
- public void patchOrderItems(DraftPatchEventContext context, OrderItems orderItem) {
+ @Before
+ public void patchOrderItems(DraftPatchEventContext context, OrderItems_ ref, OrderItems orderItem) {
// check if quantity or book was updated
Integer quantity = orderItem.getQuantity();
String bookId = orderItem.getBookId();
- String orderItemId = orderItem.getId();
- BigDecimal amount = calculateAmountInDraft(orderItemId, quantity, bookId);
+ BigDecimal amount = calculateAmountInDraft(ref, quantity, bookId);
if (amount != null) {
orderItem.setAmount(amount);
}
}
- /**
+ /*
* Calculate the total order value preview when deleting an order item from the order
- *
- * @param context
*/
- @Before(event = DraftService.EVENT_DRAFT_CANCEL, entity = OrderItems_.CDS_NAME)
- public void cancelOrderItems(DraftCancelEventContext context) {
- String orderItemId = (String) analyzer.analyze(context.getCqn()).targetKeys().get(OrderItems.ID);
- if(orderItemId != null) {
- calculateAmountInDraft(orderItemId, 0, null);
+ @Before
+ public void cancelOrderItems(DraftCancelEventContext context, OrderItems_ ref) {
+ if(ref.asRef().targetSegment().filter().isPresent()) {
+ calculateAmountInDraft(ref, 0, null);
}
}
- private BigDecimal calculateAmountInDraft(String orderItemId, Integer newQuantity, String newBookId) {
+ private BigDecimal calculateAmountInDraft(OrderItems_ ref, Integer newQuantity, String newBookId) {
Integer quantity = newQuantity;
String bookId = newBookId;
if (quantity == null && bookId == null) {
@@ -167,12 +156,11 @@ private BigDecimal calculateAmountInDraft(String orderItemId, Integer newQuantit
}
// get the order item that was updated (to get access to the book price, quantity and order total)
- Result result = adminService.run(Select.from(ORDER_ITEMS)
+ var result = adminService.run(Select.from(ref)
.columns(o -> o.quantity(), o -> o.amount(),
o -> o.book().expand(b -> b.ID(), b -> b.price()),
- o -> o.parent().expand(p -> p.ID(), p -> p.total()))
- .where(o -> o.ID().eq(orderItemId).and(o.IsActiveEntity().eq(false))));
- OrderItems itemToPatch = result.first(OrderItems.class).orElseThrow(notFound(MessageKeys.ORDERITEM_MISSING));
+ o -> o.parent().expand(p -> p.ID(), p -> p.total())));
+ OrderItems itemToPatch = result.single();
BigDecimal bookPrice = null;
// fallback to existing values
@@ -191,9 +179,8 @@ private BigDecimal calculateAmountInDraft(String orderItemId, Integer newQuantit
// get the price of the updated book ID
if(bookPrice == null) {
- result = db.run(Select.from(BOOKS).byId(bookId).columns(b -> b.price()));
- Books book = result.first(Books.class).orElseThrow(notFound(MessageKeys.BOOK_MISSING));
- bookPrice = book.getPrice();
+ var bookResult = db.run(Select.from(BOOKS).byId(bookId).columns(b -> b.price()));
+ bookPrice = bookResult.single().getPrice();
}
// update the amount of the order item
@@ -215,9 +202,9 @@ private BigDecimal calculateAmountInDraft(String orderItemId, Integer newQuantit
* @param context
*/
@On(entity = Books_.CDS_NAME)
- public void addBookToOrder(BooksAddToOrderContext context) {
+ public Orders addBookToOrder(BooksAddToOrderContext context) {
String orderId = context.getOrderId();
- List orders = adminService.run(Select.from(ORDERS).columns(o -> o._all(), o -> o.Items().expand()).where(o -> o.ID().eq(orderId))).listOf(Orders.class);
+ List orders = adminService.run(Select.from(ORDERS).columns(o -> o._all(), o -> o.Items().expand()).where(o -> o.ID().eq(orderId))).list();
Orders order = orders.stream().filter(p -> p.getIsActiveEntity()).findFirst().orElse(null);
// check that the order with given ID exists and is not in draft-mode
@@ -241,9 +228,9 @@ public void addBookToOrder(BooksAddToOrderContext context) {
newItem.setQuantity(context.getQuantity());
order.getItems().add(newItem);
- Orders updatedOrder = adminService.run(Update.entity(ORDERS).data(order)).single(Orders.class);
+ Orders updatedOrder = adminService.run(Update.entity(ORDERS).data(order)).single();
messages.success(MessageKeys.BOOK_ADDED_ORDER);
- context.setResult(updatedOrder);
+ return updatedOrder;
}
/**
@@ -260,7 +247,7 @@ public Upload getUploadSingleton() {
* @param csv
*/
@On
- public void addBooksViaCsv(CdsUpdateEventContext context, Upload upload) {
+ public List addBooksViaCsv(CdsUpdateEventContext context, Upload upload) {
InputStream is = upload.getCsv();
if (is != null) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
@@ -287,7 +274,7 @@ public void addBooksViaCsv(CdsUpdateEventContext context, Upload upload) {
throw new ServiceException(ErrorStatuses.SERVER_ERROR, MessageKeys.BOOK_IMPORT_INVALID_CSV, e);
}
}
- context.setResult(Arrays.asList(upload));
+ return Arrays.asList(upload);
}
@Before(event = {CqnService.EVENT_CREATE, CqnService.EVENT_UPDATE, DraftService.EVENT_DRAFT_NEW, DraftService.EVENT_DRAFT_PATCH})
@@ -296,10 +283,6 @@ public void restoreCoversUpId(CqnStructuredTypeRef ref, BooksCovers cover) {
cover.setUpId((String) analyzer.analyze(ref).rootKeys().get(Books.ID));
}
- private Supplier notFound(String message) {
- return () -> new ServiceException(ErrorStatuses.NOT_FOUND, message);
- }
-
private BigDecimal defaultZero(BigDecimal decimal) {
return decimal == null ? BigDecimal.valueOf(0) : decimal;
}
diff --git a/srv/src/main/java/my/bookshop/handlers/CatalogServiceHandler.java b/srv/src/main/java/my/bookshop/handlers/CatalogServiceHandler.java
index d477c3ff..8230e2e6 100644
--- a/srv/src/main/java/my/bookshop/handlers/CatalogServiceHandler.java
+++ b/srv/src/main/java/my/bookshop/handlers/CatalogServiceHandler.java
@@ -1,18 +1,16 @@
package my.bookshop.handlers;
import static cds.gen.catalogservice.CatalogService_.BOOKS;
-import static cds.gen.catalogservice.CatalogService_.REVIEWS;
-
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import org.springframework.stereotype.Component;
+import cds.gen.catalogservice.Books;
+import cds.gen.catalogservice.BooksAddReviewContext;
+import cds.gen.catalogservice.Books_;
+import cds.gen.catalogservice.CatalogService_;
+import cds.gen.catalogservice.Reviews;
+import cds.gen.catalogservice.SubmitOrderContext;
+import cds.gen.reviewservice.ReviewService;
+import cds.gen.reviewservice.ReviewService_;
import com.sap.cds.Result;
-import com.sap.cds.Struct;
import com.sap.cds.ql.CQL;
import com.sap.cds.ql.Insert;
import com.sap.cds.ql.Select;
@@ -34,17 +32,13 @@
import com.sap.cds.services.messages.Messages;
import com.sap.cds.services.persistence.PersistenceService;
import com.sap.cds.services.request.FeatureTogglesInfo;
-
-import cds.gen.catalogservice.BooksAddReviewContext;
-import cds.gen.catalogservice.Books;
-import cds.gen.catalogservice.Books_;
-import cds.gen.catalogservice.CatalogService_;
-import cds.gen.catalogservice.Reviews;
-import cds.gen.catalogservice.SubmitOrderContext;
-import cds.gen.reviewservice.ReviewService;
-import cds.gen.reviewservice.ReviewService_;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import my.bookshop.MessageKeys;
import my.bookshop.RatingCalculator;
+import org.springframework.stereotype.Component;
/**
* Custom business logic for the "Catalog Service" (see cat-service.cds)
@@ -92,22 +86,18 @@ public List items(List items) {
context.setCqn(copy);
}
- /**
+ /*
* Invokes some validations before creating a review.
- *
- * @param context {@link ReviewContext}
*/
- @Before(entity = Books_.CDS_NAME)
- public void beforeAddReview(BooksAddReviewContext context) {
+ @Before
+ public void beforeAddReview(Books_ ref, BooksAddReviewContext context) {
String user = context.getUserInfo().getName();
- String bookId = (String) analyzer.analyze(context.getCqn()).targetKeys().get(Books.ID);
- Result result = db.run(Select.from(REVIEWS)
- .where(review -> review.book_ID().eq(bookId).and(review.createdBy().eq(user))));
+ var result = db.run(Select.from(ref.reviews())
+ .where(review -> review.createdBy().eq(user)));
if (result.first().isPresent()) {
- throw new ServiceException(ErrorStatuses.METHOD_NOT_ALLOWED, MessageKeys.REVIEW_ADD_FORBIDDEN)
- .messageTarget(REVIEWS, r -> r.createdBy());
+ throw new ServiceException(ErrorStatuses.METHOD_NOT_ALLOWED, MessageKeys.REVIEW_ADD_FORBIDDEN);
}
}
@@ -116,8 +106,8 @@ public void beforeAddReview(BooksAddReviewContext context) {
*
* @param context {@link ReviewContext}
*/
- @On(entity = Books_.CDS_NAME)
- public void onAddReview(BooksAddReviewContext context) {
+ @On
+ public Reviews onAddReview(Books_ ref, BooksAddReviewContext context) {
String bookId = (String) analyzer.analyze(context.getCqn()).targetKeys().get(Books.ID);
cds.gen.reviewservice.Reviews review = cds.gen.reviewservice.Reviews.create();
review.setBookId(bookId);
@@ -126,10 +116,9 @@ public void onAddReview(BooksAddReviewContext context) {
review.setText(context.getText());
Result res = reviewService.run(Insert.into(ReviewService_.REVIEWS).entry(review));
- cds.gen.reviewservice.Reviews inserted = res.single(cds.gen.reviewservice.Reviews.class);
messages.success(MessageKeys.REVIEW_ADDED);
- context.setResult(Struct.access(inserted).as(Reviews.class));
+ return res.single(Reviews.class);
}
/**
@@ -159,10 +148,10 @@ public void setIsReviewable(CdsReadEventContext context, List books) {
return;
}
- CqnSelect query = Select.from(BOOKS, b -> b.filter(b.ID().in(bookIds)).reviews())
+ var query = Select.from(BOOKS, b -> b.filter(b.ID().in(bookIds)).reviews())
.where(r -> r.createdBy().eq(user));
- Set reviewedBooks = db.run(query).streamOf(Reviews.class).map(Reviews::getBookId)
+ Set reviewedBooks = db.run(query).stream().map(Reviews::getBookId)
.collect(Collectors.toSet());
for (Books book : books) {
@@ -173,24 +162,19 @@ public void setIsReviewable(CdsReadEventContext context, List books) {
}
@On
- public void onSubmitOrder(SubmitOrderContext context) {
+ public SubmitOrderContext.ReturnType onSubmitOrder(SubmitOrderContext context) {
Integer quantity = context.getQuantity();
String bookId = context.getBook();
- Optional book = db.run(Select.from(BOOKS).columns(Books_::stock).byId(bookId)).first(Books.class);
-
- book.orElseThrow(() -> new ServiceException(ErrorStatuses.NOT_FOUND, MessageKeys.BOOK_MISSING)
- .messageTarget(BOOKS, b -> b.ID()));
-
- int stock = book.map(Books::getStock).get();
+ Books book = db.run(Select.from(BOOKS).columns(Books_::stock).byId(bookId)).single();
+ int stock = book.getStock();
if (stock >= quantity) {
db.run(Update.entity(BOOKS).byId(bookId).data(Books.STOCK, stock -= quantity));
SubmitOrderContext.ReturnType result = SubmitOrderContext.ReturnType.create();
result.setStock(stock);
-
- context.setResult(result);
+ return result;
} else {
throw new ServiceException(ErrorStatuses.CONFLICT, MessageKeys.ORDER_EXCEEDS_STOCK, quantity);
}
diff --git a/srv/src/main/java/my/bookshop/handlers/HierarchySiblingActionHandler.java b/srv/src/main/java/my/bookshop/handlers/HierarchySiblingActionHandler.java
index 0791daaf..5cd4dfad 100644
--- a/srv/src/main/java/my/bookshop/handlers/HierarchySiblingActionHandler.java
+++ b/srv/src/main/java/my/bookshop/handlers/HierarchySiblingActionHandler.java
@@ -2,23 +2,18 @@
import static cds.gen.adminservice.AdminService_.GENRE_HIERARCHY;
-import java.util.List;
-
-import org.springframework.stereotype.Component;
-
-import com.sap.cds.ql.CQL;
+import cds.gen.adminservice.AdminService_;
+import cds.gen.adminservice.GenreHierarchy;
+import cds.gen.adminservice.GenreHierarchyMoveSiblingContext;
+import cds.gen.adminservice.GenreHierarchy_;
import com.sap.cds.ql.Select;
import com.sap.cds.ql.Update;
-import com.sap.cds.ql.cqn.CqnStructuredTypeRef;
import com.sap.cds.services.handler.EventHandler;
import com.sap.cds.services.handler.annotations.On;
import com.sap.cds.services.handler.annotations.ServiceName;
import com.sap.cds.services.persistence.PersistenceService;
-
-import cds.gen.adminservice.AdminService_;
-import cds.gen.adminservice.GenreHierarchy;
-import cds.gen.adminservice.GenreHierarchyMoveSiblingContext;
-import cds.gen.adminservice.GenreHierarchy_;
+import java.util.List;
+import org.springframework.stereotype.Component;
@Component
@ServiceName(AdminService_.CDS_NAME)
@@ -33,18 +28,18 @@ public class HierarchySiblingActionHandler implements EventHandler {
this.db = db;
}
- @On(entity = GenreHierarchy_.CDS_NAME)
- void onMoveSiblingAction(CqnStructuredTypeRef ref, GenreHierarchyMoveSiblingContext context) {
+ @On
+ void onMoveSiblingAction(GenreHierarchy_ ref, GenreHierarchyMoveSiblingContext context) {
// Find current node and its parent
- GenreHierarchy toMove = db.run(Select.from(CQL.entity(GENRE_HIERARCHY, ref))
+ GenreHierarchy toMove = db.run(Select.from(ref)
.columns(c -> c.ID(), c -> c.parent_ID()))
- .single(GenreHierarchy.class);
+ .single();
// Find all children of the parent, which are siblings of the entry being moved
List siblingNodes = db.run(Select.from(GENRE_HIERARCHY)
.columns(c -> c.ID(), c -> c.siblingRank())
.where(c -> c.parent_ID().eq(toMove.getParentId())))
- .listOf(GenreHierarchy.class);
+ .list();
int oldPosition = 0;
int newPosition = siblingNodes.size();
diff --git a/srv/src/main/java/my/bookshop/handlers/NotesServiceHandler.java b/srv/src/main/java/my/bookshop/handlers/NotesServiceHandler.java
index 5801cf2a..b257b803 100644
--- a/srv/src/main/java/my/bookshop/handlers/NotesServiceHandler.java
+++ b/srv/src/main/java/my/bookshop/handlers/NotesServiceHandler.java
@@ -3,18 +3,14 @@
import static cds.gen.notesservice.NotesService_.ADDRESSES;
import static cds.gen.notesservice.NotesService_.NOTES;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.stream.Collectors;
-
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.stereotype.Component;
-
-import com.sap.cds.Result;
+import cds.gen.api_business_partner.ApiBusinessPartner;
+import cds.gen.api_business_partner.ApiBusinessPartner_;
+import cds.gen.notesservice.Addresses;
+import cds.gen.notesservice.Addresses_;
+import cds.gen.notesservice.Notes;
+import cds.gen.notesservice.NotesService_;
+import cds.gen.notesservice.Notes_;
+import com.sap.cds.CdsResult;
import com.sap.cds.ql.CQL;
import com.sap.cds.ql.Predicate;
import com.sap.cds.ql.Select;
@@ -31,14 +27,15 @@
import com.sap.cds.services.handler.EventHandler;
import com.sap.cds.services.handler.annotations.On;
import com.sap.cds.services.handler.annotations.ServiceName;
-
-import cds.gen.api_business_partner.ApiBusinessPartner;
-import cds.gen.api_business_partner.ApiBusinessPartner_;
-import cds.gen.notesservice.Addresses;
-import cds.gen.notesservice.Addresses_;
-import cds.gen.notesservice.Notes;
-import cds.gen.notesservice.NotesService_;
-import cds.gen.notesservice.Notes_;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
@Component
@ServiceName(NotesService_.CDS_NAME)
@@ -53,24 +50,25 @@ public class NotesServiceHandler implements EventHandler {
}
@On(entity = Addresses_.CDS_NAME)
- Result readAddresses(CdsReadEventContext context) {
+ void readAddresses(CdsReadEventContext context) {
List extends Segment> segments = context.getCqn().ref().segments();
// via note
if(segments.size() == 2 && segments.getFirst().id().equals(Notes_.CDS_NAME)) {
Map noteKeys = analyzer.analyze(context.getCqn()).rootKeys();
- Notes note = context.getService().run(Select.from(NOTES).columns(n -> n.address_businessPartner(), n -> n.address_ID()).matching(noteKeys)).single(Notes.class);
+ Notes note = context.getService().run(Select.from(NOTES).columns(n -> n.address_businessPartner(), n -> n.address_ID()).matching(noteKeys)).single();
CqnSelect addressOfNote = CQL.copy(context.getCqn(), new Modifier() {
@Override
public CqnStructuredTypeRef ref(CqnStructuredTypeRef ref) {
- return CQL.entity(Addresses_.CDS_NAME)
- .filter(p -> p.get(Addresses.BUSINESS_PARTNER).eq(note.getAddressBusinessPartner())
- .and(p.get(Addresses.ID).eq(note.getAddressId())))
+ return CQL.entity(ADDRESSES)
+ .filter(p -> p.businessPartner().eq(note.getAddressBusinessPartner())
+ .and(p.ID().eq(note.getAddressId())))
.asRef();
}
});
- return context.getService().run(addressOfNote);
+ context.setResult(context.getService().run(addressOfNote));
+ return;
}
// notes expanded?
@@ -85,30 +83,30 @@ public List items(List items) {
});
// read addresses
- Result addresses = bupa.run(noNotesExpand);
+ var addresses = CdsResult.of(bupa.run(noNotesExpand), Addresses.class);
// add expanded notes?
CqnExpand notesExpand = notesExpandHolder.get();
if(notesExpand != null) {
- Select> notesSelect = Select.from(NOTES)
+ var notesSelect = Select.from(NOTES)
.columns(ensureSelected(notesExpand.items(), Notes.ADDRESS_BUSINESS_PARTNER, Notes.ADDRESS_ID))
.orderBy(notesExpand.orderBy())
- .where(n -> CQL.or(addresses.streamOf(Addresses.class)
+ .where(n -> CQL.or(addresses.stream()
.map(address -> n.address_businessPartner().eq(address.getBusinessPartner()).and(n.address_ID().eq(address.getId())))
.collect(Collectors.toList()))
.and(predicate(notesExpand.ref().rootSegment())));
- Result notes = context.getService().run(notesSelect);
- for(Addresses address : addresses.listOf(Addresses.class)) {
+ var notes = context.getService().run(notesSelect);
+ for(Addresses address : addresses) {
address.setNotes(
- notes.streamOf(Notes.class)
+ notes.stream()
.filter(n -> n.getAddressBusinessPartner().equals(address.getBusinessPartner())
&& n.getAddressId().equals(address.getId()))
.collect(Collectors.toList()));
}
}
- return addresses;
+ context.setResult(addresses);
}
@On(entity = Notes_.CDS_NAME)
@@ -121,7 +119,7 @@ void readNotes(CdsReadEventContext context) {
@Override
public CqnStructuredTypeRef ref(CqnStructuredTypeRef ref) {
- return CQL.entity(Notes_.CDS_NAME).filter(predicate(segments.get(1))).asRef();
+ return CQL.entity(NOTES).filter(predicate(segments.get(1))).asRef();
}
@Override
@@ -153,10 +151,10 @@ public List items(List items) {
CqnExpand addressExpand = addressExpandHolder.get();
if(addressExpand != null) {
// read notes and join with addresses
- Result notes = context.getService().run(noAddressExpand);
- List notesWithAddresses = notes.streamOf(Notes.class).filter(n -> n.getAddressBusinessPartner() != null && n.getAddressId() != null).collect(Collectors.toList());
+ var notes = CdsResult.of(context.getService().run(noAddressExpand), Notes.class);
+ List notesWithAddresses = notes.stream().filter(n -> n.getAddressBusinessPartner() != null && n.getAddressId() != null).collect(Collectors.toList());
if (notesWithAddresses.size() > 0) {
- Select> addressSelect = Select.from(ADDRESSES)
+ var addressSelect = Select.from(ADDRESSES)
.columns(ensureSelected(addressExpand.items(), Addresses.BUSINESS_PARTNER, Addresses.ID))
.orderBy(addressExpand.orderBy())
.where(a -> CQL.or(notesWithAddresses.stream()
@@ -164,9 +162,9 @@ public List items(List items) {
.collect(Collectors.toList()))
.and(predicate(addressExpand.ref().rootSegment())));
- Result addresses = context.getService().run(addressSelect);
- for(Notes note : notes.listOf(Notes.class)) {
- note.setAddress(addresses.streamOf(Addresses.class)
+ var addresses = context.getService().run(addressSelect);
+ for(Notes note : notes) {
+ note.setAddress(addresses.stream()
.filter(a -> a.getBusinessPartner().equals(note.getAddressBusinessPartner())
&& a.getId().equals(note.getAddressId()))
.findFirst().orElse(null));
diff --git a/srv/src/main/resources/application.yaml b/srv/src/main/resources/application.yaml
index 2096b3cf..5f9dac1d 100644
--- a/srv/src/main/resources/application.yaml
+++ b/srv/src/main/resources/application.yaml
@@ -6,6 +6,8 @@ spring:
jmx:
enabled: true
cds:
+ errors:
+ prefer-service-exception: true
odata-v4:
endpoint.path: "/api"
security: