From a4fc343578b7f8d489141f0c894472377c0919e4 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Tue, 17 Apr 2018 18:40:39 +0300 Subject: [PATCH 01/66] Add `EnrichmentNotFoundException` --- .../q/EnrichmentNotFoundException.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/EnrichmentNotFoundException.java diff --git a/api-java/src/main/java/javaclasses/mealorder/q/EnrichmentNotFoundException.java b/api-java/src/main/java/javaclasses/mealorder/q/EnrichmentNotFoundException.java new file mode 100644 index 00000000..4550c2af --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/EnrichmentNotFoundException.java @@ -0,0 +1,39 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q; + +/** + * An exception thrown when enrichment cannot be found in + * {@link io.spine.core.EventContext EventContext}. + * + * @author Illia Shepilov + */ +final class EnrichmentNotFoundException extends RuntimeException { + + private static final long serialVersionUID = 0L; + + /** + * @see RuntimeException#RuntimeException(String) + */ + EnrichmentNotFoundException(String message) { + super(message); + } +} From 95ff8350e0e079e927216345d8a0daca68809512 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Tue, 17 Apr 2018 18:41:44 +0300 Subject: [PATCH 02/66] Add `EventEnrichments` --- .../mealorder/q/EventEnrichments.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/EventEnrichments.java diff --git a/api-java/src/main/java/javaclasses/mealorder/q/EventEnrichments.java b/api-java/src/main/java/javaclasses/mealorder/q/EventEnrichments.java new file mode 100644 index 00000000..22871b33 --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/EventEnrichments.java @@ -0,0 +1,57 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q; + +import com.google.common.base.Optional; +import com.google.protobuf.Message; +import io.spine.core.Enrichments; +import io.spine.core.EventContext; + +/** + * Utility class for working with enrichments. + * + * @author Illia Shepilov + */ +final class EventEnrichments { + + /** + * The {@code private} constructor prevents the utility class instantiation. + */ + private EventEnrichments() { + } + + /** + * Obtains enrichment from the {@link EventContext} according to the enrichment class. + * + * @param enrichmentClass the class of the enrichment + * @param context the {@code EventContext} + * @return the enrichment if it is present, throws {@code EnrichmentNotFoundException} otherwise + */ + @SuppressWarnings("Guava") // Spine Java 7 API + static > + T getEnrichment(E enrichmentClass, EventContext context) { + final Optional enrichmentOptional = Enrichments.getEnrichment(enrichmentClass, context); + if (enrichmentOptional.isPresent()) { + return enrichmentOptional.get(); + } + throw new EnrichmentNotFoundException(enrichmentClass + " not found"); + } +} From 3d9e07e4ae466ac1069f05f7347ed364e745c7de Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Tue, 17 Apr 2018 18:42:27 +0300 Subject: [PATCH 03/66] Add util class `Projections` --- .../javaclasses/mealorder/q/Projections.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/Projections.java diff --git a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java new file mode 100644 index 00000000..b1a52a3a --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java @@ -0,0 +1,31 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q; + +final class Projections { + + /** + * The {@code private} constructor prevents the utility class instantiation. + */ + private Projections() { + } + +} From 54a69b8b9633dac43711bec24568dfdc26d7d21a Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 18 Apr 2018 13:20:46 +0300 Subject: [PATCH 04/66] Rework proto files according to UI conception --- .../javaclasses/mealorder/q/values.proto | 23 ++++++++++++------- .../proto/javaclasses/mealorder/values.proto | 9 ++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/model/src/main/proto/javaclasses/mealorder/q/values.proto b/model/src/main/proto/javaclasses/mealorder/q/values.proto index 6d348320..4c7bc270 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/values.proto @@ -47,10 +47,20 @@ message MenuItem { // The vendor name. VendorName vendor_name = 1; - // The collection of dishes. - repeated DishItem dish = 2; + // The collection of categories. + repeated DishesByCategory dishesByCategory = 2; } +// Dishes grouped by category. +// +message DishesByCategory { + + // Category of dishes. + CategoryName category = 1; + + // The collection of dishes. + repeated DishItem dishes = 2; +} // The single dish item of a menu. // // The dish category is used in UI to group dishes. @@ -63,11 +73,8 @@ message DishItem { // The name of a dish. string name = 2; - // The dish category. - string category = 3; - // The dish price. - spine.money.Money price = 4; + spine.money.Money price = 3; } // The item of the menu calendar. @@ -138,8 +145,8 @@ message FullMenuItem { // Date range when a menu is available. MenuDateRange menu_date_range = 2; - // The collection of dishes. - repeated DishItem dish = 3; + // The collection of categories. + repeated DishesByCategory dish = 3; } // The item of the purchase order list. diff --git a/model/src/main/proto/javaclasses/mealorder/values.proto b/model/src/main/proto/javaclasses/mealorder/values.proto index f823dc2e..31aebb4f 100644 --- a/model/src/main/proto/javaclasses/mealorder/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/values.proto @@ -36,6 +36,15 @@ import "spine/change/change.proto"; import "spine/net/email_address.proto"; import "spine/time/time.proto"; +// Name of a category. +// +// Probably it has fixed values. +message CategoryName { + + // Category of a dish. + string value = 1; +} + // The model representing a date range. // message MenuDateRange { From b09631732130c5434457f41176f5c5ca204b1264 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 18 Apr 2018 15:06:41 +0300 Subject: [PATCH 05/66] Create structure for projections --- .../q/FullMenuListViewProjection.java | 68 ++++++++++ .../q/MenuCalendarViewProjection.java | 58 +++++++++ .../mealorder/q/MenuListViewProjection.java | 96 ++++++++++++++ .../MonthlySpendingsReportViewProjection.java | 57 +++++++++ .../mealorder/q/OrderListViewProjection.java | 88 +++++++++++++ ...chaseOrderDetailsByDishViewProjection.java | 104 ++++++++++++++++ ...chaseOrderDetailsByUserViewProjection.java | 104 ++++++++++++++++ .../q/PurchaseOrderListViewProjection.java | 117 ++++++++++++++++++ .../mealorder/q/VendorListViewProjection.java | 69 +++++++++++ .../javaclasses/mealorder/q/values.proto | 2 - 10 files changed, 761 insertions(+), 2 deletions(-) create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/FullMenuListViewProjection.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/VendorListViewProjection.java diff --git a/api-java/src/main/java/javaclasses/mealorder/q/FullMenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/FullMenuListViewProjection.java new file mode 100644 index 00000000..1387479e --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/FullMenuListViewProjection.java @@ -0,0 +1,68 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q; + +import io.spine.core.Subscribe; +import io.spine.server.projection.Projection; +import javaclasses.mealorder.VendorId; +import javaclasses.mealorder.c.event.DateRangeForMenuSet; +import javaclasses.mealorder.c.event.MenuImported; +import javaclasses.mealorder.q.projection.FullMenuListView; +import javaclasses.mealorder.q.projection.FullMenuListViewVBuilder; + +public class FullMenuListViewProjection extends Projection { + + /** + * {@link MenuCalendarViewProjection} is a singleton. + * + *

The {@code ID} value should be the same for all JVMs + * to support work with the same projection from execution to execution. + */ + public static final VendorId ID = VendorId.newBuilder() + .setValue("FullMenuListViewProjectionSingleton") + .build(); + + /** + * Creates a new instance. + * + * @param id the ID for the new instance + * @throws IllegalArgumentException if the ID is not of one of the supported types + */ + public FullMenuListViewProjection(VendorId id) { + super(id); + } + + @Subscribe + void on(DateRangeForMenuSet event) { + getBuilder().clearBookItem() + .clearBookItem(); + getBuilder().clearBookSynopsis() + .clearBookSynopsis(); + } + + @Subscribe + void on(MenuImported event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java new file mode 100644 index 00000000..aed7ef92 --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java @@ -0,0 +1,58 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q; + +import io.spine.core.Subscribe; +import io.spine.server.projection.Projection; +import javaclasses.mealorder.MenuId; +import javaclasses.mealorder.VendorId; +import javaclasses.mealorder.q.projection.MenuCalendarView; +import javaclasses.mealorder.q.projection.MenuCalendarViewVBuilder; + +public class MenuCalendarViewProjection extends Projection { + + /** + * {@link MenuCalendarViewProjection} is a singleton. + * + *

The {@code ID} value should be the same for all JVMs + * to support work with the same projection from execution to execution. + */ + public static final VendorId ID = VendorId.newBuilder() + .setValue("MenuCalendarViewProjectionSingleton") + .build(); + + /** + * Creates a new instance. + * + * @param id the ID for the new instance + * @throws IllegalArgumentException if the ID is not of one of the supported types + */ + public MenuCalendarViewProjection(MenuId id) { + super(id); + } + + @Subscribe + void on(DateRangeForMenuSet event) { + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java new file mode 100644 index 00000000..9d2bd4f6 --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java @@ -0,0 +1,96 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q; + +import io.spine.core.Subscribe; +import io.spine.server.projection.Projection; +import javaclasses.mealorder.MenuId; +import javaclasses.mealorder.c.event.DateRangeForMenuSet; +import javaclasses.mealorder.c.event.MenuImported; +import javaclasses.mealorder.c.event.PurchaseOrderCreated; +import javaclasses.mealorder.q.projection.MenuListView; +import javaclasses.mealorder.q.projection.MenuListViewVBuilder; + +public class MenuListViewProjection extends Projection { + + /** + * Creates a new instance. + * + * @param id the ID for the new instance + * @throws IllegalArgumentException if the ID is not of one of the supported types + */ + public MenuListViewProjection(MenuId id) { + super(id); + } + + @Subscribe + void on(MenuImported event) { + getBuilder().clearBookItem() + .clearBookItem(); + getBuilder().clearBookSynopsis() + .clearBookSynopsis(); + } + + @Subscribe + void on(DateRangeForMenuSet event) { + BookItem bookItem = BookItem.newBuilder() + .setBookId(event.getBookId()) + .setBookCoverUrl(event.getDetails() + .getBookCoverUrl()) + .setTitle(event.getDetails() + .getTitle()) + .addAllCategories(event.getDetails() + .getCategoriesList()) + .setAuthor(event.getDetails() + .getAuthor()) + .setAvailable(true) + .build(); + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderCreated event) { + BookItem bookItem = BookItem.newBuilder() + .setBookId(event.getBookId()) + .setBookCoverUrl(event.getBookDetailsChange() + .getNewBookDetails() + .getBookCoverUrl()) + .setTitle(event.getBookDetailsChange() + .getNewBookDetails() + .getTitle()) + .addAllCategories(event.getBookDetailsChange() + .getNewBookDetails() + .getCategoriesList()) + .setAuthor(event.getBookDetailsChange() + .getNewBookDetails() + .getAuthor()) + .setAvailable(true) + .build(); + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getBookDetailsChange() + .getNewBookDetails() + .getSynopsis()); + } +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java new file mode 100644 index 00000000..3fa3e4b4 --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java @@ -0,0 +1,57 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q; + +import io.spine.core.Subscribe; +import io.spine.server.projection.Projection; +import javaclasses.mealorder.VendorId; +import javaclasses.mealorder.c.event.PurchaseOrderDelivered; +import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.q.projection.MonthlySpendingsReportView; +import javaclasses.mealorder.q.projection.MonthlySpendingsReportViewVBuilder; + +public class MonthlySpendingsReportViewProjection extends Projection { + + /** + * Creates a new instance. + * + * @param id the ID for the new instance + * @throws IllegalArgumentException if the ID is not of one of the supported types + */ + public MonthlySpendingsReportViewProjection(VendorId id) { + super(id); + } + + @Subscribe + void on(PurchaseOrderDelivered event) { + getBuilder().clearBookItem() + .clearBookItem(); + getBuilder().clearBookSynopsis() + .clearBookSynopsis(); + } + + @Subscribe + void on(PurchaseOrderSent event) { + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java new file mode 100644 index 00000000..5a79bff3 --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java @@ -0,0 +1,88 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q; + +import io.spine.core.Subscribe; +import io.spine.server.projection.Projection; +import javaclasses.mealorder.OrderId; +import javaclasses.mealorder.c.event.DishAddedToOrder; +import javaclasses.mealorder.c.event.DishRemovedFromOrder; +import javaclasses.mealorder.c.event.OrderCanceled; +import javaclasses.mealorder.c.event.OrderProcessed; +import javaclasses.mealorder.q.projection.OrderListView; +import javaclasses.mealorder.q.projection.OrderListViewVBuilder; + +public class OrderListViewProjection extends Projection { + + /** + * Creates a new instance. + * + * @param id the ID for the new instance + * @throws IllegalArgumentException if the ID is not of one of the supported types + */ + public OrderListViewProjection(OrderId id) { + super(id); + } + + @Subscribe + void on(DishAddedToOrder event) { + getBuilder().clearBookItem() + .clearBookItem(); + getBuilder().clearBookSynopsis() + .clearBookSynopsis(); + } + + @Subscribe + void on(DishRemovedFromOrder event) { + BookItem bookItem = BookItem.newBuilder() + .setBookId(event.getBookId()) + .setBookCoverUrl(event.getDetails() + .getBookCoverUrl()) + .setTitle(event.getDetails() + .getTitle()) + .addAllCategories(event.getDetails() + .getCategoriesList()) + .setAuthor(event.getDetails() + .getAuthor()) + .setAvailable(true) + .build(); + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(OrderCanceled event) { + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getBookDetailsChange() + .getNewBookDetails() + .getSynopsis()); + } + + @Subscribe + void on(OrderProcessed event) { + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getBookDetailsChange() + .getNewBookDetails() + .getSynopsis()); + } +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java new file mode 100644 index 00000000..5aac6673 --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java @@ -0,0 +1,104 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q; + +import io.spine.core.Subscribe; +import io.spine.server.projection.Projection; +import javaclasses.mealorder.PurchaseOrderId; +import javaclasses.mealorder.c.event.PurchaseOrderCanceled; +import javaclasses.mealorder.c.event.PurchaseOrderCreated; +import javaclasses.mealorder.c.event.PurchaseOrderDelivered; +import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.c.event.PurchaseOrderValidationFailed; +import javaclasses.mealorder.c.event.PurchaseOrderValidationOverruled; +import javaclasses.mealorder.c.event.PurchaseOrderValidationPassed; +import javaclasses.mealorder.q.projection.PurchaseOrderDetailsByDishView; +import javaclasses.mealorder.q.projection.PurchaseOrderDetailsByDishViewVBuilder; + +public class PurchaseOrderDetailsByDishViewProjection extends Projection { + + /** + * Creates a new instance. + * + * @param id the ID for the new instance + * @throws IllegalArgumentException if the ID is not of one of the supported types + */ + public PurchaseOrderDetailsByDishViewProjection(PurchaseOrderId id) { + super(id); + } + + @Subscribe + void on(PurchaseOrderCreated event) { + getBuilder().clearBookItem() + .clearBookItem(); + getBuilder().clearBookSynopsis() + .clearBookSynopsis(); + } + + @Subscribe + void on(PurchaseOrderDelivered event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderSent event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderValidationFailed event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderValidationOverruled event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderValidationPassed event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderCanceled event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java new file mode 100644 index 00000000..6fc0299d --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java @@ -0,0 +1,104 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q; + +import io.spine.core.Subscribe; +import io.spine.server.projection.Projection; +import javaclasses.mealorder.PurchaseOrderId; +import javaclasses.mealorder.c.event.PurchaseOrderCanceled; +import javaclasses.mealorder.c.event.PurchaseOrderCreated; +import javaclasses.mealorder.c.event.PurchaseOrderDelivered; +import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.c.event.PurchaseOrderValidationFailed; +import javaclasses.mealorder.c.event.PurchaseOrderValidationOverruled; +import javaclasses.mealorder.c.event.PurchaseOrderValidationPassed; +import javaclasses.mealorder.q.projection.PurchaseOrderDetailsByUserView; +import javaclasses.mealorder.q.projection.PurchaseOrderDetailsByUserViewVBuilder; + +public class PurchaseOrderDetailsByUserViewProjection extends Projection { + + /** + * Creates a new instance. + * + * @param id the ID for the new instance + * @throws IllegalArgumentException if the ID is not of one of the supported types + */ + public PurchaseOrderDetailsByUserViewProjection(PurchaseOrderId id) { + super(id); + } + + @Subscribe + void on(PurchaseOrderCreated event) { + getBuilder().clearBookItem() + .clearBookItem(); + getBuilder().clearBookSynopsis() + .clearBookSynopsis(); + } + + @Subscribe + void on(PurchaseOrderDelivered event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderSent event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderValidationFailed event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderValidationOverruled event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderValidationPassed event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderCanceled event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java new file mode 100644 index 00000000..e0d8aa7f --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java @@ -0,0 +1,117 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q; + +import io.spine.core.Subscribe; +import io.spine.server.projection.Projection; +import javaclasses.mealorder.PurchaseOrderId; +import javaclasses.mealorder.VendorId; +import javaclasses.mealorder.c.event.PurchaseOrderCanceled; +import javaclasses.mealorder.c.event.PurchaseOrderCreated; +import javaclasses.mealorder.c.event.PurchaseOrderDelivered; +import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.c.event.PurchaseOrderValidationFailed; +import javaclasses.mealorder.c.event.PurchaseOrderValidationOverruled; +import javaclasses.mealorder.c.event.PurchaseOrderValidationPassed; +import javaclasses.mealorder.q.projection.PurchaseOrderListView; +import javaclasses.mealorder.q.projection.PurchaseOrderListViewVBuilder; + +public class PurchaseOrderListViewProjection extends Projection { + + /** + * {@link MenuCalendarViewProjection} is a singleton. + * + *

The {@code ID} value should be the same for all JVMs + * to support work with the same projection from execution to execution. + */ + public static final PurchaseOrderId ID = PurchaseOrderId.newBuilder() + .setVendorId(VendorId.newBuilder() + .setValue( + "PurchaseOrderListViewProjectionSingleton")) + .build(); + + /** + * Creates a new instance. + * + * @param id the ID for the new instance + * @throws IllegalArgumentException if the ID is not of one of the supported types + */ + public PurchaseOrderListViewProjection(PurchaseOrderId id) { + super(id); + } + + @Subscribe + void on(PurchaseOrderCreated event) { + getBuilder().clearBookItem() + .clearBookItem(); + getBuilder().clearBookSynopsis() + .clearBookSynopsis(); + } + + @Subscribe + void on(PurchaseOrderDelivered event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderSent event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderValidationFailed event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderValidationOverruled event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderValidationPassed event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + + @Subscribe + void on(PurchaseOrderCanceled event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } + +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/VendorListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/VendorListViewProjection.java new file mode 100644 index 00000000..925de8dd --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/VendorListViewProjection.java @@ -0,0 +1,69 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q; + +import io.spine.core.Subscribe; +import io.spine.server.projection.Projection; +import javaclasses.mealorder.VendorId; +import javaclasses.mealorder.c.event.VendorAdded; +import javaclasses.mealorder.c.event.VendorUpdated; +import javaclasses.mealorder.q.projection.VendorListView; +import javaclasses.mealorder.q.projection.VendorListViewVBuilder; + +public class VendorListViewProjection extends Projection { + + /** + * {@link VendorListViewProjection} is a singleton. + * + *

The {@code ID} value should be the same for all JVMs + * to support work with the same projection from execution to execution. + */ + public static final VendorId ID = VendorId.newBuilder() + .setValue("VendorListViewProjectionSingleton") + .build(); + + /** + * Creates a new instance. + * + * @param id the ID for the new instance + * @throws IllegalArgumentException if the ID is not of one of the supported types + */ + public VendorListViewProjection(VendorId id) { + super(id); + } + + @Subscribe + void on(VendorAdded event) { + getBuilder().clearBookItem() + .clearBookItem(); + getBuilder().clearBookSynopsis() + .clearBookSynopsis(); + } + + @Subscribe + void on(VendorUpdated event) { + + getBuilder().setBookItem(bookItem); + getBuilder().setBookSynopsis(event.getDetails() + .getSynopsis()); + } +} + diff --git a/model/src/main/proto/javaclasses/mealorder/q/values.proto b/model/src/main/proto/javaclasses/mealorder/q/values.proto index 4c7bc270..562ebf08 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/values.proto @@ -63,8 +63,6 @@ message DishesByCategory { } // The single dish item of a menu. // -// The dish category is used in UI to group dishes. -// message DishItem { // The identifier of a dish. From 5f57adec27a7d16b97f737c5b8a2610201325386 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 18 Apr 2018 17:26:31 +0300 Subject: [PATCH 06/66] Handle some events in projections --- .../q/MenuCalendarViewProjection.java | 3 + .../mealorder/q/MenuListViewProjection.java | 68 ++++++++----------- .../MonthlySpendingsReportViewProjection.java | 14 +--- .../javaclasses/mealorder/q/projections.proto | 4 +- .../javaclasses/mealorder/q/values.proto | 6 ++ 5 files changed, 41 insertions(+), 54 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java index aed7ef92..ab1d7c6c 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java @@ -22,8 +22,10 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; +import javaclasses.mealorder.MenuDateRange; import javaclasses.mealorder.MenuId; import javaclasses.mealorder.VendorId; +import javaclasses.mealorder.c.event.DateRangeForMenuSet; import javaclasses.mealorder.q.projection.MenuCalendarView; import javaclasses.mealorder.q.projection.MenuCalendarViewVBuilder; @@ -51,6 +53,7 @@ public MenuCalendarViewProjection(MenuId id) { @Subscribe void on(DateRangeForMenuSet event) { + final MenuDateRange menuDateRange = event.getMenuDateRange(); getBuilder().setBookItem(bookItem); getBuilder().setBookSynopsis(event.getDetails() .getSynopsis()); diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java index 9d2bd4f6..813aea8a 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java @@ -22,13 +22,17 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; +import javaclasses.mealorder.Dish; import javaclasses.mealorder.MenuId; +import javaclasses.mealorder.VendorName; import javaclasses.mealorder.c.event.DateRangeForMenuSet; import javaclasses.mealorder.c.event.MenuImported; import javaclasses.mealorder.c.event.PurchaseOrderCreated; import javaclasses.mealorder.q.projection.MenuListView; import javaclasses.mealorder.q.projection.MenuListViewVBuilder; +import java.util.List; + public class MenuListViewProjection extends Projection { /** @@ -43,54 +47,38 @@ public MenuListViewProjection(MenuId id) { @Subscribe void on(MenuImported event) { - getBuilder().clearBookItem() - .clearBookItem(); - getBuilder().clearBookSynopsis() - .clearBookSynopsis(); + final VendorName vendorName = VendorName.newBuilder() + .setValue(event.getVendorId() + .getValue()) + .build(); + final Iterable allDishesByCategories = getAllDishesByCategories( + event.getDishList()); + final MenuItem menuItem = MenuItem.newBuilder() + .setVendorName(vendorName) + .setIsAvailable(true) + .addAllDishesByCategory(allDishesByCategories) + .build(); + getBuilder().addMenu(menuItem); } + @Subscribe void on(DateRangeForMenuSet event) { - BookItem bookItem = BookItem.newBuilder() - .setBookId(event.getBookId()) - .setBookCoverUrl(event.getDetails() - .getBookCoverUrl()) - .setTitle(event.getDetails() - .getTitle()) - .addAllCategories(event.getDetails() - .getCategoriesList()) - .setAuthor(event.getDetails() - .getAuthor()) - .setAvailable(true) - .build(); - - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); + final List menuItems = getBuilder().getMenu(); + final MenuItem menuItem = menuItems.get(menuItems.size() - 1); + final MenuItem newMenuItem = MenuItem.newBuilder(menuItem) + .setMenuDateRange(event.getMenuDateRange()) + .build(); + getBuilder().setMenu(menuItems.size() - 1, newMenuItem); } @Subscribe void on(PurchaseOrderCreated event) { - BookItem bookItem = BookItem.newBuilder() - .setBookId(event.getBookId()) - .setBookCoverUrl(event.getBookDetailsChange() - .getNewBookDetails() - .getBookCoverUrl()) - .setTitle(event.getBookDetailsChange() - .getNewBookDetails() - .getTitle()) - .addAllCategories(event.getBookDetailsChange() - .getNewBookDetails() - .getCategoriesList()) - .setAuthor(event.getBookDetailsChange() - .getNewBookDetails() - .getAuthor()) - .setAvailable(true) - .build(); + //Todo: somehow disables menus + } - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getBookDetailsChange() - .getNewBookDetails() - .getSynopsis()); + private Iterable getAllDishesByCategories( + List dishList) { + return null; } } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java index 3fa3e4b4..eeff779f 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java @@ -22,13 +22,12 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; -import javaclasses.mealorder.VendorId; +import javaclasses.mealorder.MenuListId; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; -import javaclasses.mealorder.c.event.PurchaseOrderSent; import javaclasses.mealorder.q.projection.MonthlySpendingsReportView; import javaclasses.mealorder.q.projection.MonthlySpendingsReportViewVBuilder; -public class MonthlySpendingsReportViewProjection extends Projection { +public class MonthlySpendingsReportViewProjection extends Projection { /** * Creates a new instance. @@ -36,7 +35,7 @@ public class MonthlySpendingsReportViewProjection extends Projection Date: Wed, 18 Apr 2018 18:06:04 +0300 Subject: [PATCH 07/66] Add subscriber for calendar view --- .../q/MenuCalendarViewProjection.java | 54 +++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java index ab1d7c6c..b1f0fa6a 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java @@ -22,6 +22,7 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; +import io.spine.time.LocalDate; import javaclasses.mealorder.MenuDateRange; import javaclasses.mealorder.MenuId; import javaclasses.mealorder.VendorId; @@ -29,6 +30,12 @@ import javaclasses.mealorder.q.projection.MenuCalendarView; import javaclasses.mealorder.q.projection.MenuCalendarViewVBuilder; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; + public class MenuCalendarViewProjection extends Projection { /** @@ -54,8 +61,49 @@ public MenuCalendarViewProjection(MenuId id) { @Subscribe void on(DateRangeForMenuSet event) { final MenuDateRange menuDateRange = event.getMenuDateRange(); - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); + Date start = new Date(menuDateRange.getRangeStart() + .getYear(), menuDateRange.getRangeStart() + .getMonth() + .getNumber(), + menuDateRange.getRangeStart() + .getDay()); + Date end = new Date(menuDateRange.getRangeEnd() + .getYear(), menuDateRange.getRangeEnd() + .getMonth() + .getNumber(), + menuDateRange.getRangeEnd() + .getDay()); + final List datesBetween = getDatesBetween(start, end); + datesBetween.forEach(date -> { + getBuilder().addCalendarItem(MenuCalendarItem.newBuilder() + .setDate(toLocalDate(date)) + .setHasMenu(true) + .build()); + }); + } + + private LocalDate toLocalDate(Date date) { + return LocalDate.newBuilder() + .setDay(date.getDay()) + .setMonthValue(date.getMonth()) + .setYear(date.getYear()) + .build(); + } + + private List getDatesBetween( + Date startDate, Date endDate) { + List datesInRange = new ArrayList<>(); + Calendar calendar = new GregorianCalendar(); + calendar.setTime(startDate); + + Calendar endCalendar = new GregorianCalendar(); + endCalendar.setTime(endDate); + + while (calendar.before(endCalendar)) { + Date result = calendar.getTime(); + datesInRange.add(result); + calendar.add(Calendar.DATE, 1); + } + return datesInRange; } } From 6e30e6bd99e22d761858a038657d4d15fe2bdf80 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 18 Apr 2018 19:03:48 +0300 Subject: [PATCH 08/66] Add handling for addition and removing dish from order --- .../mealorder/q/OrderListViewProjection.java | 66 +++++++++++++------ .../javaclasses/mealorder/q/projections.proto | 3 + 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java index 5a79bff3..276a5924 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java @@ -22,6 +22,7 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; +import javaclasses.mealorder.Dish; import javaclasses.mealorder.OrderId; import javaclasses.mealorder.c.event.DishAddedToOrder; import javaclasses.mealorder.c.event.DishRemovedFromOrder; @@ -30,6 +31,9 @@ import javaclasses.mealorder.q.projection.OrderListView; import javaclasses.mealorder.q.projection.OrderListViewVBuilder; +import java.util.List; +import java.util.Optional; + public class OrderListViewProjection extends Projection { /** @@ -44,30 +48,36 @@ public OrderListViewProjection(OrderId id) { @Subscribe void on(DishAddedToOrder event) { - getBuilder().clearBookItem() - .clearBookItem(); - getBuilder().clearBookSynopsis() - .clearBookSynopsis(); + final OrderId orderId = event.getOrderId(); + final DishItem dish = DishItem.newBuilder() + .setName(event.getDish() + .getName()) + .setPrice(event.getDish() + .getPrice()) + .build(); + if (getBuilder().getOrder() + .contains(getOrderById(orderId))) { + getBuilder().setOrder(getBuilder().getOrder() + .indexOf(getOrderById(orderId)), + OrderItem.newBuilder(getOrderById(orderId)) + .addDish(dish) + .build()); + } else { + getBuilder().addOrder(OrderItem.newBuilder() + .addDish(dish) + .setId(event.getOrderId()) + .build()); + } } @Subscribe void on(DishRemovedFromOrder event) { - BookItem bookItem = BookItem.newBuilder() - .setBookId(event.getBookId()) - .setBookCoverUrl(event.getDetails() - .getBookCoverUrl()) - .setTitle(event.getDetails() - .getTitle()) - .addAllCategories(event.getDetails() - .getCategoriesList()) - .setAuthor(event.getDetails() - .getAuthor()) - .setAvailable(true) - .build(); - - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); + final List orderItems = getBuilder().getOrder(); + final int removeIndex = getDishFromOrder(event.getDish(), getOrderById(event.getOrderId())); + final OrderItem newOrder = OrderItem.newBuilder(getOrderById(event.getOrderId())) + .removeDish(removeIndex) + .build(); + getBuilder().setOrder(orderItems.indexOf(getOrderById(event.getOrderId())), newOrder); } @Subscribe @@ -85,4 +95,20 @@ void on(OrderProcessed event) { .getNewBookDetails() .getSynopsis()); } + + private OrderItem getOrderById(OrderId orderId) { + final List orderItems = getBuilder().getOrder(); + final Optional inventoryItem = + orderItems.stream() + .filter(item -> item.getId() + .equals(orderId)) + .findFirst(); + return inventoryItem.get(); + } + + private int getDishFromOrder(Dish dish, OrderItem order) { + return order.getDishList() + .indexOf(dish); + } + } diff --git a/model/src/main/proto/javaclasses/mealorder/q/projections.proto b/model/src/main/proto/javaclasses/mealorder/q/projections.proto index a71459eb..eef489cc 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/projections.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/projections.proto @@ -101,6 +101,9 @@ message OrderListView { // The collection of user's orders. repeated OrderItem order = 2; + + // If true user cannot add or remove dishes. + bool processed = 3; } // **** Projections for UI role Admin. **** From 029cec1710050b5d24f97efe480f3aa123fdc787 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Thu, 19 Apr 2018 14:44:02 +0300 Subject: [PATCH 09/66] Add handling for addition and updating vendors --- .../c/po/PurchaseOrderAggregate.java | 2 +- .../mealorder/q/OrderListViewProjection.java | 13 +++--- .../mealorder/q/VendorListViewProjection.java | 43 ++++++++++++++++--- .../javaclasses/mealorder/c/events.proto | 2 + .../javaclasses/mealorder/q/values.proto | 2 +- 5 files changed, 45 insertions(+), 17 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/c/po/PurchaseOrderAggregate.java b/api-java/src/main/java/javaclasses/mealorder/c/po/PurchaseOrderAggregate.java index 25406707..af056a22 100644 --- a/api-java/src/main/java/javaclasses/mealorder/c/po/PurchaseOrderAggregate.java +++ b/api-java/src/main/java/javaclasses/mealorder/c/po/PurchaseOrderAggregate.java @@ -221,7 +221,7 @@ void purchaseOrderCanceled(PurchaseOrderCanceled event) { } @Apply - void purchaseOrderCanceled(PurchaseOrderDelivered event) { + void purchaseOrderDelivered(PurchaseOrderDelivered event) { getBuilder().setStatus(DELIVERED); } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java index 276a5924..6afc2b27 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java @@ -34,6 +34,9 @@ import java.util.List; import java.util.Optional; +/** + * @author Alexander Karpets + */ public class OrderListViewProjection extends Projection { /** @@ -82,18 +85,12 @@ void on(DishRemovedFromOrder event) { @Subscribe void on(OrderCanceled event) { - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getBookDetailsChange() - .getNewBookDetails() - .getSynopsis()); + getBuilder().clearOrder(); } @Subscribe void on(OrderProcessed event) { - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getBookDetailsChange() - .getNewBookDetails() - .getSynopsis()); + getBuilder().setProcessed(true); } private OrderItem getOrderById(OrderId orderId) { diff --git a/api-java/src/main/java/javaclasses/mealorder/q/VendorListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/VendorListViewProjection.java index 925de8dd..ab6892de 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/VendorListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/VendorListViewProjection.java @@ -28,6 +28,12 @@ import javaclasses.mealorder.q.projection.VendorListView; import javaclasses.mealorder.q.projection.VendorListViewVBuilder; +import java.util.List; +import java.util.stream.IntStream; + +/** + * @author Alexander Karpets + */ public class VendorListViewProjection extends Projection { /** @@ -52,18 +58,41 @@ public VendorListViewProjection(VendorId id) { @Subscribe void on(VendorAdded event) { - getBuilder().clearBookItem() - .clearBookItem(); - getBuilder().clearBookSynopsis() - .clearBookSynopsis(); + final VendorItem vendorItem = VendorItem.newBuilder() + .setId(event.getVendorId()) + .setEmail(event.getEmail()) + .setVendorName(event.getVendorName()) + .addAllPhoneNumber(event.getPhoneNumberList()) + .setPoDailyDeadline(event.getPoDailyDeadline()) + .build(); + getBuilder().addVendor(vendorItem); } @Subscribe void on(VendorUpdated event) { + final VendorItem vendorItem = VendorItem.newBuilder() + .setId(event.getVendorId()) + .setEmail(event.getVendorChange() + .getNewEmail()) + .setVendorName(event.getVendorChange() + .getNewVendorName()) + .addAllPhoneNumber(event.getVendorChange() + .getNewPhoneNumberList()) + .setPoDailyDeadline(event.getVendorChange() + .getNewPoDailyDeadline()) + .build(); + getBuilder().setVendor(getVendorById(event.getVendorId()), vendorItem); + } - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); + private int getVendorById(VendorId vendorId) { + final List vendorList = getBuilder().getVendor(); + int index = IntStream.range(0, vendorList.size()) + .filter(i -> vendorList.get(i) + .getId() + .equals(vendorId)) + .findFirst() + .getAsInt(); + return index; } } diff --git a/model/src/main/proto/javaclasses/mealorder/c/events.proto b/model/src/main/proto/javaclasses/mealorder/c/events.proto index 29d9ffde..d02c5e22 100644 --- a/model/src/main/proto/javaclasses/mealorder/c/events.proto +++ b/model/src/main/proto/javaclasses/mealorder/c/events.proto @@ -221,6 +221,8 @@ message PurchaseOrderDelivered { // Was delivered at this time. google.protobuf.Timestamp when_delievered = 3; + + } // The event signalizing about the successful sending of a purchase order. diff --git a/model/src/main/proto/javaclasses/mealorder/q/values.proto b/model/src/main/proto/javaclasses/mealorder/q/values.proto index e7ba1990..28627b75 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/values.proto @@ -132,7 +132,7 @@ message VendorItem { // The vendor email address. spine.net.EmailAddress email = 3; - // Phone numbers of the vendor. + // Phone numbers of a vendor. repeated PhoneNumber phone_number = 4; // Daily purchase order creation deadline time. From 624709f7151d69d768f7ced0f0913a620134a658 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Thu, 19 Apr 2018 15:16:48 +0300 Subject: [PATCH 10/66] Remove unnecessary subscribers in projections --- .../q/FullMenuListViewProjection.java | 8 +- .../MonthlySpendingsReportViewProjection.java | 5 +- ...chaseOrderDetailsByDishViewProjection.java | 23 +----- ...chaseOrderDetailsByUserViewProjection.java | 23 +----- .../q/PurchaseOrderListViewProjection.java | 79 ++++++++----------- 5 files changed, 37 insertions(+), 101 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/FullMenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/FullMenuListViewProjection.java index 1387479e..41b17987 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/FullMenuListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/FullMenuListViewProjection.java @@ -52,17 +52,11 @@ public FullMenuListViewProjection(VendorId id) { @Subscribe void on(DateRangeForMenuSet event) { - getBuilder().clearBookItem() - .clearBookItem(); - getBuilder().clearBookSynopsis() - .clearBookSynopsis(); + } @Subscribe void on(MenuImported event) { - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); } } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java index eeff779f..9795ac50 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java @@ -41,9 +41,6 @@ public MonthlySpendingsReportViewProjection(MenuListId id) { @Subscribe void on(PurchaseOrderDelivered event) { - getBuilder().clearBookItem() - .clearBookItem(); - getBuilder().clearBookSynopsis() - .clearBookSynopsis(); + } } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java index 5aac6673..4285a8b8 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java @@ -47,58 +47,37 @@ public PurchaseOrderDetailsByDishViewProjection(PurchaseOrderId id) { @Subscribe void on(PurchaseOrderCreated event) { - getBuilder().clearBookItem() - .clearBookItem(); - getBuilder().clearBookSynopsis() - .clearBookSynopsis(); + } @Subscribe void on(PurchaseOrderDelivered event) { - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); } @Subscribe void on(PurchaseOrderSent event) { - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); } @Subscribe void on(PurchaseOrderValidationFailed event) { - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); } @Subscribe void on(PurchaseOrderValidationOverruled event) { - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); } @Subscribe void on(PurchaseOrderValidationPassed event) { - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); } @Subscribe void on(PurchaseOrderCanceled event) { - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); } } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java index 6fc0299d..6df73db5 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java @@ -47,58 +47,37 @@ public PurchaseOrderDetailsByUserViewProjection(PurchaseOrderId id) { @Subscribe void on(PurchaseOrderCreated event) { - getBuilder().clearBookItem() - .clearBookItem(); - getBuilder().clearBookSynopsis() - .clearBookSynopsis(); + } @Subscribe void on(PurchaseOrderDelivered event) { - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); } @Subscribe void on(PurchaseOrderSent event) { - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); } @Subscribe void on(PurchaseOrderValidationFailed event) { - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); } @Subscribe void on(PurchaseOrderValidationOverruled event) { - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); } @Subscribe void on(PurchaseOrderValidationPassed event) { - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); } @Subscribe void on(PurchaseOrderCanceled event) { - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); } } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java index e0d8aa7f..332458fe 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java @@ -23,17 +23,17 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; import javaclasses.mealorder.PurchaseOrderId; +import javaclasses.mealorder.PurchaseOrderStatus; import javaclasses.mealorder.VendorId; -import javaclasses.mealorder.c.event.PurchaseOrderCanceled; -import javaclasses.mealorder.c.event.PurchaseOrderCreated; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; import javaclasses.mealorder.c.event.PurchaseOrderValidationFailed; -import javaclasses.mealorder.c.event.PurchaseOrderValidationOverruled; -import javaclasses.mealorder.c.event.PurchaseOrderValidationPassed; import javaclasses.mealorder.q.projection.PurchaseOrderListView; import javaclasses.mealorder.q.projection.PurchaseOrderListViewVBuilder; +import java.util.List; +import java.util.stream.IntStream; + public class PurchaseOrderListViewProjection extends Projection { /** @@ -58,60 +58,47 @@ public PurchaseOrderListViewProjection(PurchaseOrderId id) { super(id); } - @Subscribe - void on(PurchaseOrderCreated event) { - getBuilder().clearBookItem() - .clearBookItem(); - getBuilder().clearBookSynopsis() - .clearBookSynopsis(); - } - @Subscribe void on(PurchaseOrderDelivered event) { + final PurchaseOrderItem purchaseOrderItem = PurchaseOrderItem.newBuilder() + .setId(event.getId()) + .setPurchaseOrderStatus( + PurchaseOrderStatus.DELIVERED) + .build(); + getBuilder().setPurchaseOrder(getPurchaseOrderItemById(event.getId()), purchaseOrderItem); - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); } @Subscribe void on(PurchaseOrderSent event) { - - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); + final PurchaseOrderItem purchaseOrderItem = PurchaseOrderItem.newBuilder() + .setId(event.getPurchaseOrder() + .getId()) + .setPurchaseOrderStatus( + PurchaseOrderStatus.SENT) + .build(); + getBuilder().setPurchaseOrder(getPurchaseOrderItemById(event.getPurchaseOrder() + .getId()), purchaseOrderItem); } @Subscribe void on(PurchaseOrderValidationFailed event) { - - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); + final PurchaseOrderItem purchaseOrderItem = PurchaseOrderItem.newBuilder() + .setId(event.getId()) + .setPurchaseOrderStatus( + PurchaseOrderStatus.INVALID) + .build(); + getBuilder().setPurchaseOrder(getPurchaseOrderItemById(event.getId()), purchaseOrderItem); } - @Subscribe - void on(PurchaseOrderValidationOverruled event) { - - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); + private int getPurchaseOrderItemById(PurchaseOrderId id) { + final List orderList = getBuilder().getPurchaseOrder(); + final int index = IntStream.range(0, orderList.size()) + .filter(i -> orderList.get(i) + .getId() + .equals(id)) + .findFirst() + .getAsInt(); + return index; } - - @Subscribe - void on(PurchaseOrderValidationPassed event) { - - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); - } - - @Subscribe - void on(PurchaseOrderCanceled event) { - - getBuilder().setBookItem(bookItem); - getBuilder().setBookSynopsis(event.getDetails() - .getSynopsis()); - } - } From 4f6b5e26cb79c102963b1db3898421a5acb4ae1b Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Thu, 19 Apr 2018 16:22:34 +0300 Subject: [PATCH 11/66] Add subscribers for PO details --- .../mealorder/q/MenuListViewProjection.java | 6 +++ .../mealorder/q/OrderListViewProjection.java | 11 ++++- ...chaseOrderDetailsByDishViewProjection.java | 48 +++++++++++-------- 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java index 813aea8a..2018f445 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java @@ -59,6 +59,12 @@ void on(MenuImported event) { .addAllDishesByCategory(allDishesByCategories) .build(); getBuilder().addMenu(menuItem); + // Todo : Pasha from Timestamp to LocalDate or change proto files +// final MenuListId menuListId = MenuListId.newBuilder() +// .setDate(event.getWhenImported() +// .getSeconds())) +// .build(); +// getBuilder().setListId(menuListId); } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java index 6afc2b27..e8646cfa 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java @@ -24,6 +24,7 @@ import io.spine.server.projection.Projection; import javaclasses.mealorder.Dish; import javaclasses.mealorder.OrderId; +import javaclasses.mealorder.OrderListId; import javaclasses.mealorder.c.event.DishAddedToOrder; import javaclasses.mealorder.c.event.DishRemovedFromOrder; import javaclasses.mealorder.c.event.OrderCanceled; @@ -51,6 +52,7 @@ public OrderListViewProjection(OrderId id) { @Subscribe void on(DishAddedToOrder event) { + final OrderId orderId = event.getOrderId(); final DishItem dish = DishItem.newBuilder() .setName(event.getDish() @@ -60,11 +62,18 @@ void on(DishAddedToOrder event) { .build(); if (getBuilder().getOrder() .contains(getOrderById(orderId))) { + final OrderListId listId = OrderListId.newBuilder() + .setUserId(event.getOrderId() + .getUserId()) + .setOrderDate(event.getOrderId() + .getOrderDate()) + .build(); getBuilder().setOrder(getBuilder().getOrder() .indexOf(getOrderById(orderId)), OrderItem.newBuilder(getOrderById(orderId)) .addDish(dish) - .build()); + .build()) + .setListId(listId); } else { getBuilder().addOrder(OrderItem.newBuilder() .addDish(dish) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java index 4285a8b8..01b90c1b 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java @@ -22,17 +22,22 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; +import javaclasses.mealorder.Order; import javaclasses.mealorder.PurchaseOrderId; -import javaclasses.mealorder.c.event.PurchaseOrderCanceled; +import javaclasses.mealorder.PurchaseOrderStatus; import javaclasses.mealorder.c.event.PurchaseOrderCreated; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; import javaclasses.mealorder.c.event.PurchaseOrderValidationFailed; -import javaclasses.mealorder.c.event.PurchaseOrderValidationOverruled; -import javaclasses.mealorder.c.event.PurchaseOrderValidationPassed; import javaclasses.mealorder.q.projection.PurchaseOrderDetailsByDishView; import javaclasses.mealorder.q.projection.PurchaseOrderDetailsByDishViewVBuilder; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Alexander Karpets + */ public class PurchaseOrderDetailsByDishViewProjection extends Projection { /** @@ -47,37 +52,38 @@ public PurchaseOrderDetailsByDishViewProjection(PurchaseOrderId id) { @Subscribe void on(PurchaseOrderCreated event) { - + final List dishItems = getDishItems(event.getOrderList()); + getBuilder().addAllDish(dishItems); + getBuilder().setId(event.getId()); } @Subscribe void on(PurchaseOrderDelivered event) { - + getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.DELIVERED); } @Subscribe void on(PurchaseOrderSent event) { - + getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.SENT); } @Subscribe void on(PurchaseOrderValidationFailed event) { - + getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.INVALID); } - @Subscribe - void on(PurchaseOrderValidationOverruled event) { - + private List getDishItems(List orderList) { + List dishItems = new ArrayList<>(); + orderList.forEach(order -> + order.getDishList() + .forEach(dish -> { + dishItems.add(DishItem.newBuilder() + .setName(dish.getName()) + .setPrice(dish.getPrice()) + .setId(dish.getId()) + .build()); + }) + ); + return dishItems; } - - @Subscribe - void on(PurchaseOrderValidationPassed event) { - - } - - @Subscribe - void on(PurchaseOrderCanceled event) { - - } - } From b0a2418bae517ef587e3aa0003e233401b655225 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Thu, 19 Apr 2018 18:01:01 +0300 Subject: [PATCH 12/66] Add subscribers for `PurchaseOrderDetailsByUserViewProjection` --- ...chaseOrderDetailsByUserViewProjection.java | 76 +++++++++++++++---- 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java index 6df73db5..bf0376f2 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java @@ -22,17 +22,20 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; +import javaclasses.mealorder.Order; import javaclasses.mealorder.PurchaseOrderId; -import javaclasses.mealorder.c.event.PurchaseOrderCanceled; +import javaclasses.mealorder.PurchaseOrderStatus; +import javaclasses.mealorder.UserId; import javaclasses.mealorder.c.event.PurchaseOrderCreated; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; import javaclasses.mealorder.c.event.PurchaseOrderValidationFailed; -import javaclasses.mealorder.c.event.PurchaseOrderValidationOverruled; -import javaclasses.mealorder.c.event.PurchaseOrderValidationPassed; import javaclasses.mealorder.q.projection.PurchaseOrderDetailsByUserView; import javaclasses.mealorder.q.projection.PurchaseOrderDetailsByUserViewVBuilder; +import java.util.ArrayList; +import java.util.List; + public class PurchaseOrderDetailsByUserViewProjection extends Projection { /** @@ -48,36 +51,77 @@ public PurchaseOrderDetailsByUserViewProjection(PurchaseOrderId id) { @Subscribe void on(PurchaseOrderCreated event) { + final List usersOrders = getUserOrders(event); + getBuilder().addAllOrder(usersOrders); + getBuilder().setId(event.getId()); } @Subscribe void on(PurchaseOrderDelivered event) { - + getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.DELIVERED); } @Subscribe void on(PurchaseOrderSent event) { - + getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.SENT); } @Subscribe void on(PurchaseOrderValidationFailed event) { - + getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.INVALID); } - @Subscribe - void on(PurchaseOrderValidationOverruled event) { - + private List getUserOrders(PurchaseOrderCreated event) { + final List dishes = new ArrayList<>(); + for (int i = 0; i < event.getOrderList() + .size(); i++) { + if (!userOrderDetailsHasUser(dishes, event.getOrderList() + .get(i) + .getId() + .getUserId())) { + final UserId user = event.getOrderList() + .get(i) + .getId() + .getUserId(); + final List dishItems = getDishItemsForUser(user, event.getOrderList()); + final UserOrderDetails dish = UserOrderDetails.newBuilder() + .setId(event.getOrderList() + .get(i) + .getId() + .getUserId()) + .addAllDish(dishItems) + .build(); + dishes.add(dish); + } + } + return dishes; } - @Subscribe - void on(PurchaseOrderValidationPassed event) { - + private boolean userOrderDetailsHasUser(List dishes, + UserId userId) { + return dishes.stream() + .anyMatch(dish -> + dish.getId() + .equals(userId)); } - @Subscribe - void on(PurchaseOrderCanceled event) { - + private List getDishItemsForUser(UserId user, List orderList) { + final List dishItems = new ArrayList<>(); + orderList.forEach(order -> { + if (order.getId() + .getUserId() == user) { + + order.getDishList() + .forEach(dish -> { + final DishItem dishItem = DishItem.newBuilder() + .setId(dish.getId()) + .setName(dish.getName()) + .setPrice(dish.getPrice()) + .build(); + dishItems.add(dishItem); + }); + } + }); + return dishItems; } - } From a0c085449cdf72c63d454d7547378ff688cf48f0 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Thu, 19 Apr 2018 18:28:49 +0300 Subject: [PATCH 13/66] Set structure for Enrichments --- .../mealorder/c/BoundedContexts.java | 14 +++ .../mealorder/c/MealOrderEnrichments.java | 105 ++++++++++++++++++ .../javaclasses/mealorder/c/events.proto | 2 - 3 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 api-java/src/main/java/javaclasses/mealorder/c/MealOrderEnrichments.java diff --git a/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java b/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java index 74684f35..ee78c9c6 100644 --- a/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java +++ b/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java @@ -21,6 +21,8 @@ package javaclasses.mealorder.c; import io.spine.server.BoundedContext; +import io.spine.server.event.EventBus; +import io.spine.server.event.EventEnricher; import io.spine.server.storage.StorageFactory; import io.spine.server.storage.memory.InMemoryStorageFactory; import javaclasses.mealorder.c.order.OrderRepository; @@ -98,4 +100,16 @@ public static BoundedContext createBoundedContext(StorageFactory storageFactory) .setName(NAME) .build(); } + + private static EventBus.Builder createEventBus(StorageFactory storageFactory, + PurchaseOrderRepository poRepository) { + final EventEnricher enricher = MealOrderEnrichments.newBuilder() + .setPurchaseOrderRepository(poRepository) + .build() + .createEnricher(); + final EventBus.Builder eventBus = EventBus.newBuilder() + .setEnricher(enricher) + .setStorageFactory(storageFactory); + return eventBus; + } } diff --git a/api-java/src/main/java/javaclasses/mealorder/c/MealOrderEnrichments.java b/api-java/src/main/java/javaclasses/mealorder/c/MealOrderEnrichments.java new file mode 100644 index 00000000..eef6c9ff --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/c/MealOrderEnrichments.java @@ -0,0 +1,105 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.c; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import io.spine.server.event.EventEnricher; +import javaclasses.mealorder.PurchaseOrder; +import javaclasses.mealorder.PurchaseOrderId; +import javaclasses.mealorder.c.po.PurchaseOrderAggregate; +import javaclasses.mealorder.c.po.PurchaseOrderRepository; + +import static com.google.common.base.Preconditions.checkNotNull; + +@SuppressWarnings("Guava") // Spine Java 7 API. +final class MealOrderEnrichments { + + private final PurchaseOrderRepository taskRepo; + + private MealOrderEnrichments(Builder builder) { + this.taskRepo = builder.taskRepo; + } + + /** + * Creates an instance of {@link EventEnricher} for the TodoList bounded context. + * + *

The enricher enriches the events in the system by predefined rules. + * + * @return TodoList {@code EventEnricher} + */ + EventEnricher createEnricher() { + final EventEnricher enricher = + EventEnricher.newBuilder() + .add(PurchaseOrderId.class, PurchaseOrder.class, poIdToPo()) + .build(); + return enricher; + } + + private Function poIdToPo() { + final Function result = taskId -> { + if (taskId == null) { + return PurchaseOrder.getDefaultInstance(); + } + final Optional aggregate = taskRepo.find(taskId); + if (!aggregate.isPresent()) { + return PurchaseOrder.getDefaultInstance(); + } + final PurchaseOrder task = aggregate.get() + .getState(); + return task; + }; + return result; + } + + /** + * Creates a new builder for (@code TodoListEnrichments). + * + * @return new builder instance + */ + static Builder newBuilder() { + return new Builder(); + } + + /** + * A builder for {@code EventEnricherSupplier} instances. + */ + static class Builder { + + private PurchaseOrderRepository taskRepo; + + /** + * The {@code private} constructor prevents direct instantiation. + */ + private Builder() { + } + + Builder setPurchaseOrderRepository(PurchaseOrderRepository definitionRepository) { + checkNotNull(definitionRepository); + this.taskRepo = definitionRepository; + return this; + } + + MealOrderEnrichments build() { + return new MealOrderEnrichments(this); + } + } +} diff --git a/model/src/main/proto/javaclasses/mealorder/c/events.proto b/model/src/main/proto/javaclasses/mealorder/c/events.proto index d02c5e22..29d9ffde 100644 --- a/model/src/main/proto/javaclasses/mealorder/c/events.proto +++ b/model/src/main/proto/javaclasses/mealorder/c/events.proto @@ -221,8 +221,6 @@ message PurchaseOrderDelivered { // Was delivered at this time. google.protobuf.Timestamp when_delievered = 3; - - } // The event signalizing about the successful sending of a purchase order. From 95a7e019ff7f75a8150ba574d3320fb781d9940e Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Thu, 19 Apr 2018 18:56:02 +0300 Subject: [PATCH 14/66] Change menu now holds dates with a status instead of a date range --- .../mealorder/q/MenuListViewProjection.java | 6 +++++- .../main/proto/javaclasses/mealorder/q/values.proto | 2 +- .../main/proto/javaclasses/mealorder/values.proto | 13 +++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java index 2018f445..9ed6c49c 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java @@ -23,6 +23,7 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; import javaclasses.mealorder.Dish; +import javaclasses.mealorder.MenuForDay; import javaclasses.mealorder.MenuId; import javaclasses.mealorder.VendorName; import javaclasses.mealorder.c.event.DateRangeForMenuSet; @@ -31,6 +32,7 @@ import javaclasses.mealorder.q.projection.MenuListView; import javaclasses.mealorder.q.projection.MenuListViewVBuilder; +import java.util.ArrayList; import java.util.List; public class MenuListViewProjection extends Projection { @@ -72,8 +74,10 @@ void on(MenuImported event) { void on(DateRangeForMenuSet event) { final List menuItems = getBuilder().getMenu(); final MenuItem menuItem = menuItems.get(menuItems.size() - 1); + final List menuDays = new ArrayList<>(); + final MenuItem newMenuItem = MenuItem.newBuilder(menuItem) - .setMenuDateRange(event.getMenuDateRange()) + .addAllMenuDays(menuDays) .build(); getBuilder().setMenu(menuItems.size() - 1, newMenuItem); } diff --git a/model/src/main/proto/javaclasses/mealorder/q/values.proto b/model/src/main/proto/javaclasses/mealorder/q/values.proto index 28627b75..2cdd9864 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/values.proto @@ -54,7 +54,7 @@ message MenuItem { bool is_available = 3; // Date range when a menu is available. - MenuDateRange menu_date_range = 4; + repeated MenuForDay menu_days = 4; } // Dishes grouped by category. diff --git a/model/src/main/proto/javaclasses/mealorder/values.proto b/model/src/main/proto/javaclasses/mealorder/values.proto index 31aebb4f..fa72fa30 100644 --- a/model/src/main/proto/javaclasses/mealorder/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/values.proto @@ -36,6 +36,19 @@ import "spine/change/change.proto"; import "spine/net/email_address.proto"; import "spine/time/time.proto"; +// Day with status. +// +// If not available this menu will be disabled on UI. +// +message MenuForDay { + + // Menu date + spine.time.LocalDate date = 1; + + // If available a user can add dishes to his order. + bool available = 2; +} + // Name of a category. // // Probably it has fixed values. From b0a7e381a9eb74c611b7b2f701b4f042d610479a Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Thu, 19 Apr 2018 19:03:04 +0300 Subject: [PATCH 15/66] Extract methods that work with dates to projections --- .../q/MenuCalendarViewProjection.java | 31 ++---------------- .../mealorder/q/MenuListViewProjection.java | 20 ++++++++++++ .../javaclasses/mealorder/q/Projections.java | 32 +++++++++++++++++++ 3 files changed, 55 insertions(+), 28 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java index b1f0fa6a..a78f563f 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java @@ -22,7 +22,6 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; -import io.spine.time.LocalDate; import javaclasses.mealorder.MenuDateRange; import javaclasses.mealorder.MenuId; import javaclasses.mealorder.VendorId; @@ -30,12 +29,12 @@ import javaclasses.mealorder.q.projection.MenuCalendarView; import javaclasses.mealorder.q.projection.MenuCalendarViewVBuilder; -import java.util.ArrayList; -import java.util.Calendar; import java.util.Date; -import java.util.GregorianCalendar; import java.util.List; +import static javaclasses.mealorder.q.Projections.getDatesBetween; +import static javaclasses.mealorder.q.Projections.toLocalDate; + public class MenuCalendarViewProjection extends Projection { /** @@ -82,28 +81,4 @@ void on(DateRangeForMenuSet event) { }); } - private LocalDate toLocalDate(Date date) { - return LocalDate.newBuilder() - .setDay(date.getDay()) - .setMonthValue(date.getMonth()) - .setYear(date.getYear()) - .build(); - } - - private List getDatesBetween( - Date startDate, Date endDate) { - List datesInRange = new ArrayList<>(); - Calendar calendar = new GregorianCalendar(); - calendar.setTime(startDate); - - Calendar endCalendar = new GregorianCalendar(); - endCalendar.setTime(endDate); - - while (calendar.before(endCalendar)) { - Date result = calendar.getTime(); - datesInRange.add(result); - calendar.add(Calendar.DATE, 1); - } - return datesInRange; - } } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java index 9ed6c49c..308d55a5 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java @@ -23,6 +23,7 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; import javaclasses.mealorder.Dish; +import javaclasses.mealorder.MenuDateRange; import javaclasses.mealorder.MenuForDay; import javaclasses.mealorder.MenuId; import javaclasses.mealorder.VendorName; @@ -33,8 +34,11 @@ import javaclasses.mealorder.q.projection.MenuListViewVBuilder; import java.util.ArrayList; +import java.util.Date; import java.util.List; +import static javaclasses.mealorder.q.Projections.getDatesBetween; + public class MenuListViewProjection extends Projection { /** @@ -76,6 +80,22 @@ void on(DateRangeForMenuSet event) { final MenuItem menuItem = menuItems.get(menuItems.size() - 1); final List menuDays = new ArrayList<>(); + final MenuDateRange menuDateRange = event.getMenuDateRange(); + Date start = new Date(menuDateRange.getRangeStart() + .getYear(), menuDateRange.getRangeStart() + .getMonth() + .getNumber(), + menuDateRange.getRangeStart() + .getDay()); + Date end = new Date(menuDateRange.getRangeEnd() + .getYear(), menuDateRange.getRangeEnd() + .getMonth() + .getNumber(), + menuDateRange.getRangeEnd() + .getDay()); + final List datesBetween = getDatesBetween(start, end); + + final MenuItem newMenuItem = MenuItem.newBuilder(menuItem) .addAllMenuDays(menuDays) .build(); diff --git a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java index b1a52a3a..b8ef2932 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java @@ -20,6 +20,14 @@ package javaclasses.mealorder.q; +import io.spine.time.LocalDate; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.List; + final class Projections { /** @@ -28,4 +36,28 @@ final class Projections { private Projections() { } + public static List getDatesBetween( + Date startDate, Date endDate) { + List datesInRange = new ArrayList<>(); + Calendar calendar = new GregorianCalendar(); + calendar.setTime(startDate); + + Calendar endCalendar = new GregorianCalendar(); + endCalendar.setTime(endDate); + + while (calendar.before(endCalendar)) { + Date result = calendar.getTime(); + datesInRange.add(result); + calendar.add(Calendar.DATE, 1); + } + return datesInRange; + } + + public static LocalDate toLocalDate(Date date) { + return LocalDate.newBuilder() + .setDay(date.getDay()) + .setMonthValue(date.getMonth()) + .setYear(date.getYear()) + .build(); + } } From aa62e76eabbe7cb0e74968339992fb779e1e4e2a Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Thu, 19 Apr 2018 19:11:14 +0300 Subject: [PATCH 16/66] Rework subscriber on `MenuImported` event --- .../mealorder/q/MenuListViewProjection.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java index 308d55a5..cbf0f273 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java @@ -22,6 +22,7 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; +import io.spine.time.LocalDate; import javaclasses.mealorder.Dish; import javaclasses.mealorder.MenuDateRange; import javaclasses.mealorder.MenuForDay; @@ -73,7 +74,6 @@ void on(MenuImported event) { // getBuilder().setListId(menuListId); } - @Subscribe void on(DateRangeForMenuSet event) { final List menuItems = getBuilder().getMenu(); @@ -94,7 +94,18 @@ void on(DateRangeForMenuSet event) { menuDateRange.getRangeEnd() .getDay()); final List datesBetween = getDatesBetween(start, end); - + datesBetween.forEach(date -> { + final LocalDate localDate = LocalDate.newBuilder() + .setDay(date.getDay()) + .setMonthValue(date.getMonth()) + .setYear(date.getYear()) + .build(); + final MenuForDay menuForDay = MenuForDay.newBuilder() + .setDate(localDate) + .setAvailable(true) + .build(); + menuDays.add(menuForDay); + }); final MenuItem newMenuItem = MenuItem.newBuilder(menuItem) .addAllMenuDays(menuDays) @@ -104,7 +115,7 @@ void on(DateRangeForMenuSet event) { @Subscribe void on(PurchaseOrderCreated event) { - //Todo: somehow disables menus + //Todo: pasha disables menus } private Iterable getAllDishesByCategories( From 09c61aedb0bc244135649b4f814fbbcf6813d049 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Fri, 20 Apr 2018 12:29:24 +0300 Subject: [PATCH 17/66] Add `Projections` class test --- .../q/projection/ProjectionTest.java | 46 +++++++++++++++++++ .../PurchaseOrderListViewProjectionTest.java | 24 ++++++++++ 2 files changed, 70 insertions(+) create mode 100644 api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionTest.java create mode 100644 api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionTest.java new file mode 100644 index 00000000..1ef68790 --- /dev/null +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.projection; + +import com.google.protobuf.Message; +import io.spine.core.Event; +import io.spine.core.EventEnvelope; +import io.spine.server.command.TestEventFactory; +import io.spine.server.event.EventEnricher; +import io.spine.server.event.EventFactory; +import javaclasses.exlibris.testdata.TestEventEnricherFactory; + +abstract class ProjectionTest { + + private final EventFactory eventFactory = TestEventFactory.newInstance(getClass()); + private final EventEnricher enricher = TestEventEnricherFactory.eventEnricherInstance(); + + Event createEvent(Message messageOrAny) { + final Event event = eventFactory.createEvent(messageOrAny, null); + final EventEnvelope envelope = EventEnvelope.of(event); + if (!enricher.canBeEnriched(envelope)) { + return event; + } + + return enricher.enrich(envelope) + .getOuterObject(); + } +} diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java new file mode 100644 index 00000000..05ae87ba --- /dev/null +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java @@ -0,0 +1,24 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.projection; + +public class PurchaseOrderListViewProjectionTest { +} From a3b865b7c6122260d5da4ff7895b02b21b470731 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Fri, 20 Apr 2018 13:31:36 +0300 Subject: [PATCH 18/66] Add event factory for projection tests --- .../q/PurchaseOrderListViewProjection.java | 22 +++--- .../q/projection/ProjectionTest.java | 2 +- .../PurchaseOrderListViewProjectionTest.java | 38 +++++++++- .../testdata/TestEventEnricherFactory.java | 46 ++++++++++++ .../testdata/TestMealOrderEventFactory.java | 70 +++++++++++++++++++ 5 files changed, 165 insertions(+), 13 deletions(-) create mode 100644 testutil-api/src/main/java/javaclasses/mealorder/testdata/TestEventEnricherFactory.java create mode 100644 testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java index 332458fe..e817dcbf 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java @@ -58,17 +58,6 @@ public PurchaseOrderListViewProjection(PurchaseOrderId id) { super(id); } - @Subscribe - void on(PurchaseOrderDelivered event) { - final PurchaseOrderItem purchaseOrderItem = PurchaseOrderItem.newBuilder() - .setId(event.getId()) - .setPurchaseOrderStatus( - PurchaseOrderStatus.DELIVERED) - .build(); - getBuilder().setPurchaseOrder(getPurchaseOrderItemById(event.getId()), purchaseOrderItem); - - } - @Subscribe void on(PurchaseOrderSent event) { final PurchaseOrderItem purchaseOrderItem = PurchaseOrderItem.newBuilder() @@ -81,6 +70,17 @@ void on(PurchaseOrderSent event) { .getId()), purchaseOrderItem); } + @Subscribe + void on(PurchaseOrderDelivered event) { + final PurchaseOrderItem purchaseOrderItem = PurchaseOrderItem.newBuilder() + .setId(event.getId()) + .setPurchaseOrderStatus( + PurchaseOrderStatus.DELIVERED) + .build(); + getBuilder().setPurchaseOrder(getPurchaseOrderItemById(event.getId()), purchaseOrderItem); + + } + @Subscribe void on(PurchaseOrderValidationFailed event) { final PurchaseOrderItem purchaseOrderItem = PurchaseOrderItem.newBuilder() diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionTest.java index 1ef68790..b27a0147 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionTest.java @@ -26,7 +26,7 @@ import io.spine.server.command.TestEventFactory; import io.spine.server.event.EventEnricher; import io.spine.server.event.EventFactory; -import javaclasses.exlibris.testdata.TestEventEnricherFactory; +import javaclasses.mealorder.testdata.TestEventEnricherFactory; abstract class ProjectionTest { diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java index 05ae87ba..b5a7af67 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java @@ -20,5 +20,41 @@ package javaclasses.mealorder.q.projection; -public class PurchaseOrderListViewProjectionTest { +import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.q.PurchaseOrderListViewProjection; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +public class PurchaseOrderListViewProjectionTest extends ProjectionTest { + + private PurchaseOrderListViewProjection projection; + + @BeforeEach + void setUp() { + projection = new PurchaseOrderListViewProjection(PurchaseOrderListViewProjection.ID); + } + + @Nested + @DisplayName("TaskCreated event should be interpreted by MyListViewProjection and") + class TaskCreatedEvent { + + @Test + @DisplayName("add TaskItem to MyListView") + void addView() { + final PurchaseOrderSent taskCreatedEvent = taskCreatedInstance(); + dispatch(projection, createEvent(taskCreatedEvent)); + + final List views = projection.getState() + .getMyList() + .getItemsList(); + assertEquals(1, views.size()); + + final TaskItem view = views.get(0); + assertEquals(TASK_PRIORITY, view.getPriority()); + assertEquals(DESCRIPTION, view.getDescription() + .getValue()); + } + } } diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestEventEnricherFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestEventEnricherFactory.java new file mode 100644 index 00000000..536d2392 --- /dev/null +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestEventEnricherFactory.java @@ -0,0 +1,46 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.testdata; + +import io.spine.server.event.EventEnricher; + +public class TestEventEnricherFactory { +// private static final Function PO_ID_TO_ORDER = +// taskId -> bookDetails; + + private TestEventEnricherFactory() { + } + + /** + * Provides a pre-configured {@link EventEnricher} event instance. + * + * @return {@code EventEnricher} + */ + public static EventEnricher eventEnricherInstance() { +// final EventEnricher result = EventEnricher.newBuilder() +// .add(PurchaseOrderId.class, +// PurchaseOrder.class, +// PoIdTo::apply) +// .build(); + return EventEnricher.newBuilder() + .build(); + } +} diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java new file mode 100644 index 00000000..e8dff963 --- /dev/null +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java @@ -0,0 +1,70 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.testdata; + +import com.google.protobuf.Timestamp; +import io.spine.net.EmailAddress; +import javaclasses.mealorder.Order; +import javaclasses.mealorder.PurchaseOrder; +import javaclasses.mealorder.PurchaseOrderId; +import javaclasses.mealorder.PurchaseOrderStatus; +import javaclasses.mealorder.c.event.PurchaseOrderSent; + +import static io.spine.time.Time.getCurrentTime; + +public class TestMealOrderEventFactory { + + private static final Order ORDER = TestValues.ORDER; + private static final PurchaseOrderId ID = TestValues.PURCHASE_ORDER_ID; + private static final PurchaseOrder PURCHASE_ORDER = PurchaseOrder.newBuilder() + .addOrder(ORDER) + .setId(ID) + .setStatus( + PurchaseOrderStatus.CREATED) + .build(); + + private TestMealOrderEventFactory() { + } + + public static class PurchaseOrderEvents { + private PurchaseOrderEvents() { + } + + public static PurchaseOrderSent purchaseOrderSentInstance() { + return purchaseOrderSentInstance(PURCHASE_ORDER, TestValues.USER_ID.getEmail(), + TestValues.EMAIL); + } + + public static PurchaseOrderSent purchaseOrderSentInstance(PurchaseOrder po, + EmailAddress senderEmail, + EmailAddress vendorEmail) { + final Timestamp currentTime = getCurrentTime(); + final PurchaseOrderSent result = + PurchaseOrderSent.newBuilder() + .setPurchaseOrder(po) + .setSenderEmail(senderEmail) + .setVendorEmail(vendorEmail) + .setWhenSent(currentTime) + .build(); + return result; + } + } +} From ab549b47ff7ceff63d6594239192f5b5e983d602 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Fri, 20 Apr 2018 14:40:34 +0300 Subject: [PATCH 19/66] Add tests for `POListView` --- .../q/PurchaseOrderListViewProjection.java | 3 +- .../PurchaseOrderListViewProjectionTest.java | 60 ++++++++++++++----- .../testdata/TestMealOrderEventFactory.java | 19 ++++++ 3 files changed, 64 insertions(+), 18 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java index e817dcbf..d4433553 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java @@ -66,8 +66,7 @@ void on(PurchaseOrderSent event) { .setPurchaseOrderStatus( PurchaseOrderStatus.SENT) .build(); - getBuilder().setPurchaseOrder(getPurchaseOrderItemById(event.getPurchaseOrder() - .getId()), purchaseOrderItem); + getBuilder().addPurchaseOrder(purchaseOrderItem); } @Subscribe diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java index b5a7af67..2256fcb3 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java @@ -20,15 +20,25 @@ package javaclasses.mealorder.q.projection; +import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.q.PurchaseOrderItem; import javaclasses.mealorder.q.PurchaseOrderListViewProjection; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -public class PurchaseOrderListViewProjectionTest extends ProjectionTest { +import java.util.List; +import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderDeliveredInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderSentInstance; +import static org.junit.jupiter.api.Assertions.assertEquals; +public class PurchaseOrderListViewProjectionTest extends ProjectionTest { + final Logger logger = LoggerFactory.getLogger(PurchaseOrderListViewProjectionTest.class); private PurchaseOrderListViewProjection projection; @BeforeEach @@ -37,24 +47,42 @@ void setUp() { } @Nested - @DisplayName("TaskCreated event should be interpreted by MyListViewProjection and") - class TaskCreatedEvent { + @DisplayName("PurchaseOrderSent event should be interpreted by PurchaseOrderListViewProjection") + class PurchaseOrderSentEvent { + + @Test + @DisplayName("Should set order for a projection") + void addView() { + final PurchaseOrderSent purchaseOrderSent = purchaseOrderSentInstance(); + dispatch(projection, createEvent(purchaseOrderSent)); + + final List purchaseOrderList = projection.getState() + .getPurchaseOrderList(); + assertEquals(1, purchaseOrderList.size()); + assertEquals(15, purchaseOrderList.get(0) + .getId() + .getPoDate() + .getDay()); + } + } + + @Nested + @DisplayName("PurchaseOrderDelivered event should be interpreted by PurchaseOrderListViewProjection") + class PurchaseOrderDeliveredEvent { @Test - @DisplayName("add TaskItem to MyListView") + @DisplayName("Should change status of the PO") void addView() { - final PurchaseOrderSent taskCreatedEvent = taskCreatedInstance(); - dispatch(projection, createEvent(taskCreatedEvent)); - - final List views = projection.getState() - .getMyList() - .getItemsList(); - assertEquals(1, views.size()); - - final TaskItem view = views.get(0); - assertEquals(TASK_PRIORITY, view.getPriority()); - assertEquals(DESCRIPTION, view.getDescription() - .getValue()); + final PurchaseOrderSent purchaseOrderSent = purchaseOrderSentInstance(); + dispatch(projection, createEvent(purchaseOrderSent)); + final PurchaseOrderDelivered purchaseOrderDelivered = purchaseOrderDeliveredInstance(); + dispatch(projection, createEvent(purchaseOrderDelivered)); + final List purchaseOrderList = projection.getState() + .getPurchaseOrderList(); + assertEquals(1, purchaseOrderList.size()); + assertEquals("DELIVERED", purchaseOrderList.get(0) + .getPurchaseOrderStatus() + .name()); } } } diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java index e8dff963..859af132 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java @@ -26,6 +26,8 @@ import javaclasses.mealorder.PurchaseOrder; import javaclasses.mealorder.PurchaseOrderId; import javaclasses.mealorder.PurchaseOrderStatus; +import javaclasses.mealorder.UserId; +import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; import static io.spine.time.Time.getCurrentTime; @@ -66,5 +68,22 @@ public static PurchaseOrderSent purchaseOrderSentInstance(PurchaseOrder po, .build(); return result; } + + public static PurchaseOrderDelivered purchaseOrderDeliveredInstance() { + return purchaseOrderDeliveredInstance(TestValues.PURCHASE_ORDER_ID, TestValues.USER_ID); + } + + private static PurchaseOrderDelivered purchaseOrderDeliveredInstance( + PurchaseOrderId purchaseOrderId, + UserId userId) { + final Timestamp currentTime = getCurrentTime(); + final PurchaseOrderDelivered result = + PurchaseOrderDelivered.newBuilder() + .setId(purchaseOrderId) + .setWhoMarkedAsDelivered(userId) + .setWhenDelievered(currentTime) + .build(); + return result; + } } } From 0d1a8039948ef60014c258115f8d3c145dc79346 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Fri, 20 Apr 2018 14:54:58 +0300 Subject: [PATCH 20/66] Add enrichments.proto for purchase order --- .../MonthlySpendingsReportViewProjection.java | 12 +++++- .../javaclasses/mealorder/c/enrichments.proto | 43 +++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 model/src/main/proto/javaclasses/mealorder/c/enrichments.proto diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java index 9795ac50..e37be811 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java @@ -23,6 +23,7 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; import javaclasses.mealorder.MenuListId; +import javaclasses.mealorder.PurchaseOrderId; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.q.projection.MonthlySpendingsReportView; import javaclasses.mealorder.q.projection.MonthlySpendingsReportViewVBuilder; @@ -41,6 +42,15 @@ public MonthlySpendingsReportViewProjection(MenuListId id) { @Subscribe void on(PurchaseOrderDelivered event) { - + final PurchaseOrderId taskId = event.getId(); +// final TaskEnrichment enrichment = getEnrichment(TaskEnrichment.class, context); +// final Task task = enrichment.getTask(); +// final TaskItem view = TaskItem.newBuilder() +// .setId(taskId) +// .setDescription(task.getDescription()) +// .setDueDate(task.getDueDate()) +// .setPriority(task.getPriority()) +// .build(); +// addTaskItem(view); } } diff --git a/model/src/main/proto/javaclasses/mealorder/c/enrichments.proto b/model/src/main/proto/javaclasses/mealorder/c/enrichments.proto new file mode 100644 index 00000000..86fb0b7a --- /dev/null +++ b/model/src/main/proto/javaclasses/mealorder/c/enrichments.proto @@ -0,0 +1,43 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +syntax = "proto3"; + +package javaclasses.mealorder.c; + +import "spine/options.proto"; + +option (type_url_prefix) = "type.javaclasses.mealorder"; +option java_package = "javaclasses.mealorder.c.event"; +option java_outer_classname = "EnrichmentsProto"; +option java_multiple_files = true; +option java_generate_equals_and_hash = true; + +import "javaclasses/mealorder/model.proto"; +import "javaclasses/mealorder/values.proto"; + +// Task enrichment for the `PurchaseOrderDelivered` event. +// +message PurchaseOrderEnrichment { + option (enrichment_for) = "javaclasses.mealorder.c.PurchaseOrderDelivered"; + + // The state of the PO produced by PO created. + PurchaseOrder purchase_order = 1 [(by) = "id"]; +} From 87386830e72af088c82780db8f595d093efb36d4 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Fri, 20 Apr 2018 15:33:03 +0300 Subject: [PATCH 21/66] Add context and enrichment in monthly spendings --- .../MonthlySpendingsReportViewProjection.java | 24 +++++++++++-------- .../javaclasses/mealorder/q/Projections.java | 4 ++-- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java index e37be811..a402ecc7 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java @@ -20,14 +20,22 @@ package javaclasses.mealorder.q; +import io.spine.core.EventContext; import io.spine.core.Subscribe; import io.spine.server.projection.Projection; import javaclasses.mealorder.MenuListId; +import javaclasses.mealorder.Order; +import javaclasses.mealorder.PurchaseOrder; import javaclasses.mealorder.PurchaseOrderId; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; +import javaclasses.mealorder.c.event.PurchaseOrderEnrichment; import javaclasses.mealorder.q.projection.MonthlySpendingsReportView; import javaclasses.mealorder.q.projection.MonthlySpendingsReportViewVBuilder; +import java.util.List; + +import static javaclasses.mealorder.q.EventEnrichments.getEnrichment; + public class MonthlySpendingsReportViewProjection extends Projection { /** @@ -40,17 +48,13 @@ public MonthlySpendingsReportViewProjection(MenuListId id) { super(id); } + //todo: pasha @Subscribe - void on(PurchaseOrderDelivered event) { + void on(PurchaseOrderDelivered event, EventContext context) { final PurchaseOrderId taskId = event.getId(); -// final TaskEnrichment enrichment = getEnrichment(TaskEnrichment.class, context); -// final Task task = enrichment.getTask(); -// final TaskItem view = TaskItem.newBuilder() -// .setId(taskId) -// .setDescription(task.getDescription()) -// .setDueDate(task.getDueDate()) -// .setPriority(task.getPriority()) -// .build(); -// addTaskItem(view); + final PurchaseOrderEnrichment enrichment = getEnrichment(PurchaseOrderEnrichment.class, + context); + final PurchaseOrder po = enrichment.getPurchaseOrder(); + final List orderList = po.getOrderList(); } } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java index b8ef2932..932c2660 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java @@ -36,7 +36,7 @@ final class Projections { private Projections() { } - public static List getDatesBetween( + static List getDatesBetween( Date startDate, Date endDate) { List datesInRange = new ArrayList<>(); Calendar calendar = new GregorianCalendar(); @@ -53,7 +53,7 @@ public static List getDatesBetween( return datesInRange; } - public static LocalDate toLocalDate(Date date) { + static LocalDate toLocalDate(Date date) { return LocalDate.newBuilder() .setDay(date.getDay()) .setMonthValue(date.getMonth()) From 8da61d18e1c1e48918ce8205fcf6699c9cc1c3a7 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Fri, 20 Apr 2018 17:03:49 +0300 Subject: [PATCH 22/66] Use new java 8 approach to get dates from a date range --- .../q/MenuCalendarViewProjection.java | 28 ++++----- .../mealorder/q/MenuListViewProjection.java | 20 ++---- .../javaclasses/mealorder/q/Projections.java | 41 ++++++------ .../MenuCalendarViewProjectionTest.java | 62 +++++++++++++++++++ .../PurchaseOrderListViewProjectionTest.java | 3 - .../testdata/TestMealOrderEventFactory.java | 30 +++++++++ .../mealorder/testdata/TestValues.java | 11 ++++ 7 files changed, 137 insertions(+), 58 deletions(-) create mode 100644 api-java/src/test/java/javaclasses/mealorder/q/projection/MenuCalendarViewProjectionTest.java diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java index a78f563f..c46e3d43 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java @@ -29,7 +29,7 @@ import javaclasses.mealorder.q.projection.MenuCalendarView; import javaclasses.mealorder.q.projection.MenuCalendarViewVBuilder; -import java.util.Date; +import java.time.LocalDate; import java.util.List; import static javaclasses.mealorder.q.Projections.getDatesBetween; @@ -43,9 +43,11 @@ public class MenuCalendarViewProjection extends ProjectionThe {@code ID} value should be the same for all JVMs * to support work with the same projection from execution to execution. */ - public static final VendorId ID = VendorId.newBuilder() - .setValue("MenuCalendarViewProjectionSingleton") - .build(); + public static final MenuId ID = MenuId.newBuilder() + .setVendorId(VendorId.newBuilder() + .setValue( + "MenuCalendarViewProjectionSingleton")) + .build(); /** * Creates a new instance. @@ -60,19 +62,11 @@ public MenuCalendarViewProjection(MenuId id) { @Subscribe void on(DateRangeForMenuSet event) { final MenuDateRange menuDateRange = event.getMenuDateRange(); - Date start = new Date(menuDateRange.getRangeStart() - .getYear(), menuDateRange.getRangeStart() - .getMonth() - .getNumber(), - menuDateRange.getRangeStart() - .getDay()); - Date end = new Date(menuDateRange.getRangeEnd() - .getYear(), menuDateRange.getRangeEnd() - .getMonth() - .getNumber(), - menuDateRange.getRangeEnd() - .getDay()); - final List datesBetween = getDatesBetween(start, end); + final List datesBetween = getDatesBetween(event.getMenuDateRange() + .getRangeStart(), + event.getMenuDateRange() + .getRangeEnd()); + datesBetween.forEach(date -> { getBuilder().addCalendarItem(MenuCalendarItem.newBuilder() .setDate(toLocalDate(date)) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java index cbf0f273..d07eb80d 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java @@ -35,7 +35,6 @@ import javaclasses.mealorder.q.projection.MenuListViewVBuilder; import java.util.ArrayList; -import java.util.Date; import java.util.List; import static javaclasses.mealorder.q.Projections.getDatesBetween; @@ -81,23 +80,12 @@ void on(DateRangeForMenuSet event) { final List menuDays = new ArrayList<>(); final MenuDateRange menuDateRange = event.getMenuDateRange(); - Date start = new Date(menuDateRange.getRangeStart() - .getYear(), menuDateRange.getRangeStart() - .getMonth() - .getNumber(), - menuDateRange.getRangeStart() - .getDay()); - Date end = new Date(menuDateRange.getRangeEnd() - .getYear(), menuDateRange.getRangeEnd() - .getMonth() - .getNumber(), - menuDateRange.getRangeEnd() - .getDay()); - final List datesBetween = getDatesBetween(start, end); + final List datesBetween = getDatesBetween( + menuDateRange.getRangeStart(), menuDateRange.getRangeEnd()); datesBetween.forEach(date -> { final LocalDate localDate = LocalDate.newBuilder() - .setDay(date.getDay()) - .setMonthValue(date.getMonth()) + .setDay(date.getDayOfMonth()) + .setMonthValue(date.getMonthValue()) .setYear(date.getYear()) .build(); final MenuForDay menuForDay = MenuForDay.newBuilder() diff --git a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java index 932c2660..8d96d55c 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java @@ -22,11 +22,10 @@ import io.spine.time.LocalDate; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; +import java.time.temporal.ChronoUnit; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; final class Projections { @@ -36,27 +35,25 @@ final class Projections { private Projections() { } - static List getDatesBetween( - Date startDate, Date endDate) { - List datesInRange = new ArrayList<>(); - Calendar calendar = new GregorianCalendar(); - calendar.setTime(startDate); - - Calendar endCalendar = new GregorianCalendar(); - endCalendar.setTime(endDate); - - while (calendar.before(endCalendar)) { - Date result = calendar.getTime(); - datesInRange.add(result); - calendar.add(Calendar.DATE, 1); - } - return datesInRange; + static List getDatesBetween( + LocalDate startDate, LocalDate endDate) { + java.time.LocalDate start = java.time.LocalDate.of(startDate.getYear(), + startDate.getMonthValue(), + startDate.getDay()); + java.time.LocalDate end = java.time.LocalDate.of(endDate.getYear(), endDate.getMonthValue(), + endDate.getDay()); + long numOfDaysBetween = ChronoUnit.DAYS.between(start, end); + final List collect = IntStream.iterate(0, i -> i + 1) + .limit(numOfDaysBetween) + .mapToObj(i -> start.plusDays(i)) + .collect(Collectors.toList()); + return collect; } - static LocalDate toLocalDate(Date date) { + static LocalDate toLocalDate(java.time.LocalDate date) { return LocalDate.newBuilder() - .setDay(date.getDay()) - .setMonthValue(date.getMonth()) + .setDay(date.getDayOfMonth()) + .setMonthValue(date.getMonthValue()) .setYear(date.getYear()) .build(); } diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuCalendarViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuCalendarViewProjectionTest.java new file mode 100644 index 00000000..fa1d61c6 --- /dev/null +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuCalendarViewProjectionTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.projection; + +import javaclasses.mealorder.c.event.DateRangeForMenuSet; +import javaclasses.mealorder.q.MenuCalendarItem; +import javaclasses.mealorder.q.MenuCalendarViewProjection; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.VendorEvents.dateRangeForMenuSetInstance; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class MenuCalendarViewProjectionTest extends ProjectionTest { + private MenuCalendarViewProjection projection; + + @BeforeEach + void setUp() { + projection = new MenuCalendarViewProjection(MenuCalendarViewProjection.ID); + } + + @Nested + @DisplayName("DateRangeForMenuSet event should be interpreted by MenuCalendarViewProjection") + class PurchaseOrderSentEvent { + private final Logger logger = LoggerFactory.getLogger(PurchaseOrderSentEvent.class); + + @Test + @DisplayName("Should set dates with menus") + void addView() { + final DateRangeForMenuSet dateRangeForMenuSet = dateRangeForMenuSetInstance(); + dispatch(projection, createEvent(dateRangeForMenuSet)); + final List calendarItems = projection.getState() + .getCalendarItemList(); + assertEquals(25, calendarItems.size()); + } + } +} diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java index 2256fcb3..7ce4ced4 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java @@ -28,8 +28,6 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.List; @@ -38,7 +36,6 @@ import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderSentInstance; import static org.junit.jupiter.api.Assertions.assertEquals; public class PurchaseOrderListViewProjectionTest extends ProjectionTest { - final Logger logger = LoggerFactory.getLogger(PurchaseOrderListViewProjectionTest.class); private PurchaseOrderListViewProjection projection; @BeforeEach diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java index 859af132..6d7ccf98 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java @@ -22,11 +22,15 @@ import com.google.protobuf.Timestamp; import io.spine.net.EmailAddress; +import javaclasses.mealorder.MenuDateRange; +import javaclasses.mealorder.MenuId; import javaclasses.mealorder.Order; import javaclasses.mealorder.PurchaseOrder; import javaclasses.mealorder.PurchaseOrderId; import javaclasses.mealorder.PurchaseOrderStatus; import javaclasses.mealorder.UserId; +import javaclasses.mealorder.VendorId; +import javaclasses.mealorder.c.event.DateRangeForMenuSet; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; @@ -86,4 +90,30 @@ private static PurchaseOrderDelivered purchaseOrderDeliveredInstance( return result; } } + + public static class VendorEvents { + private VendorEvents() { + } + + public static DateRangeForMenuSet dateRangeForMenuSetInstance() { + return dateRangeForMenuSetInstance(TestValues.VENDOR_ID, TestValues.MENU_ID, + TestValues.USER_ID, TestValues.MENU_DATE_RANGE2); + } + + private static DateRangeForMenuSet dateRangeForMenuSetInstance(VendorId vendorId, + MenuId menuId, + UserId userId, + MenuDateRange menuDateRange) { + final Timestamp currentTime = getCurrentTime(); + final DateRangeForMenuSet result = + DateRangeForMenuSet.newBuilder() + .setVendorId(vendorId) + .setMenuId(menuId) + .setWhoSet(userId) + .setWhenSet(currentTime) + .setMenuDateRange(menuDateRange) + .build(); + return result; + } + } } diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java index e0520521..3c9811b3 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java @@ -143,6 +143,11 @@ public class TestValues { .setMonthValue(2) .setDay(19) .build(); + public static final LocalDate END_DATE_FROM_PAST2 = LocalDate.newBuilder() + .setYear(2017) + .setMonthValue(3) + .setDay(10) + .build(); public static final LocalDate INVALID_START_DATE = LocalDate.newBuilder() .setYear(2020) @@ -162,6 +167,12 @@ public class TestValues { .setRangeEnd( INVALID_END_DATE) .build(); + public static final MenuDateRange MENU_DATE_RANGE2 = MenuDateRange.newBuilder() + .setRangeStart( + START_DATE_FROM_PAST) + .setRangeEnd( + END_DATE_FROM_PAST2) + .build(); public static final MenuDateRange MENU_DATE_RANGE_FROM_PAST = MenuDateRange.newBuilder() .setRangeStart( From c542924eb912fb0442a366ca274bbe03de0ed1bf Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Fri, 20 Apr 2018 18:45:22 +0300 Subject: [PATCH 23/66] Add tests for order by user projection --- ...chaseOrderDetailsByUserViewProjection.java | 1 - .../MenuCalendarViewProjectionTest.java | 3 - ...eOrderDetailsByUserViewProjectionTest.java | 70 +++++++++++++++++ .../testdata/TestMealOrderEventFactory.java | 22 ++++++ .../mealorder/testdata/TestValues.java | 75 +++++++++++++++++++ 5 files changed, 167 insertions(+), 4 deletions(-) create mode 100644 api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java index bf0376f2..b0c56c08 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java @@ -50,7 +50,6 @@ public PurchaseOrderDetailsByUserViewProjection(PurchaseOrderId id) { @Subscribe void on(PurchaseOrderCreated event) { - final List usersOrders = getUserOrders(event); getBuilder().addAllOrder(usersOrders); getBuilder().setId(event.getId()); diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuCalendarViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuCalendarViewProjectionTest.java index fa1d61c6..5809555f 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuCalendarViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuCalendarViewProjectionTest.java @@ -27,8 +27,6 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.List; @@ -47,7 +45,6 @@ void setUp() { @Nested @DisplayName("DateRangeForMenuSet event should be interpreted by MenuCalendarViewProjection") class PurchaseOrderSentEvent { - private final Logger logger = LoggerFactory.getLogger(PurchaseOrderSentEvent.class); @Test @DisplayName("Should set dates with menus") diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java new file mode 100644 index 00000000..50f81c25 --- /dev/null +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.projection; + +import io.spine.time.LocalDate; +import javaclasses.mealorder.PurchaseOrderId; +import javaclasses.mealorder.VendorId; +import javaclasses.mealorder.c.event.PurchaseOrderCreated; +import javaclasses.mealorder.q.PurchaseOrderDetailsByUserViewProjection; +import javaclasses.mealorder.q.UserOrderDetails; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderCreatedInstance; + +public class PurchaseOrderDetailsByUserViewProjectionTest extends ProjectionTest { + private PurchaseOrderDetailsByUserViewProjection projection; + + @BeforeEach + void setUp() { + projection = new PurchaseOrderDetailsByUserViewProjection(PurchaseOrderId.newBuilder() + .setPoDate( + LocalDate.newBuilder() + .setDay(14) + .build()) + .setVendorId( + VendorId.newBuilder() + .setValue( + "Пюре") + .build()) + .build()); + } + + @Nested + @DisplayName("PurchaseOrderSent event should be interpreted by PurchaseOrderListViewProjection") + class PurchaseOrderSentEvent { + + @Test + @DisplayName("Should set order for a projection") + void addView() { + final PurchaseOrderCreated purchaseOrderCreated = purchaseOrderCreatedInstance(); + dispatch(projection, createEvent(purchaseOrderCreated)); + final List orderList = projection.getState() + .getOrderList(); + } + } +} diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java index 6d7ccf98..2a97f847 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java @@ -31,9 +31,12 @@ import javaclasses.mealorder.UserId; import javaclasses.mealorder.VendorId; import javaclasses.mealorder.c.event.DateRangeForMenuSet; +import javaclasses.mealorder.c.event.PurchaseOrderCreated; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; +import java.util.List; + import static io.spine.time.Time.getCurrentTime; public class TestMealOrderEventFactory { @@ -89,6 +92,25 @@ private static PurchaseOrderDelivered purchaseOrderDeliveredInstance( .build(); return result; } + + public static PurchaseOrderCreated purchaseOrderCreatedInstance() { + return purchaseOrderCreatedInstance(TestValues.PURCHASE_ORDER_ID, TestValues.USER_ID, + TestValues.BIG_ORDER); + } + + public static PurchaseOrderCreated purchaseOrderCreatedInstance( + PurchaseOrderId purchaseOrderId, UserId userId, + List orders) { + final Timestamp currentTime = getCurrentTime(); + final PurchaseOrderCreated result = + PurchaseOrderCreated.newBuilder() + .setId(purchaseOrderId) + .setWhenCreated(currentTime) + .setWhoCreated(userId) + .addAllOrder(orders) + .build(); + return result; + } } public static class VendorEvents { diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java index 3c9811b3..6ef9d502 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java @@ -38,6 +38,9 @@ import javaclasses.mealorder.VendorId; import javaclasses.mealorder.VendorName; +import java.util.ArrayList; +import java.util.List; + import static io.spine.time.MonthOfYear.FEBRUARY; import static io.spine.time.Time.getCurrentTime; import static javaclasses.mealorder.OrderStatus.ORDER_ACTIVE; @@ -55,10 +58,18 @@ public class TestValues { .setValue("VendorName1") .build(); + public static final VendorName VENDOR_NAME2 = VendorName.newBuilder() + .setValue("Позитив") + .build(); + public static final VendorId VENDOR_ID = VendorId.newBuilder() .setValue("vendor:" + VENDOR_NAME) .build(); + public static final VendorId VENDOR_ID2 = VendorId.newBuilder() + .setValue("vendor:" + VENDOR_NAME2) + .build(); + public static final VendorName NEW_VENDOR_NAME = VendorName.newBuilder() .setValue("VendorName2") .build(); @@ -74,6 +85,13 @@ public class TestValues { .build()) .build(); + public static final UserId USER_ID2 = UserId.newBuilder() + .setEmail(EmailAddress.newBuilder() + .setValue( + "petr@example.com") + .build()) + .build(); + public static final LocalTime PO_DAILY_DEADLINE = LocalTime.newBuilder() .setHours(10) .setMinutes(0) @@ -256,4 +274,61 @@ public class TestValues { .addDish(DISH1) .setStatus(ORDER_ACTIVE) .build(); + public static final List BIG_ORDER = createOrder(); + + private static List createOrder() { + List orders = new ArrayList<>(); + final Order order1 = Order.newBuilder() + .addDish(DISH1) + .addDish(DISH1) + .addDish(DISH2) + .addDish(DISH2) + .addDish(DISH2) + .setId( + OrderId.newBuilder() + .setUserId(USER_ID) + .setVendorId(VENDOR_ID) + .setOrderDate(END_DATE) + .build()) + .build(); + final Order order2 = Order.newBuilder() + .addDish(DISH1) + .addDish(DISH1) + .addDish(DISH2) + .addDish(DISH2) + .addDish(DISH2) + .setId( + OrderId.newBuilder() + .setUserId(USER_ID2) + .setVendorId(VENDOR_ID) + .setOrderDate(END_DATE) + .build()) + .build(); + final Order order3 = Order.newBuilder() + .addDish(DISH2) + .addDish(DISH2) + .setId( + OrderId.newBuilder() + .setUserId(USER_ID) + .setVendorId(VENDOR_ID2) + .setOrderDate(END_DATE) + .build()) + .build(); + final Order order4 = Order.newBuilder() + .addDish(DISH1) + .addDish(DISH1) + .addDish(DISH2) + .setId( + OrderId.newBuilder() + .setUserId(USER_ID2) + .setVendorId(VENDOR_ID2) + .setOrderDate(END_DATE) + .build()) + .build(); + orders.add(order1); + orders.add(order2); + orders.add(order3); + orders.add(order4); + return orders; + } } From 154d7e3ec3ee49e5e377e3cc07c187543fa37e35 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Fri, 20 Apr 2018 19:07:55 +0300 Subject: [PATCH 24/66] Refactor PO by user view --- .../mealorder/q/PurchaseOrderDetailsByUserViewProjection.java | 4 ++-- .../main/java/javaclasses/mealorder/testdata/TestValues.java | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java index b0c56c08..8cb0cbaa 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java @@ -108,8 +108,8 @@ private List getDishItemsForUser(UserId user, List orderList) { final List dishItems = new ArrayList<>(); orderList.forEach(order -> { if (order.getId() - .getUserId() == user) { - + .getUserId() + .equals(user)) { order.getDishList() .forEach(dish -> { final DishItem dishItem = DishItem.newBuilder() diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java index 6ef9d502..ce231216 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java @@ -281,9 +281,7 @@ private static List createOrder() { final Order order1 = Order.newBuilder() .addDish(DISH1) .addDish(DISH1) - .addDish(DISH2) - .addDish(DISH2) - .addDish(DISH2) + .addDish(DISH1) .setId( OrderId.newBuilder() .setUserId(USER_ID) From 8bce763eda9f0af17459ab9c7f5e8300554ea141 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Mon, 23 Apr 2018 12:09:50 +0300 Subject: [PATCH 25/66] Add identifiers for singletons --- .../mealorder/c/MealOrderEnrichments.java | 20 ++++++------- .../javaclasses/mealorder/identifiers.proto | 24 +++++++++++++++ .../javaclasses/mealorder/q/projections.proto | 30 ++++++++----------- .../javaclasses/mealorder/q/values.proto | 19 +----------- .../proto/javaclasses/mealorder/values.proto | 2 +- 5 files changed, 48 insertions(+), 47 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/c/MealOrderEnrichments.java b/api-java/src/main/java/javaclasses/mealorder/c/MealOrderEnrichments.java index eef6c9ff..4909ef9d 100644 --- a/api-java/src/main/java/javaclasses/mealorder/c/MealOrderEnrichments.java +++ b/api-java/src/main/java/javaclasses/mealorder/c/MealOrderEnrichments.java @@ -33,10 +33,10 @@ @SuppressWarnings("Guava") // Spine Java 7 API. final class MealOrderEnrichments { - private final PurchaseOrderRepository taskRepo; + private final PurchaseOrderRepository poRepository; private MealOrderEnrichments(Builder builder) { - this.taskRepo = builder.taskRepo; + this.poRepository = builder.poRepository; } /** @@ -55,17 +55,17 @@ EventEnricher createEnricher() { } private Function poIdToPo() { - final Function result = taskId -> { - if (taskId == null) { + final Function result = poId -> { + if (poId == null) { return PurchaseOrder.getDefaultInstance(); } - final Optional aggregate = taskRepo.find(taskId); + final Optional aggregate = poRepository.find(poId); if (!aggregate.isPresent()) { return PurchaseOrder.getDefaultInstance(); } - final PurchaseOrder task = aggregate.get() - .getState(); - return task; + final PurchaseOrder po = aggregate.get() + .getState(); + return po; }; return result; } @@ -84,7 +84,7 @@ static Builder newBuilder() { */ static class Builder { - private PurchaseOrderRepository taskRepo; + private PurchaseOrderRepository poRepository; /** * The {@code private} constructor prevents direct instantiation. @@ -94,7 +94,7 @@ private Builder() { Builder setPurchaseOrderRepository(PurchaseOrderRepository definitionRepository) { checkNotNull(definitionRepository); - this.taskRepo = definitionRepository; + this.poRepository = definitionRepository; return this; } diff --git a/model/src/main/proto/javaclasses/mealorder/identifiers.proto b/model/src/main/proto/javaclasses/mealorder/identifiers.proto index c802ed99..8d13a5c5 100644 --- a/model/src/main/proto/javaclasses/mealorder/identifiers.proto +++ b/model/src/main/proto/javaclasses/mealorder/identifiers.proto @@ -35,6 +35,30 @@ import "spine/net/email_address.proto"; import "spine/time/time.proto"; import "javaclasses/mealorder/attributes.proto"; +// The ID of the vendor list. +// +message VendorListId { + + // The ID of the vendor list + string value = 1; +} + +// The ID of the purchase order list. +// +message PurchaseOrderListId { + + // The ID of the purchase order list. + string value = 1; +} + +// The ID of the calendar. +// +message MenuCalendarId { + + // The ID of the calendar. + string value = 1; +} + // The ID of a user. // // Represented by the user's email address. diff --git a/model/src/main/proto/javaclasses/mealorder/q/projections.proto b/model/src/main/proto/javaclasses/mealorder/q/projections.proto index eef489cc..79390427 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/projections.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/projections.proto @@ -77,8 +77,11 @@ message MenuListView { // message MenuCalendarView { + // The identifier of the calendar. + MenuCalendarId menu_calendar_id = 1; + // The collection of calendar items (dates). - repeated MenuCalendarItem calendar_item = 1; + repeated MenuCalendarItem calendar_item = 2; } // The projection state of an order list. @@ -116,23 +119,11 @@ message OrderListView { // message VendorListView { - // The collection of all vendors. - repeated VendorItem vendor = 1; -} + // The identifier of the vendor list singleton. + VendorListId vendor_list_id = 1; -// The projection state of the full menu list. -// -// This view includes the list of all menus, -// sorted by menu date range. -// -// Subscribes following events: -// 1. `DateRangeForMenuSet` -// 2. `MenuImported` -// -message FullMenuListView { - - // The collection of all menus. - repeated FullMenuItem menu = 1; + // The collection of all vendors. + repeated VendorItem vendor = 2; } // The projection state of the purchase order list. @@ -151,8 +142,11 @@ message FullMenuListView { // message PurchaseOrderListView { + // The identifier of the purchase order list singleton. + PurchaseOrderListId purchase_order_list_id = 1; + // The collection of all purchase orders. - repeated PurchaseOrderItem purchase_order = 1; + repeated PurchaseOrderItem purchase_order = 2; } // The projection state of a purchase order details view diff --git a/model/src/main/proto/javaclasses/mealorder/q/values.proto b/model/src/main/proto/javaclasses/mealorder/q/values.proto index 2cdd9864..413ff83f 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/values.proto @@ -50,11 +50,8 @@ message MenuItem { // The collection of categories. repeated DishesByCategory dishesByCategory = 2; - // True if a user can add dishes to his order. - bool is_available = 3; - // Date range when a menu is available. - repeated MenuForDay menu_days = 4; + repeated MenuForDay menu_days = 3; } // Dishes grouped by category. @@ -139,20 +136,6 @@ message VendorItem { spine.time.LocalTime po_daily_deadline = 5; } -// The item of the full menu list. -// -message FullMenuItem { - - // The identifier of a menu. - MenuId menu_id = 1; - - // Date range when a menu is available. - MenuDateRange menu_date_range = 2; - - // The collection of categories. - repeated DishesByCategory dish = 3; -} - // The item of the purchase order list. // message PurchaseOrderItem { diff --git a/model/src/main/proto/javaclasses/mealorder/values.proto b/model/src/main/proto/javaclasses/mealorder/values.proto index fa72fa30..22fe4fa4 100644 --- a/model/src/main/proto/javaclasses/mealorder/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/values.proto @@ -46,7 +46,7 @@ message MenuForDay { spine.time.LocalDate date = 1; // If available a user can add dishes to his order. - bool available = 2; + bool is_available = 2; } // Name of a category. From e825c1ee587fbb44e7e747370f819cdceb7c70d3 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Mon, 23 Apr 2018 12:42:02 +0300 Subject: [PATCH 26/66] Rework monthly spendings -> now has list of pending orders --- .../main/proto/javaclasses/mealorder/c/events.proto | 2 +- .../proto/javaclasses/mealorder/q/projections.proto | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/model/src/main/proto/javaclasses/mealorder/c/events.proto b/model/src/main/proto/javaclasses/mealorder/c/events.proto index 29d9ffde..9213f541 100644 --- a/model/src/main/proto/javaclasses/mealorder/c/events.proto +++ b/model/src/main/proto/javaclasses/mealorder/c/events.proto @@ -227,7 +227,7 @@ message PurchaseOrderDelivered { // message PurchaseOrderSent { - // The identifier of a purchase order. + // Purchase order. PurchaseOrder purchase_order = 1; // Was sent at this time. diff --git a/model/src/main/proto/javaclasses/mealorder/q/projections.proto b/model/src/main/proto/javaclasses/mealorder/q/projections.proto index 79390427..1754c3be 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/projections.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/projections.proto @@ -209,7 +209,9 @@ message PurchaseOrderDetailsByUserView { // It contains users spendings for period from month first // date till today if a report is formed for the current month. // -// Subscribes on PurchaseOrderDelivered: +// Subscribes following events: +// 1. `PurchaseOrderDelivered` +// 2. `PurchaseOrderSent` // message MonthlySpendingsReportView { @@ -218,4 +220,10 @@ message MonthlySpendingsReportView { // The collection of users spendings for the specified month. repeated UserSpendings user_spending = 2; + + // List of orders. + // + // Created on `PurchaseOrderSent` and on `PurchaseOrderDelivered` + // users spendings will be added to the users' monthly spendings. + repeated UserOrderDetails order = 3; } From 3974c7500a01d5438b98292470d17e2f5d02312b Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Mon, 23 Apr 2018 12:51:39 +0300 Subject: [PATCH 27/66] Delete enrichments --- .../q/EnrichmentNotFoundException.java | 39 ------------ .../mealorder/q/EventEnrichments.java | 57 ----------------- .../q/FullMenuListViewProjection.java | 62 ------------------- .../mealorder/q/MenuListViewProjection.java | 2 - .../MonthlySpendingsReportViewProjection.java | 10 --- .../javaclasses/mealorder/c/enrichments.proto | 43 ------------- .../javaclasses/mealorder/q/projections.proto | 3 +- 7 files changed, 1 insertion(+), 215 deletions(-) delete mode 100644 api-java/src/main/java/javaclasses/mealorder/q/EnrichmentNotFoundException.java delete mode 100644 api-java/src/main/java/javaclasses/mealorder/q/EventEnrichments.java delete mode 100644 api-java/src/main/java/javaclasses/mealorder/q/FullMenuListViewProjection.java delete mode 100644 model/src/main/proto/javaclasses/mealorder/c/enrichments.proto diff --git a/api-java/src/main/java/javaclasses/mealorder/q/EnrichmentNotFoundException.java b/api-java/src/main/java/javaclasses/mealorder/q/EnrichmentNotFoundException.java deleted file mode 100644 index 4550c2af..00000000 --- a/api-java/src/main/java/javaclasses/mealorder/q/EnrichmentNotFoundException.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2018, TeamDev Ltd. All rights reserved. - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package javaclasses.mealorder.q; - -/** - * An exception thrown when enrichment cannot be found in - * {@link io.spine.core.EventContext EventContext}. - * - * @author Illia Shepilov - */ -final class EnrichmentNotFoundException extends RuntimeException { - - private static final long serialVersionUID = 0L; - - /** - * @see RuntimeException#RuntimeException(String) - */ - EnrichmentNotFoundException(String message) { - super(message); - } -} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/EventEnrichments.java b/api-java/src/main/java/javaclasses/mealorder/q/EventEnrichments.java deleted file mode 100644 index 22871b33..00000000 --- a/api-java/src/main/java/javaclasses/mealorder/q/EventEnrichments.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2018, TeamDev Ltd. All rights reserved. - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package javaclasses.mealorder.q; - -import com.google.common.base.Optional; -import com.google.protobuf.Message; -import io.spine.core.Enrichments; -import io.spine.core.EventContext; - -/** - * Utility class for working with enrichments. - * - * @author Illia Shepilov - */ -final class EventEnrichments { - - /** - * The {@code private} constructor prevents the utility class instantiation. - */ - private EventEnrichments() { - } - - /** - * Obtains enrichment from the {@link EventContext} according to the enrichment class. - * - * @param enrichmentClass the class of the enrichment - * @param context the {@code EventContext} - * @return the enrichment if it is present, throws {@code EnrichmentNotFoundException} otherwise - */ - @SuppressWarnings("Guava") // Spine Java 7 API - static > - T getEnrichment(E enrichmentClass, EventContext context) { - final Optional enrichmentOptional = Enrichments.getEnrichment(enrichmentClass, context); - if (enrichmentOptional.isPresent()) { - return enrichmentOptional.get(); - } - throw new EnrichmentNotFoundException(enrichmentClass + " not found"); - } -} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/FullMenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/FullMenuListViewProjection.java deleted file mode 100644 index 41b17987..00000000 --- a/api-java/src/main/java/javaclasses/mealorder/q/FullMenuListViewProjection.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2018, TeamDev Ltd. All rights reserved. - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package javaclasses.mealorder.q; - -import io.spine.core.Subscribe; -import io.spine.server.projection.Projection; -import javaclasses.mealorder.VendorId; -import javaclasses.mealorder.c.event.DateRangeForMenuSet; -import javaclasses.mealorder.c.event.MenuImported; -import javaclasses.mealorder.q.projection.FullMenuListView; -import javaclasses.mealorder.q.projection.FullMenuListViewVBuilder; - -public class FullMenuListViewProjection extends Projection { - - /** - * {@link MenuCalendarViewProjection} is a singleton. - * - *

The {@code ID} value should be the same for all JVMs - * to support work with the same projection from execution to execution. - */ - public static final VendorId ID = VendorId.newBuilder() - .setValue("FullMenuListViewProjectionSingleton") - .build(); - - /** - * Creates a new instance. - * - * @param id the ID for the new instance - * @throws IllegalArgumentException if the ID is not of one of the supported types - */ - public FullMenuListViewProjection(VendorId id) { - super(id); - } - - @Subscribe - void on(DateRangeForMenuSet event) { - - } - - @Subscribe - void on(MenuImported event) { - - } -} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java index d07eb80d..7a30edca 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java @@ -61,7 +61,6 @@ void on(MenuImported event) { event.getDishList()); final MenuItem menuItem = MenuItem.newBuilder() .setVendorName(vendorName) - .setIsAvailable(true) .addAllDishesByCategory(allDishesByCategories) .build(); getBuilder().addMenu(menuItem); @@ -90,7 +89,6 @@ void on(DateRangeForMenuSet event) { .build(); final MenuForDay menuForDay = MenuForDay.newBuilder() .setDate(localDate) - .setAvailable(true) .build(); menuDays.add(menuForDay); }); diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java index a402ecc7..6133f1c2 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java @@ -24,17 +24,11 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; import javaclasses.mealorder.MenuListId; -import javaclasses.mealorder.Order; -import javaclasses.mealorder.PurchaseOrder; import javaclasses.mealorder.PurchaseOrderId; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; -import javaclasses.mealorder.c.event.PurchaseOrderEnrichment; import javaclasses.mealorder.q.projection.MonthlySpendingsReportView; import javaclasses.mealorder.q.projection.MonthlySpendingsReportViewVBuilder; -import java.util.List; - -import static javaclasses.mealorder.q.EventEnrichments.getEnrichment; public class MonthlySpendingsReportViewProjection extends Projection { @@ -52,9 +46,5 @@ public MonthlySpendingsReportViewProjection(MenuListId id) { @Subscribe void on(PurchaseOrderDelivered event, EventContext context) { final PurchaseOrderId taskId = event.getId(); - final PurchaseOrderEnrichment enrichment = getEnrichment(PurchaseOrderEnrichment.class, - context); - final PurchaseOrder po = enrichment.getPurchaseOrder(); - final List orderList = po.getOrderList(); } } diff --git a/model/src/main/proto/javaclasses/mealorder/c/enrichments.proto b/model/src/main/proto/javaclasses/mealorder/c/enrichments.proto deleted file mode 100644 index 86fb0b7a..00000000 --- a/model/src/main/proto/javaclasses/mealorder/c/enrichments.proto +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2018, TeamDev Ltd. All rights reserved. - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -syntax = "proto3"; - -package javaclasses.mealorder.c; - -import "spine/options.proto"; - -option (type_url_prefix) = "type.javaclasses.mealorder"; -option java_package = "javaclasses.mealorder.c.event"; -option java_outer_classname = "EnrichmentsProto"; -option java_multiple_files = true; -option java_generate_equals_and_hash = true; - -import "javaclasses/mealorder/model.proto"; -import "javaclasses/mealorder/values.proto"; - -// Task enrichment for the `PurchaseOrderDelivered` event. -// -message PurchaseOrderEnrichment { - option (enrichment_for) = "javaclasses.mealorder.c.PurchaseOrderDelivered"; - - // The state of the PO produced by PO created. - PurchaseOrder purchase_order = 1 [(by) = "id"]; -} diff --git a/model/src/main/proto/javaclasses/mealorder/q/projections.proto b/model/src/main/proto/javaclasses/mealorder/q/projections.proto index 1754c3be..667cd1d5 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/projections.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/projections.proto @@ -72,8 +72,7 @@ message MenuListView { // today to the same day next week. (8 elements) // The each date contains information about the menus availability for it. // -// Subscribes following events: -// 1. `DateRangeForMenuSet` +// Subscribes on `DateRangeForMenuSet` // message MenuCalendarView { From e71107c0f5e645df2583f037df0b427291842c78 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Mon, 23 Apr 2018 12:57:28 +0300 Subject: [PATCH 28/66] Add projections IDs to java classes --- .../mealorder/q/MenuCalendarViewProjection.java | 16 +++++++--------- .../mealorder/q/MenuListViewProjection.java | 6 +++--- .../q/MonthlySpendingsReportViewProjection.java | 7 +++---- .../mealorder/q/OrderListViewProjection.java | 4 ++-- .../q/PurchaseOrderListViewProjection.java | 15 +++++++-------- .../mealorder/q/VendorListViewProjection.java | 11 ++++++----- 6 files changed, 28 insertions(+), 31 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java index c46e3d43..00f2fe95 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java @@ -22,9 +22,8 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; +import javaclasses.mealorder.MenuCalendarId; import javaclasses.mealorder.MenuDateRange; -import javaclasses.mealorder.MenuId; -import javaclasses.mealorder.VendorId; import javaclasses.mealorder.c.event.DateRangeForMenuSet; import javaclasses.mealorder.q.projection.MenuCalendarView; import javaclasses.mealorder.q.projection.MenuCalendarViewVBuilder; @@ -35,7 +34,7 @@ import static javaclasses.mealorder.q.Projections.getDatesBetween; import static javaclasses.mealorder.q.Projections.toLocalDate; -public class MenuCalendarViewProjection extends Projection { +public class MenuCalendarViewProjection extends Projection { /** * {@link MenuCalendarViewProjection} is a singleton. @@ -43,11 +42,10 @@ public class MenuCalendarViewProjection extends ProjectionThe {@code ID} value should be the same for all JVMs * to support work with the same projection from execution to execution. */ - public static final MenuId ID = MenuId.newBuilder() - .setVendorId(VendorId.newBuilder() - .setValue( - "MenuCalendarViewProjectionSingleton")) - .build(); + public static final MenuCalendarId ID = MenuCalendarId.newBuilder() + .setValue( + "MenuCalendarViewProjectionSingleton") + .build(); /** * Creates a new instance. @@ -55,7 +53,7 @@ public class MenuCalendarViewProjection extends Projection { +public class MenuListViewProjection extends Projection { /** * Creates a new instance. @@ -47,7 +47,7 @@ public class MenuListViewProjection extends Projection { +public class MonthlySpendingsReportViewProjection extends Projection { /** * Creates a new instance. @@ -38,7 +37,7 @@ public class MonthlySpendingsReportViewProjection extends Projection { +public class OrderListViewProjection extends Projection { /** * Creates a new instance. @@ -46,7 +46,7 @@ public class OrderListViewProjection extends Projection { +public class PurchaseOrderListViewProjection extends Projection { /** * {@link MenuCalendarViewProjection} is a singleton. @@ -42,11 +42,10 @@ public class PurchaseOrderListViewProjection extends ProjectionThe {@code ID} value should be the same for all JVMs * to support work with the same projection from execution to execution. */ - public static final PurchaseOrderId ID = PurchaseOrderId.newBuilder() - .setVendorId(VendorId.newBuilder() - .setValue( - "PurchaseOrderListViewProjectionSingleton")) - .build(); + public static final PurchaseOrderListId ID = PurchaseOrderListId.newBuilder() + .setValue( + "PurchaseOrderListViewProjectionSingleton") + .build(); /** * Creates a new instance. @@ -54,7 +53,7 @@ public class PurchaseOrderListViewProjection extends Projection { +public class VendorListViewProjection extends Projection { /** * {@link VendorListViewProjection} is a singleton. @@ -42,9 +43,9 @@ public class VendorListViewProjection extends ProjectionThe {@code ID} value should be the same for all JVMs * to support work with the same projection from execution to execution. */ - public static final VendorId ID = VendorId.newBuilder() - .setValue("VendorListViewProjectionSingleton") - .build(); + public static final VendorListId ID = VendorListId.newBuilder() + .setValue("VendorListViewProjectionSingleton") + .build(); /** * Creates a new instance. @@ -52,7 +53,7 @@ public class VendorListViewProjection extends Projection Date: Mon, 23 Apr 2018 14:17:08 +0300 Subject: [PATCH 29/66] Add subscribes for the MonthlySpendingsReportView projection --- .../mealorder/c/po/PurchaseOrders.java | 2 +- .../q/MenuCalendarViewProjection.java | 1 - .../MonthlySpendingsReportViewProjection.java | 32 +++++++++++++++++-- .../javaclasses/mealorder/c/events.proto | 2 +- .../testdata/TestMealOrderEventFactory.java | 2 +- 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/c/po/PurchaseOrders.java b/api-java/src/main/java/javaclasses/mealorder/c/po/PurchaseOrders.java index 63db91c6..b43eff4f 100644 --- a/api-java/src/main/java/javaclasses/mealorder/c/po/PurchaseOrders.java +++ b/api-java/src/main/java/javaclasses/mealorder/c/po/PurchaseOrders.java @@ -221,7 +221,7 @@ static PurchaseOrderDelivered createPOMarkedAsDeliveredEvent(MarkPurchaseOrderAs .newBuilder() .setId(id) .setWhoMarkedAsDelivered(whoMarksAsDelivered) - .setWhenDelievered(getCurrentTime()) + .setWhenDelivered(getCurrentTime()) .build(); return result; diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java index c46e3d43..4c8ab716 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java @@ -61,7 +61,6 @@ public MenuCalendarViewProjection(MenuId id) { @Subscribe void on(DateRangeForMenuSet event) { - final MenuDateRange menuDateRange = event.getMenuDateRange(); final List datesBetween = getDatesBetween(event.getMenuDateRange() .getRangeStart(), event.getMenuDateRange() diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java index 6133f1c2..c14b32f6 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java @@ -20,12 +20,17 @@ package javaclasses.mealorder.q; -import io.spine.core.EventContext; +import com.google.protobuf.Timestamp; import io.spine.core.Subscribe; +import io.spine.net.EmailAddress; import io.spine.server.projection.Projection; import javaclasses.mealorder.MenuListId; +import javaclasses.mealorder.MonthlySpendingsReportId; +import javaclasses.mealorder.PurchaseOrder; import javaclasses.mealorder.PurchaseOrderId; +import javaclasses.mealorder.UserId; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; +import javaclasses.mealorder.c.event.PurchaseOrderSent; import javaclasses.mealorder.q.projection.MonthlySpendingsReportView; import javaclasses.mealorder.q.projection.MonthlySpendingsReportViewVBuilder; @@ -42,9 +47,30 @@ public MonthlySpendingsReportViewProjection(MenuListId id) { super(id); } - //todo: pasha @Subscribe - void on(PurchaseOrderDelivered event, EventContext context) { + void on(PurchaseOrderDelivered event) { final PurchaseOrderId taskId = event.getId(); + final UserId userId = event.getWhoMarkedAsDelivered(); + final Timestamp whenDelivered = event.getWhenDelivered(); + + final UserSpendings userSpendings = UserSpendings.newBuilder().build(); + final UserOrderDetails userOrderDetails = UserOrderDetails.newBuilder().build(); + + getBuilder().addUserSpending(userSpendings); + getBuilder().addOrder(userOrderDetails); + } + + @Subscribe + void on(PurchaseOrderSent event) { + final PurchaseOrder purchaseOrder = event.getPurchaseOrder(); + final Timestamp whenSent = event.getWhenSent(); + final EmailAddress senderEmail = event.getSenderEmail(); + final EmailAddress vendorEmail = event.getVendorEmail(); + + final UserSpendings userSpendings = UserSpendings.newBuilder().build(); + final UserOrderDetails userOrderDetails = UserOrderDetails.newBuilder().build(); + + getBuilder().addUserSpending(userSpendings); + getBuilder().addOrder(userOrderDetails); } } diff --git a/model/src/main/proto/javaclasses/mealorder/c/events.proto b/model/src/main/proto/javaclasses/mealorder/c/events.proto index 9213f541..711974a3 100644 --- a/model/src/main/proto/javaclasses/mealorder/c/events.proto +++ b/model/src/main/proto/javaclasses/mealorder/c/events.proto @@ -220,7 +220,7 @@ message PurchaseOrderDelivered { UserId who_marked_as_delivered = 2; // Was delivered at this time. - google.protobuf.Timestamp when_delievered = 3; + google.protobuf.Timestamp when_delivered = 3; } // The event signalizing about the successful sending of a purchase order. diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java index 2a97f847..e70156e0 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java @@ -88,7 +88,7 @@ private static PurchaseOrderDelivered purchaseOrderDeliveredInstance( PurchaseOrderDelivered.newBuilder() .setId(purchaseOrderId) .setWhoMarkedAsDelivered(userId) - .setWhenDelievered(currentTime) + .setWhenDelivered(currentTime) .build(); return result; } From 70c4012e3de7f2d15c6e39fb687aac599236d543 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Mon, 23 Apr 2018 15:37:28 +0300 Subject: [PATCH 30/66] Add subscribers for `MenuListViewProjection` --- .../mealorder/q/MenuListViewProjection.java | 82 +++++++++++++++--- .../javaclasses/mealorder/q/Projections.java | 5 ++ ...chaseOrderDetailsByDishViewProjection.java | 2 +- .../MenuListViewProjectionTest.java | 71 ++++++++++++++++ .../q/projection/ProjectionTest.java | 12 +-- .../testdata/TestEventEnricherFactory.java | 46 ---------- .../testdata/TestMealOrderEventFactory.java | 21 +++++ .../mealorder/testdata/TestValues.java | 85 +++++++++++++++++++ 8 files changed, 256 insertions(+), 68 deletions(-) create mode 100644 api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java delete mode 100644 testutil-api/src/main/java/javaclasses/mealorder/testdata/TestEventEnricherFactory.java diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java index 917bfdd8..c9d7f196 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java @@ -20,9 +20,11 @@ package javaclasses.mealorder.q; +import com.google.protobuf.Timestamp; import io.spine.core.Subscribe; import io.spine.server.projection.Projection; import io.spine.time.LocalDate; +import javaclasses.mealorder.CategoryName; import javaclasses.mealorder.Dish; import javaclasses.mealorder.MenuDateRange; import javaclasses.mealorder.MenuForDay; @@ -36,8 +38,11 @@ import java.util.ArrayList; import java.util.List; +import java.util.OptionalInt; +import java.util.stream.IntStream; import static javaclasses.mealorder.q.Projections.getDatesBetween; +import static javaclasses.mealorder.q.Projections.timeStampToLocalDate; public class MenuListViewProjection extends Projection { @@ -57,19 +62,14 @@ void on(MenuImported event) { .setValue(event.getVendorId() .getValue()) .build(); - final Iterable allDishesByCategories = getAllDishesByCategories( + final List allDishesByCategories = getAllDishesByCategories( event.getDishList()); final MenuItem menuItem = MenuItem.newBuilder() .setVendorName(vendorName) .addAllDishesByCategory(allDishesByCategories) .build(); getBuilder().addMenu(menuItem); - // Todo : Pasha from Timestamp to LocalDate or change proto files -// final MenuListId menuListId = MenuListId.newBuilder() -// .setDate(event.getWhenImported() -// .getSeconds())) -// .build(); -// getBuilder().setListId(menuListId); + } @Subscribe @@ -89,6 +89,7 @@ void on(DateRangeForMenuSet event) { .build(); final MenuForDay menuForDay = MenuForDay.newBuilder() .setDate(localDate) + .setIsAvailable(true) .build(); menuDays.add(menuForDay); }); @@ -101,11 +102,72 @@ void on(DateRangeForMenuSet event) { @Subscribe void on(PurchaseOrderCreated event) { - //Todo: pasha disables menus + final List newMenu = getBuilder().getMenu(); + for (int i = 0; i < newMenu.size(); i++) { + final MenuItem menuItem = newMenu.get(i); + final List menuDaysList = menuItem.getMenuDaysList(); + for (int j = 0; j < menuDaysList.size(); j++) { + final MenuForDay menuForDay = menuDaysList.get(j); + final Timestamp whenCreated = event.getWhenCreated(); + final LocalDate date = timeStampToLocalDate(whenCreated); + if (menuForDay.getDate() + .equals(date)) { + final MenuForDay newMenuForDay = MenuForDay.newBuilder() + .setDate(date) + .setIsAvailable(false) + .build(); + menuDaysList.set(j, newMenuForDay); + } + } + final MenuItem newMenuItem = MenuItem.newBuilder(menuItem) + .clearMenuDays() + .addAllMenuDays(menuDaysList) + .build(); + newMenu.set(i, newMenuItem); + } + getBuilder().clearMenu() + .addAllMenu(newMenu); } - private Iterable getAllDishesByCategories( + private List getAllDishesByCategories( List dishList) { - return null; + final List dishesByCategoryList = new ArrayList<>(); + dishList.forEach(dish -> { + final int index = categoryIndex(dishesByCategoryList, dish.getCategory()); + final DishItem newDish = DishItem.newBuilder() + .setId(dish.getId()) + .setName(dish.getName()) + .setPrice(dish.getPrice()) + .build(); + if (index == -1) { + final CategoryName category = CategoryName.newBuilder() + .setValue(dish.getCategory()) + .build(); + + final DishesByCategory dishesByCategory = DishesByCategory.newBuilder() + .setCategory(category) + .addDishes(newDish) + .build(); + dishesByCategoryList.add(dishesByCategory); + } else { + final DishesByCategory newDishesByCategory = DishesByCategory.newBuilder( + dishesByCategoryList.get(index)) + .addDishes(newDish) + .build(); + dishesByCategoryList.set(index, newDishesByCategory); + } + }); + return dishesByCategoryList; + } + + private int categoryIndex(List dishByCategory, String category) { + final OptionalInt optionalInt = IntStream.range(0, dishByCategory.size()) + .filter(i -> dishByCategory.get(i) + .getCategory() + .getValue() + .equals(category)) + .findFirst(); + return optionalInt.isPresent() ? optionalInt.getAsInt() : -1; } + } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java index 8d96d55c..7078ec8c 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java @@ -20,6 +20,7 @@ package javaclasses.mealorder.q; +import com.google.protobuf.Timestamp; import io.spine.time.LocalDate; import java.time.temporal.ChronoUnit; @@ -57,4 +58,8 @@ static LocalDate toLocalDate(java.time.LocalDate date) { .setYear(date.getYear()) .build(); } + + static LocalDate timeStampToLocalDate(Timestamp timestamp) { + return null; + } } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java index 01b90c1b..15e57e03 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java @@ -73,7 +73,7 @@ void on(PurchaseOrderValidationFailed event) { } private List getDishItems(List orderList) { - List dishItems = new ArrayList<>(); + final List dishItems = new ArrayList<>(); orderList.forEach(order -> order.getDishList() .forEach(dish -> { diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java new file mode 100644 index 00000000..b351d358 --- /dev/null +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.projection; + +import javaclasses.mealorder.MenuListId; +import javaclasses.mealorder.c.event.DateRangeForMenuSet; +import javaclasses.mealorder.c.event.MenuImported; +import javaclasses.mealorder.q.MenuListViewProjection; +import javaclasses.mealorder.testdata.TestValues; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.VendorEvents.dateRangeForMenuSetInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.VendorEvents.menuImportedInstance; + +public class MenuListViewProjectionTest extends ProjectionTest { + private MenuListViewProjection projection; + + @BeforeEach + void setUp() { + projection = new MenuListViewProjection(MenuListId.newBuilder() + .setDate(TestValues.DATE) + .build()); + } + + @Nested + @DisplayName("MenuImported event should be interpreted by MenuListViewProjection") + class MenuImportedEvent { + @Test + @DisplayName("Should import menu") + void addView() { + final MenuImported menuImported = menuImportedInstance(); + dispatch(projection, createEvent(menuImported)); + } + } + + @Nested + @DisplayName("DateRangeForMenuSet event should be interpreted by MenuListViewProjection") + class DateRangeForMenuSetEvent { + @Test + @DisplayName("Should set dates with menus") + void addView() { + final MenuImported menuImported = menuImportedInstance(); + dispatch(projection, createEvent(menuImported)); + final DateRangeForMenuSet dateRangeForMenuSet = dateRangeForMenuSetInstance(); + dispatch(projection, createEvent(dateRangeForMenuSet)); + } + } +} + diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionTest.java index b27a0147..b315216a 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionTest.java @@ -22,25 +22,15 @@ import com.google.protobuf.Message; import io.spine.core.Event; -import io.spine.core.EventEnvelope; import io.spine.server.command.TestEventFactory; -import io.spine.server.event.EventEnricher; import io.spine.server.event.EventFactory; -import javaclasses.mealorder.testdata.TestEventEnricherFactory; abstract class ProjectionTest { private final EventFactory eventFactory = TestEventFactory.newInstance(getClass()); - private final EventEnricher enricher = TestEventEnricherFactory.eventEnricherInstance(); Event createEvent(Message messageOrAny) { final Event event = eventFactory.createEvent(messageOrAny, null); - final EventEnvelope envelope = EventEnvelope.of(event); - if (!enricher.canBeEnriched(envelope)) { - return event; - } - - return enricher.enrich(envelope) - .getOuterObject(); + return event; } } diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestEventEnricherFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestEventEnricherFactory.java deleted file mode 100644 index 536d2392..00000000 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestEventEnricherFactory.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2018, TeamDev Ltd. All rights reserved. - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package javaclasses.mealorder.testdata; - -import io.spine.server.event.EventEnricher; - -public class TestEventEnricherFactory { -// private static final Function PO_ID_TO_ORDER = -// taskId -> bookDetails; - - private TestEventEnricherFactory() { - } - - /** - * Provides a pre-configured {@link EventEnricher} event instance. - * - * @return {@code EventEnricher} - */ - public static EventEnricher eventEnricherInstance() { -// final EventEnricher result = EventEnricher.newBuilder() -// .add(PurchaseOrderId.class, -// PurchaseOrder.class, -// PoIdTo::apply) -// .build(); - return EventEnricher.newBuilder() - .build(); - } -} diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java index 2a97f847..c2ca05c1 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java @@ -22,6 +22,7 @@ import com.google.protobuf.Timestamp; import io.spine.net.EmailAddress; +import javaclasses.mealorder.Dish; import javaclasses.mealorder.MenuDateRange; import javaclasses.mealorder.MenuId; import javaclasses.mealorder.Order; @@ -31,6 +32,7 @@ import javaclasses.mealorder.UserId; import javaclasses.mealorder.VendorId; import javaclasses.mealorder.c.event.DateRangeForMenuSet; +import javaclasses.mealorder.c.event.MenuImported; import javaclasses.mealorder.c.event.PurchaseOrderCreated; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; @@ -137,5 +139,24 @@ private static DateRangeForMenuSet dateRangeForMenuSetInstance(VendorId vendorId .build(); return result; } + + public static MenuImported menuImportedInstance() { + return menuImportedInstance(TestValues.VENDOR_ID, TestValues.MENU_ID, + TestValues.USER_ID, TestValues.BIG_MENU); + } + + private static MenuImported menuImportedInstance(VendorId vendorId, MenuId menuId, + UserId whoImported, List dishes) { + final Timestamp currentTime = getCurrentTime(); + final MenuImported result = + MenuImported.newBuilder() + .setVendorId(vendorId) + .setMenuId(menuId) + .setWhoImported(whoImported) + .setWhenImported(currentTime) + .addAllDish(dishes) + .build(); + return result; + } } } diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java index ce231216..d9c21587 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java @@ -127,6 +127,11 @@ public class TestValues { .setWhenImported(getCurrentTime()) .build(); + public static final MenuId MENU_ID2 = MenuId.newBuilder() + .setVendorId(VENDOR_ID2) + .setWhenImported(getCurrentTime()) + .build(); + public static final MenuId NONEXISTENT_MENU_ID = MenuId.newBuilder() .setVendorId(VENDOR_ID) .setWhenImported( @@ -219,6 +224,73 @@ public class TestValues { .setPrice(Money.getDefaultInstance()) .build(); + public static final Dish DISH3 = Dish.newBuilder() + .setId(DishId.newBuilder() + .setMenuId(MENU_ID2) + .setSequentialNumber(1) + .build()) + .setName("Картофель") + .setCategory("Второе блюдо") + .setPrice(Money.newBuilder() + .setAmount(56) + .build()) + .build(); + public static final Dish DISH4 = Dish.newBuilder() + .setId(DishId.newBuilder() + .setMenuId(MENU_ID2) + .setSequentialNumber(1) + .build()) + .setName("Борщ украинский") + .setCategory("Первое блюдо") + .setPrice(Money.newBuilder() + .setAmount(33) + .build()) + .build(); + public static final Dish DISH5 = Dish.newBuilder() + .setId(DishId.newBuilder() + .setMenuId(MENU_ID2) + .setSequentialNumber(1) + .build()) + .setName("Стейк из лосося") + .setCategory("Второе блюдо") + .setPrice(Money.newBuilder() + .setAmount(80) + .build()) + .build(); + public static final Dish DISH6 = Dish.newBuilder() + .setId(DishId.newBuilder() + .setMenuId(MENU_ID2) + .setSequentialNumber(1) + .build()) + .setName("Компот из сухофруктов") + .setCategory("Напитки") + .setPrice(Money.newBuilder() + .setAmount(10) + .build()) + .build(); + public static final Dish DISH7 = Dish.newBuilder() + .setId(DishId.newBuilder() + .setMenuId(MENU_ID2) + .setSequentialNumber(1) + .build()) + .setName("Скумбрия на гриле") + .setCategory("Второе блюдо") + .setPrice(Money.newBuilder() + .setAmount(10) + .build()) + .build(); + public static final Dish DISH8 = Dish.newBuilder() + .setId(DishId.newBuilder() + .setMenuId(MENU_ID2) + .setSequentialNumber(1) + .build()) + .setName("Суп гороховый") + .setCategory("Первое блюдо") + .setPrice(Money.newBuilder() + .setAmount(10) + .build()) + .build(); + public static final LocalDate DATE = LocalDate.newBuilder() .setYear( 2019) @@ -275,6 +347,19 @@ public class TestValues { .setStatus(ORDER_ACTIVE) .build(); public static final List BIG_ORDER = createOrder(); + public static final List BIG_MENU = createMenu(); + + private static List createMenu() { + final List menu = new ArrayList<>(); + menu.add(DISH3); + menu.add(DISH4); + menu.add(DISH5); + menu.add(DISH6); + menu.add(DISH7); + menu.add(DISH8); + + return menu; + } private static List createOrder() { List orders = new ArrayList<>(); From a42f2171ce96a159671e6a8fb79e26b6c0788004 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 23 Apr 2018 16:42:29 +0300 Subject: [PATCH 31/66] Add subscriber handlers --- .../MonthlySpendingsReportViewProjection.java | 95 +++++++++++++++---- .../javaclasses/mealorder/q/projections.proto | 4 +- 2 files changed, 77 insertions(+), 22 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java index c14b32f6..8b4cde95 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java @@ -20,20 +20,24 @@ package javaclasses.mealorder.q; -import com.google.protobuf.Timestamp; import io.spine.core.Subscribe; -import io.spine.net.EmailAddress; +import io.spine.money.Money; import io.spine.server.projection.Projection; +import io.spine.time.LocalDate; +import javaclasses.mealorder.Dish; +import javaclasses.mealorder.LocalMonth; import javaclasses.mealorder.MenuListId; import javaclasses.mealorder.MonthlySpendingsReportId; +import javaclasses.mealorder.Order; import javaclasses.mealorder.PurchaseOrder; -import javaclasses.mealorder.PurchaseOrderId; import javaclasses.mealorder.UserId; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; import javaclasses.mealorder.q.projection.MonthlySpendingsReportView; import javaclasses.mealorder.q.projection.MonthlySpendingsReportViewVBuilder; +import java.util.ArrayList; +import java.util.List; public class MonthlySpendingsReportViewProjection extends Projection { @@ -48,29 +52,80 @@ public MonthlySpendingsReportViewProjection(MenuListId id) { } @Subscribe - void on(PurchaseOrderDelivered event) { - final PurchaseOrderId taskId = event.getId(); - final UserId userId = event.getWhoMarkedAsDelivered(); - final Timestamp whenDelivered = event.getWhenDelivered(); + void on(PurchaseOrderSent event) { + final PurchaseOrder purchaseOrder = event.getPurchaseOrder(); + final List userOrderDetailsList = new ArrayList<>(); + final List dishItemList = new ArrayList<>(); + final List orders = purchaseOrder.getOrderList(); - final UserSpendings userSpendings = UserSpendings.newBuilder().build(); - final UserOrderDetails userOrderDetails = UserOrderDetails.newBuilder().build(); + for (int i = 0; i < orders.size(); i++) { + final UserId userId = orders.get(i) + .getId() + .getUserId(); + final List dishList = orders.get(i) + .getDishList(); + for (int j = 0; j < dishList.size(); j++) { + final DishItem dishItem = DishItem.newBuilder() + .setId(dishList.get(i) + .getId()) + .setName(dishList.get(i) + .getName()) + .setPrice(dishItemList.get(i) + .getPrice()) + .build(); + dishItemList.add(dishItem); + } + final UserOrderDetails userOrderDetails = UserOrderDetails.newBuilder() + .setId(userId) + .addAllDish(dishItemList) + .build(); + userOrderDetailsList.add(userOrderDetails); + } - getBuilder().addUserSpending(userSpendings); - getBuilder().addOrder(userOrderDetails); + final LocalDate localDate = purchaseOrder.getId() + .getPoDate(); + final LocalMonth localMonth = LocalMonth.newBuilder() + .setMonth(localDate.getMonth()) + .setYear(localDate.getYear()) + .build(); + + getBuilder().setReportId(MonthlySpendingsReportId.newBuilder() + .setMonth(localMonth) + .build()); + getBuilder().addAllOrder(userOrderDetailsList); } @Subscribe - void on(PurchaseOrderSent event) { - final PurchaseOrder purchaseOrder = event.getPurchaseOrder(); - final Timestamp whenSent = event.getWhenSent(); - final EmailAddress senderEmail = event.getSenderEmail(); - final EmailAddress vendorEmail = event.getVendorEmail(); + void on(PurchaseOrderDelivered event) { + final List userSpendingsList = new ArrayList<>(); + + for (int i = 0; i < getBuilder().getOrder() + .size(); i++) { + + long money = 0; + for (int j = 0; j < getBuilder().getOrder() + .get(i) + .getDishList() + .size(); j++) { + money += getBuilder().getOrder() + .get(j) + .getDish(j) + .getPrice() + .getAmount(); + } - final UserSpendings userSpendings = UserSpendings.newBuilder().build(); - final UserOrderDetails userOrderDetails = UserOrderDetails.newBuilder().build(); + final Money usersMoney = Money.newBuilder() + .setAmount(money) + .build(); - getBuilder().addUserSpending(userSpendings); - getBuilder().addOrder(userOrderDetails); + final UserSpendings userSpendings = UserSpendings.newBuilder() + .setId(getBuilder().getOrder() + .get(i) + .getId()) + .setAmount(usersMoney) + .build(); + userSpendingsList.add(userSpendings); + } + getBuilder().addAllUserSpending(userSpendingsList); } } diff --git a/model/src/main/proto/javaclasses/mealorder/q/projections.proto b/model/src/main/proto/javaclasses/mealorder/q/projections.proto index 667cd1d5..effbb58a 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/projections.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/projections.proto @@ -209,8 +209,8 @@ message PurchaseOrderDetailsByUserView { // date till today if a report is formed for the current month. // // Subscribes following events: -// 1. `PurchaseOrderDelivered` -// 2. `PurchaseOrderSent` +// 1. `PurchaseOrderSent` +// 2. `PurchaseOrderDelivered` // message MonthlySpendingsReportView { From 253c51a55ed481098364e7241ade225e954a5c5d Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Mon, 23 Apr 2018 16:57:30 +0300 Subject: [PATCH 32/66] Add tests for `PurchaseOrderDetailsByDishViewProjection` projection --- ...eOrderDetailsByDishViewProjectionTest.java | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByDishViewProjectionTest.java diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByDishViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByDishViewProjectionTest.java new file mode 100644 index 00000000..c98e296c --- /dev/null +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByDishViewProjectionTest.java @@ -0,0 +1,118 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.projection; + +import io.spine.time.LocalDate; +import javaclasses.mealorder.PurchaseOrderId; +import javaclasses.mealorder.PurchaseOrderStatus; +import javaclasses.mealorder.VendorId; +import javaclasses.mealorder.c.event.PurchaseOrderCreated; +import javaclasses.mealorder.c.event.PurchaseOrderDelivered; +import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.q.DishItem; +import javaclasses.mealorder.q.PurchaseOrderDetailsByDishViewProjection; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderCreatedInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderDeliveredInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderSentInstance; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class PurchaseOrderDetailsByDishViewProjectionTest extends ProjectionTest { + private PurchaseOrderDetailsByDishViewProjection projection; + + @BeforeEach + void setUp() { + projection = new PurchaseOrderDetailsByDishViewProjection(PurchaseOrderId.newBuilder() + .setPoDate( + LocalDate.newBuilder() + .setDay(14) + .build()) + .setVendorId( + VendorId.newBuilder() + .setValue( + "Пюре") + .build()) + .build()); + } + + @Nested + @DisplayName("PurchaseOrderCreated event should be interpreted by PurchaseOrderDetailsByDishViewProjection") + class PurchaseOrderCreatedEvent { + + @Test + @DisplayName("Should set order for a projection") + void addView() { + final PurchaseOrderCreated purchaseOrderCreated = purchaseOrderCreatedInstance(); + dispatch(projection, createEvent(purchaseOrderCreated)); + final List dishes = projection.getState() + .getDishList(); + assertEquals(13, dishes.size()); + assertEquals("vendor:value: \"VendorName1\"\n", projection.getState() + .getId() + .getVendorId() + .getValue()); + } + } + + @Nested + @DisplayName("PurchaseOrderSent event should be interpreted by PurchaseOrderDetailsByDishViewProjection") + class PurchaseOrderSentEvent { + + @Test + @DisplayName("Should set status for a projection") + void addView() { + final PurchaseOrderCreated purchaseOrderCreated = purchaseOrderCreatedInstance(); + dispatch(projection, createEvent(purchaseOrderCreated)); + final PurchaseOrderSent purchaseOrderSent = purchaseOrderSentInstance(); + dispatch(projection, createEvent(purchaseOrderSent)); + assertEquals(PurchaseOrderStatus.SENT, projection.getState() + .getPurchaseOrderStatus()); + } + } + + @Nested + @DisplayName("PurchaseOrderDelivered event should be interpreted by PurchaseOrderDetailsByDishViewProjection") + class PurchaseOrderDeliveredEvent { + + @Test + @DisplayName("Should change existing status for a projection") + void addView() { + final PurchaseOrderCreated purchaseOrderCreated = purchaseOrderCreatedInstance(); + dispatch(projection, createEvent(purchaseOrderCreated)); + final PurchaseOrderSent purchaseOrderSent = purchaseOrderSentInstance(); + dispatch(projection, createEvent(purchaseOrderSent)); + assertEquals(PurchaseOrderStatus.SENT, projection.getState() + .getPurchaseOrderStatus()); + + final PurchaseOrderDelivered purchaseOrderDelivered = purchaseOrderDeliveredInstance(); + dispatch(projection, createEvent(purchaseOrderDelivered)); + assertEquals(PurchaseOrderStatus.DELIVERED, projection.getState() + .getPurchaseOrderStatus()); + } + } +} From 2a76551d5e320017352a3430996a34fa91b7a452 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Mon, 23 Apr 2018 19:47:01 +0300 Subject: [PATCH 33/66] Refactor proto model --- .../mealorder/c/order/OrderAggregate.java | 3 + .../mealorder/c/po/PurchaseOrders.java | 1 + .../mealorder/c/vendor/VendorAggregate.java | 1 + .../mealorder/q/OrderListViewProjection.java | 12 +- .../OrderListViewProjectionTest.java | 53 ++++++++ .../VendorListViewProjectionTest.java | 62 ++++++++++ .../javaclasses/mealorder/attributes.proto | 4 +- .../javaclasses/mealorder/c/commands.proto | 70 +++++------ .../javaclasses/mealorder/c/events.proto | 114 +++++++++--------- .../javaclasses/mealorder/c/rejections.proto | 94 +++++++-------- .../javaclasses/mealorder/identifiers.proto | 36 +++--- .../proto/javaclasses/mealorder/model.proto | 24 ++-- .../javaclasses/mealorder/q/projections.proto | 68 ++--------- .../javaclasses/mealorder/q/values.proto | 32 ++--- .../proto/javaclasses/mealorder/values.proto | 32 ++--- .../testdata/TestOrderCommandFactory.java | 2 + .../TestPurchaseOrderCommandFactory.java | 6 + 17 files changed, 352 insertions(+), 262 deletions(-) create mode 100644 api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java create mode 100644 api-java/src/test/java/javaclasses/mealorder/q/projection/VendorListViewProjectionTest.java diff --git a/api-java/src/main/java/javaclasses/mealorder/c/order/OrderAggregate.java b/api-java/src/main/java/javaclasses/mealorder/c/order/OrderAggregate.java index 5e801181..1a3b44a9 100644 --- a/api-java/src/main/java/javaclasses/mealorder/c/order/OrderAggregate.java +++ b/api-java/src/main/java/javaclasses/mealorder/c/order/OrderAggregate.java @@ -99,6 +99,7 @@ OrderCreated handle(CreateOrder cmd) throws OrderAlreadyExists, MenuNotAvailable final OrderCreated result = OrderCreated.newBuilder() .setOrderId(orderId) .setMenuId(menuId) + .setWhenCreated(getCurrentTime()) .build(); return result; } @@ -125,6 +126,7 @@ DishAddedToOrder handle(AddDishToOrder cmd) throws DishVendorMismatch, final DishAddedToOrder result = DishAddedToOrder.newBuilder() .setOrderId(orderId) .setDish(dish) + .setWhenAdded(getCurrentTime()) .build(); return result; } @@ -145,6 +147,7 @@ DishRemovedFromOrder handle(RemoveDishFromOrder cmd) throws CannotRemoveMissingD DishRemovedFromOrder result = DishRemovedFromOrder.newBuilder() .setOrderId(orderId) .setDish(dish) + .setWhenRemoved(getCurrentTime()) .build(); return result; } diff --git a/api-java/src/main/java/javaclasses/mealorder/c/po/PurchaseOrders.java b/api-java/src/main/java/javaclasses/mealorder/c/po/PurchaseOrders.java index 63db91c6..d6bd1216 100644 --- a/api-java/src/main/java/javaclasses/mealorder/c/po/PurchaseOrders.java +++ b/api-java/src/main/java/javaclasses/mealorder/c/po/PurchaseOrders.java @@ -277,6 +277,7 @@ static PurchaseOrderSent createPOSentEvent(PurchaseOrder purchaseOrder, .setPurchaseOrder(purchaseOrder) .setSenderEmail(senderEmail) .setVendorEmail(vendorEmail) + .setWhenSent(getCurrentTime()) .build(); return result; } diff --git a/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorAggregate.java b/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorAggregate.java index 352c65fb..e0a97a9c 100644 --- a/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorAggregate.java +++ b/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorAggregate.java @@ -79,6 +79,7 @@ VendorAdded handle(AddVendor cmd) throws VendorAlreadyExists { .setEmail(cmd.getEmail()) .addAllPhoneNumber(cmd.getPhoneNumberList()) .setPoDailyDeadline(cmd.getPoDailyDeadline()) + .setWhenAdded(getCurrentTime()) .build(); return vendorAdded; } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java index a875f56e..8a69f805 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java @@ -94,12 +94,20 @@ void on(DishRemovedFromOrder event) { @Subscribe void on(OrderCanceled event) { - getBuilder().clearOrder(); + final OrderItem order = getOrderById(event.getOrderId()); + getBuilder().removeOrder(getBuilder().getOrder() + .indexOf(order)); } @Subscribe + void on(OrderProcessed event) { - getBuilder().setProcessed(true); + final OrderItem order = getOrderById(event.getOrder() + .getId()); + getBuilder().setOrder(getBuilder().getOrder() + .indexOf(order), OrderItem.newBuilder(order) + .setIsProcessed(true) + .build()); } private OrderItem getOrderById(OrderId orderId) { diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java new file mode 100644 index 00000000..4dcc357e --- /dev/null +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java @@ -0,0 +1,53 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.projection; + +import javaclasses.mealorder.OrderListId; +import javaclasses.mealorder.q.OrderListViewProjection; +import javaclasses.mealorder.testdata.TestValues; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +public class OrderListViewProjectionTest extends ProjectionTest { + private OrderListViewProjection projection; + + @BeforeEach + void setUp() { + projection = new OrderListViewProjection(OrderListId.newBuilder() + .setUserId(TestValues.USER_ID) + .build()); + } + + @Nested + @DisplayName("DishAddedToOrder event should be interpreted by OrderListViewProjection") + class DishAddedToOrderEvent { + + @Test + @DisplayName("Should add dish to the order") + void addView() { +// final DishAddedToOrder dishAddedToOrder = dshAddedToOrderInstance(); +// dispatch(projection, createEvent(dishAddedToOrder)); + + } + } +} diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/VendorListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/VendorListViewProjectionTest.java new file mode 100644 index 00000000..349f4c83 --- /dev/null +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/VendorListViewProjectionTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.projection; + +import javaclasses.mealorder.q.VendorListViewProjection; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +public class VendorListViewProjectionTest extends ProjectionTest { + private VendorListViewProjection projection; + + @BeforeEach + void setUp() { + projection = new VendorListViewProjection(VendorListViewProjection.ID); + } + + @Nested + @DisplayName("VendorAdded event should be interpreted by VendorListViewProjection") + class VendorAddedEvent { + + @Test + @DisplayName("Should add new vendor") + void addView() { +// final VendorAdded vendorAdded = vendorAddedInstance(); +// dispatch(projection, createEvent(vendorAdded)); + + } + } + + @Nested + @DisplayName("VendorUpdated event should be interpreted by VendorListViewProjection") + class VendorUpdatedEvent { + + @Test + @DisplayName("Should update vendor") + void addView() { +// final VendorUpdated vendorUpdated = VendorUpdatedInstance(); +// dispatch(projection, createEvent(vendorUpdated)); + + } + } +} diff --git a/model/src/main/proto/javaclasses/mealorder/attributes.proto b/model/src/main/proto/javaclasses/mealorder/attributes.proto index 86fd7e87..37c6681b 100644 --- a/model/src/main/proto/javaclasses/mealorder/attributes.proto +++ b/model/src/main/proto/javaclasses/mealorder/attributes.proto @@ -37,8 +37,8 @@ import "spine/time/time.proto"; message LocalMonth { // The month value. - spine.time.MonthOfYear month = 1; + spine.time.MonthOfYear month = 1 [(required) = true]; // The year value. - int32 year = 2; + int32 year = 2 [(required) = true]; } diff --git a/model/src/main/proto/javaclasses/mealorder/c/commands.proto b/model/src/main/proto/javaclasses/mealorder/c/commands.proto index 07dc001a..3c4e4a10 100644 --- a/model/src/main/proto/javaclasses/mealorder/c/commands.proto +++ b/model/src/main/proto/javaclasses/mealorder/c/commands.proto @@ -44,23 +44,23 @@ import "javaclasses/mealorder/model.proto"; message AddVendor { // The identifier of a vendor which should be added. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // The identifier of the user who adds a vendor. - UserId user_id = 2; + UserId user_id = 2 [(required) = true]; // The name of a vendor. - VendorName vendor_name = 3; + VendorName vendor_name = 3 [(required) = true]; // The email adress of a vendor to send a purchase order. - spine.net.EmailAddress email = 4; + spine.net.EmailAddress email = 4 [(required) = true]; // Phone numbers of a vendor. - repeated PhoneNumber phone_number = 5; + repeated PhoneNumber phone_number = 5 [(required) = true]; // Time when orders for this vendor are closed for editing. // Purchase orders for a vendor will be created exactly at this time. - spine.time.LocalTime po_daily_deadline = 6; + spine.time.LocalTime po_daily_deadline = 6 [(required) = true]; } // Updates a vendor profile. @@ -68,13 +68,13 @@ message AddVendor { message UpdateVendor { // The identifier of a vendor. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // The identifier of the user who updates vendor profile. - UserId user_id = 2; + UserId user_id = 2 [(required) = true]; // Changes in a vendor profile. - VendorChange vendor_change = 3; + VendorChange vendor_change = 3 [(required) = true]; } // Imports a menu. @@ -82,16 +82,16 @@ message UpdateVendor { message ImportMenu { // The identifier of a vendor. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // The identifier of a imported menu - MenuId menuId = 2; + MenuId menuId = 2 [(required) = true]; // The identifier of the user who imports a menu. - UserId user_id = 3; + UserId user_id = 3 [(required) = true]; // The collection of dishes. - repeated Dish dish = 4; + repeated Dish dish = 4 [(required) = true]; } // Sets a menu date range. @@ -99,16 +99,16 @@ message ImportMenu { message SetDateRangeForMenu { // The identifier of a vendor. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // The identifier of a menu. - MenuId menu_id = 2; + MenuId menu_id = 2 [(required) = true]; // The identifier of the user who sets a menu date range. - UserId user_id = 3; + UserId user_id = 3 [(required) = true]; // A menu date range that should be set. - MenuDateRange menu_date_range = 4; + MenuDateRange menu_date_range = 4 [(required) = true]; } // Creates a new order. @@ -118,10 +118,10 @@ message SetDateRangeForMenu { message CreateOrder { // The identifier of an order. - OrderId order_id = 1; + OrderId order_id = 1 [(required) = true]; // The identifier of the menu. Dishes from only this menu can be added to an order. - MenuId menu_id = 2; + MenuId menu_id = 2 [(required) = true]; } // Adds a dish to an order. @@ -132,10 +132,10 @@ message CreateOrder { message AddDishToOrder { // The identifier of an order. - OrderId order_id = 1; + OrderId order_id = 1 [(required) = true]; // A dish that should be added to an order. - Dish dish = 2; + Dish dish = 2 [(required) = true]; } // Removes a dish from an order. @@ -146,10 +146,10 @@ message AddDishToOrder { message RemoveDishFromOrder { // The identifier of an order. - OrderId order_id = 1; + OrderId order_id = 1 [(required) = true]; // The identifier of a dish that should be removed from an order. - DishId dish_id = 2; + DishId dish_id = 2 [(required) = true]; } // Cancels an order. @@ -162,10 +162,10 @@ message RemoveDishFromOrder { message CancelOrder { // The identifier of an order. - OrderId order_id = 1; + OrderId order_id = 1 [(required) = true]; // The identifier of the user who cancels an order. - UserId who_cancels = 2; + UserId who_cancels = 2 [(required) = true]; } // Creates a purchase order. @@ -173,16 +173,16 @@ message CancelOrder { message CreatePurchaseOrder { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The collection of all orders for this day for the specified vendor. repeated Order order = 2; // The identifier of the user who creates a purchase order. - UserId who_creates = 3; + UserId who_creates = 3 [(required) = true]; // The email adress of a vendor to send a purchase order. - spine.net.EmailAddress vendor_email = 4; + spine.net.EmailAddress vendor_email = 4 [(required) = true]; } // Marks a purchase order as delivered. @@ -192,10 +192,10 @@ message CreatePurchaseOrder { message MarkPurchaseOrderAsDelivered { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The identifier of the user who marks a purchase order as delivered. - UserId who_marks_as_delivered = 2; + UserId who_marks_as_delivered = 2 [(required) = true]; } // Overrules a purchase order validation. @@ -205,13 +205,13 @@ message MarkPurchaseOrderAsDelivered { message MarkPurchaseOrderAsValid { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The identifier of the user who marks a purchase order as valid. - UserId user_id = 2; + UserId user_id = 2 [(required) = true]; // The reason why a purchase order should be marked as valid. - string reason = 3; + string reason = 3 [(required) = true]; // The email adress of a vendor to send a purchase order. spine.net.EmailAddress vendor_email = 4; @@ -224,7 +224,7 @@ message MarkPurchaseOrderAsValid { message CancelPurchaseOrder { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The reason of cancelation. oneof reason { @@ -237,5 +237,5 @@ message CancelPurchaseOrder { } // The identifier of the user who cancels a purchase order. - UserId user_id = 4; + UserId user_id = 4 [(required) = true]; } diff --git a/model/src/main/proto/javaclasses/mealorder/c/events.proto b/model/src/main/proto/javaclasses/mealorder/c/events.proto index 9213f541..ed86ae5a 100644 --- a/model/src/main/proto/javaclasses/mealorder/c/events.proto +++ b/model/src/main/proto/javaclasses/mealorder/c/events.proto @@ -42,25 +42,25 @@ import "javaclasses/mealorder/values.proto"; message VendorAdded { // The identifier of a added vendor. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // The identifier of the user who added a vendor. - UserId who_added = 2; + UserId who_added = 2 [(required) = true]; // Was added at this time. - google.protobuf.Timestamp when_added = 3; + google.protobuf.Timestamp when_added = 3 [(required) = true]; // The name of a vendor. - VendorName vendor_name = 4; + VendorName vendor_name = 4 [(required) = true]; // The email adress to send a purchase order. - spine.net.EmailAddress email = 5; + spine.net.EmailAddress email = 5 [(required) = true]; // Phone numbers of a vendor. - repeated PhoneNumber phone_number = 6; + repeated PhoneNumber phone_number = 6 [(required) = true]; // Time to which all orders to this vendor must be made. - spine.time.LocalTime po_daily_deadline = 7; + spine.time.LocalTime po_daily_deadline = 7 [(required) = true]; } // The event fired upon a vendor profile update. @@ -68,16 +68,16 @@ message VendorAdded { message VendorUpdated { // The identifier of an updated vendor. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // The identifier of the user who updated a vendor profile. - UserId who_uploaded = 2; + UserId who_uploaded = 2 [(required) = true]; // Was updated at this time. - google.protobuf.Timestamp when_updated = 3; + google.protobuf.Timestamp when_updated = 3 [(required) = true]; // Changes in a vendor profile. - VendorChange vendor_change = 4; + VendorChange vendor_change = 4 [(required) = true]; } // The event signalizing about the successful import of a menu. @@ -88,19 +88,19 @@ message VendorUpdated { message MenuImported { // The identifier of the vendor that provided a menu. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // The identifier of an imported menu. - MenuId menu_id = 2; + MenuId menu_id = 2 [(required) = true]; // The identifier of the user who imported a menu. - UserId who_imported = 3; + UserId who_imported = 3 [(required) = true]; // Was imported at this time. - google.protobuf.Timestamp when_imported = 4; + google.protobuf.Timestamp when_imported = 4 [(required) = true]; // The collection of menu dishes. - repeated Dish dish = 5; + repeated Dish dish = 5 [(required) = true]; } // The event reflecting a menu active date range set. @@ -108,19 +108,19 @@ message MenuImported { message DateRangeForMenuSet { // The identifier of a vendor. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // The identifier of a menu. - MenuId menu_id = 2; + MenuId menu_id = 2 [(required) = true]; // The identifier of the user who set date range. - UserId who_set = 3; + UserId who_set = 3 [(required) = true]; // Was set at this time. - google.protobuf.Timestamp when_set = 4; + google.protobuf.Timestamp when_set = 4 [(required) = true]; // Date range that has been set. - MenuDateRange menu_date_range = 5; + MenuDateRange menu_date_range = 5 [(required) = true]; } // The event signalizing about the successful creation of an order. @@ -130,13 +130,13 @@ message DateRangeForMenuSet { message OrderCreated { // The identifier of an order. - OrderId order_id = 1; + OrderId order_id = 1 [(required) = true]; // The identifier of the menu which contains dishes that can be added to an order. - MenuId menu_id = 2; + MenuId menu_id = 2 [(required) = true]; // Was created at this time. - google.protobuf.Timestamp when_created = 3; + google.protobuf.Timestamp when_created = 3 [(required) = true]; } // The event signalizing about a dish addition to the order. @@ -144,13 +144,13 @@ message OrderCreated { message DishAddedToOrder { // The identifier of the order. - OrderId order_id = 1; + OrderId order_id = 1 [(required) = true]; // A dish that added to an order. - Dish dish = 2; + Dish dish = 2 [(required) = true]; // Was added at this time. - google.protobuf.Timestamp when_added = 3; + google.protobuf.Timestamp when_added = 3 [(required) = true]; } // The event signalizing about the successful removing of a dish from the order. @@ -158,13 +158,13 @@ message DishAddedToOrder { message DishRemovedFromOrder { // The identifier of the order. - OrderId order_id = 1; + OrderId order_id = 1 [(required) = true]; // A dish removed from an order. - Dish dish = 2; + Dish dish = 2 [(required) = true]; // Was removed at this time. - google.protobuf.Timestamp when_removed = 3; + google.protobuf.Timestamp when_removed = 3 [(required) = true]; } // The event signalizing about the successful order cancellation. @@ -172,13 +172,13 @@ message DishRemovedFromOrder { message OrderCanceled { // The identifier of an order. - OrderId order_id = 1; + OrderId order_id = 1 [(required) = true]; // The identifier of the user who canceled an order. - UserId who_canceled = 2; + UserId who_canceled = 2 [(required) = true]; // Was canceled at this time. - google.protobuf.Timestamp when_canceled = 3; + google.protobuf.Timestamp when_canceled = 3 [(required) = true]; } // The event signalizing about the successful addition of an order to the purchase order. @@ -186,10 +186,10 @@ message OrderCanceled { message OrderProcessed { // An order that was added to the purchase order. - Order order = 1; + Order order = 1 [(required) = true]; // Was added to the purchase order at this time. - google.protobuf.Timestamp when_processed = 2; + google.protobuf.Timestamp when_processed = 2 [(required) = true]; } // The event signalizing about the successful creation of a purchase order. @@ -197,16 +197,16 @@ message OrderProcessed { message PurchaseOrderCreated { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // Was created at this time. - google.protobuf.Timestamp when_created = 2; + google.protobuf.Timestamp when_created = 2 [(required) = true]; // The identifier of the user who created a purchase order. - UserId who_created = 3; + UserId who_created = 3 [(required) = true]; // The collection of all orders for this day. - repeated Order order = 4; + repeated Order order = 4 [(required) = true]; } // The event signalizing about the successful delivering of a purchase order. @@ -214,13 +214,13 @@ message PurchaseOrderCreated { message PurchaseOrderDelivered { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The identifier of the user who marked a purchase order as delivered. - UserId who_marked_as_delivered = 2; + UserId who_marked_as_delivered = 2 [(required) = true]; // Was delivered at this time. - google.protobuf.Timestamp when_delievered = 3; + google.protobuf.Timestamp when_delievered = 3 [(required) = true]; } // The event signalizing about the successful sending of a purchase order. @@ -228,16 +228,16 @@ message PurchaseOrderDelivered { message PurchaseOrderSent { // Purchase order. - PurchaseOrder purchase_order = 1; + PurchaseOrder purchase_order = 1 [(required) = true]; // Was sent at this time. - google.protobuf.Timestamp when_sent = 2; + google.protobuf.Timestamp when_sent = 2 [(required) = true]; // The email address of the sender. - spine.net.EmailAddress sender_email = 3; + spine.net.EmailAddress sender_email = 3 [(required) = true]; // The email address of the recipient. - spine.net.EmailAddress vendor_email = 4; + spine.net.EmailAddress vendor_email = 4 [(required) = true]; } // The event signalizing about failed purchase order validation. @@ -251,13 +251,13 @@ message PurchaseOrderSent { message PurchaseOrderValidationFailed { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The collection of orders that caused a failure of validation. - repeated Order failure_order = 2; + repeated Order failure_order = 2 [(required) = true]; // Validation failed at this time. - google.protobuf.Timestamp when_failed = 3; + google.protobuf.Timestamp when_failed = 3 [(required) = true]; } // The event signalizing that purchase order validation is overruled successfully. @@ -265,13 +265,13 @@ message PurchaseOrderValidationFailed { message PurchaseOrderValidationOverruled { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The identifier of the user who overruled validation. - UserId who_overruled = 2; + UserId who_overruled = 2 [(required) = true]; // The reason why validation is overruled. - string reason = 3; + string reason = 3 [(required) = true]; // Validation was overruled at this time. google.protobuf.Timestamp when_overruled = 4; @@ -282,10 +282,10 @@ message PurchaseOrderValidationOverruled { message PurchaseOrderValidationPassed { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // Validation completed successfully at this time. - google.protobuf.Timestamp when_passed = 2; + google.protobuf.Timestamp when_passed = 2 [(required) = true]; } // The event signalizing about the successful order cancellation. @@ -293,13 +293,13 @@ message PurchaseOrderValidationPassed { message PurchaseOrderCanceled { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The identifier of the user who cancelled a purchase order. - UserId user_id = 2; + UserId user_id = 2 [(required) = true]; // Was canceled at this time. - google.protobuf.Timestamp when_canceled = 3; + google.protobuf.Timestamp when_canceled = 3 [(required) = true]; // The reason of cancellation. // diff --git a/model/src/main/proto/javaclasses/mealorder/c/rejections.proto b/model/src/main/proto/javaclasses/mealorder/c/rejections.proto index 91841117..574a9355 100644 --- a/model/src/main/proto/javaclasses/mealorder/c/rejections.proto +++ b/model/src/main/proto/javaclasses/mealorder/c/rejections.proto @@ -43,13 +43,13 @@ import "javaclasses/mealorder/values.proto"; message VendorAlreadyExists { // The identifier of the existing vendor. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // The name of the existing vendor. - VendorName vendor_name = 2; + VendorName vendor_name = 2 [(required) = true]; // Addition was rejected at this time. - google.protobuf.Timestamp when_rejected = 3; + google.protobuf.Timestamp when_rejected = 3 [(required) = true]; } // The rejection to set date range for a menu. @@ -59,16 +59,16 @@ message VendorAlreadyExists { message CannotSetDateRange { // The identifier of the vendor of this menu. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // The identifier of the menu which date range wasn't set. - MenuId menu_id = 2; + MenuId menu_id = 2 [(required) = true]; // Date range that was been attempted to set. - MenuDateRange menu_date_range = 3; + MenuDateRange menu_date_range = 3 [(required) = true]; // Setting was rejected at this time. - google.protobuf.Timestamp when_rejected = 4; + google.protobuf.Timestamp when_rejected = 4 [(required) = true]; } // The rejection to create an order. @@ -78,10 +78,10 @@ message CannotSetDateRange { message OrderAlreadyExists { // The identifier of the existing order. - OrderId order_id = 1; + OrderId order_id = 1 [(required) = true]; // Creation was rejected at this time. - google.protobuf.Timestamp when_rejected = 2; + google.protobuf.Timestamp when_rejected = 2 [(required) = true]; } // The rejection to create an order. @@ -91,16 +91,16 @@ message OrderAlreadyExists { message MenuNotAvailable { // The identifier of the user who tried to create an order. - UserId user_id = 1; + UserId user_id = 1 [(required) = true]; // The identifier of the vendor from who the user tried to order. - VendorId vendor_id = 2; + VendorId vendor_id = 2 [(required) = true]; // The date on which the user attempted to create an order. - spine.time.LocalDate order_date = 3; + spine.time.LocalDate order_date = 3 [(required) = true]; // Creation was rejected at this time. - google.protobuf.Timestamp when_rejected = 4; + google.protobuf.Timestamp when_rejected = 4 [(required) = true]; } @@ -111,19 +111,19 @@ message MenuNotAvailable { message DishVendorMismatch { // The identifier of the order in which the user tried to add a dish. - OrderId order_id = 1; + OrderId order_id = 1 [(required) = true]; // The identifier of a dish which the user tried to add to the order. - DishId dish_id = 2; + DishId dish_id = 2 [(required) = true]; // The identifier of the user who tried to add a dish. - UserId user_id = 3; + UserId user_id = 3 [(required) = true]; // The mismatching vendor value. - VendorMismatch vendor_mismatch = 4; + VendorMismatch vendor_mismatch = 4 [(required) = true]; // Addition was rejected at this time. - google.protobuf.Timestamp when_rejected = 5; + google.protobuf.Timestamp when_rejected = 5 [(required) = true]; } // The rejection to add a dish to the order. @@ -133,19 +133,19 @@ message DishVendorMismatch { message CannotAddDishToNotActiveOrder { // The identifier of the order in which the user tried to add a dish. - OrderId order_id = 1; + OrderId order_id = 1 [(required) = true]; // The identifier of a dish which the user tried to add to the order. - DishId dish_id = 2; + DishId dish_id = 2 [(required) = true]; // The identifier of the user who tried to add a dish. - UserId user_id = 3; + UserId user_id = 3 [(required) = true]; // The status of the order. - OrderStatus order_status = 4; + OrderStatus order_status = 4 [(required) = true]; // Addition was rejected at this time. - google.protobuf.Timestamp when_rejected = 5; + google.protobuf.Timestamp when_rejected = 5 [(required) = true]; } // The rejection to remove a dish from the order. @@ -155,19 +155,19 @@ message CannotAddDishToNotActiveOrder { message CannotRemoveDishFromNotActiveOrder { // The identifier of the order in which the user tried to add a dish. - OrderId order_id = 1; + OrderId order_id = 1 [(required) = true]; // The identifier of a dish which the user tried to add to the order. - DishId dish_id = 2; + DishId dish_id = 2 [(required) = true]; // The identifier of the user who tried to add a dish. - UserId user_id = 3; + UserId user_id = 3 [(required) = true]; // The status of the order. - OrderStatus order_status = 4; + OrderStatus order_status = 4 [(required) = true]; // Addition was rejected at this time. - google.protobuf.Timestamp when_rejected = 5; + google.protobuf.Timestamp when_rejected = 5 [(required) = true]; } // The rejection to remove a dish from the order. @@ -177,16 +177,16 @@ message CannotRemoveDishFromNotActiveOrder { message CannotRemoveMissingDish { // The identifier of the order from which the user tried to remove a dish. - OrderId order_id = 1; + OrderId order_id = 1 [(required) = true]; // The identifier of the user who tried to remove a dish. - UserId user_id = 2; + UserId user_id = 2 [(required) = true]; // The identifier of a dish which the user tried to remove from the order. - DishId dish_id = 3; + DishId dish_id = 3 [(required) = true]; // Removing was rejected at this time. - google.protobuf.Timestamp when_rejected = 4; + google.protobuf.Timestamp when_rejected = 4 [(required) = true]; } // The rejection to cancel an order. @@ -196,13 +196,13 @@ message CannotRemoveMissingDish { message CannotCancelProcessedOrder { // The identifier of an order which the user tried to cancel. - OrderId order_id = 1; + OrderId order_id = 1 [(required) = true]; // The identifier of the user who tried to cancel an order. - UserId user_id = 2; + UserId user_id = 2 [(required) = true]; // Cancellation was rejected at this time. - google.protobuf.Timestamp when_rejected = 3; + google.protobuf.Timestamp when_rejected = 3 [(required) = true]; } // The rejection to create a purchase order. @@ -212,13 +212,13 @@ message CannotCancelProcessedOrder { message CannotCreatePurchaseOrder { // The identifier of the vendor for which a purchase order wasn't created. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // The date on which a purchase order creation was rejected. - spine.time.LocalDate purchase_order_date = 2; + spine.time.LocalDate purchase_order_date = 2 [(required) = true]; // Creation was rejected at this time. - google.protobuf.Timestamp when_rejected = 3; + google.protobuf.Timestamp when_rejected = 3 [(required) = true]; } // The rejection to mark a purchase order as delivered. @@ -228,13 +228,13 @@ message CannotCreatePurchaseOrder { message CannotMarkPurchaseOrderAsDelivered { // The identifier of a purchase order which the user tried to mark as delivered. - PurchaseOrderId po_id = 1; + PurchaseOrderId po_id = 1 [(required) = true]; // The identifier of the user who tried to mark a purchase ordser as delivered. - UserId user_id = 2; + UserId user_id = 2 [(required) = true]; // Rejected at this time. - google.protobuf.Timestamp when_rejected = 3; + google.protobuf.Timestamp when_rejected = 3 [(required) = true]; } // The rejection to cancel a purchase order. @@ -244,13 +244,13 @@ message CannotMarkPurchaseOrderAsDelivered { message CannotCancelDeliveredPurchaseOrder { // The identifier of a purchase order which the user tried to cancel. - PurchaseOrderId po_id = 1; + PurchaseOrderId po_id = 1 [(required) = true]; // The identifier of the user who tried to cancel a purchase order. - UserId user_id = 2; + UserId user_id = 2 [(required) = true]; // Cancellation was rejected at this time. - google.protobuf.Timestamp when_rejected = 3; + google.protobuf.Timestamp when_rejected = 3 [(required) = true]; } // The rejection to overrule a purchase order validation. @@ -260,11 +260,11 @@ message CannotCancelDeliveredPurchaseOrder { message CannotOverruleValidationOfNotInvalidPO { // The identifier of a purchase order which validation the user tried to overrule. - PurchaseOrderId po_id = 1; + PurchaseOrderId po_id = 1 [(required) = true]; // The identifier of the user who tried to overrule validation. - UserId user_id = 2; + UserId user_id = 2 [(required) = true]; // Rejected at this time. - google.protobuf.Timestamp when_rejected = 3; + google.protobuf.Timestamp when_rejected = 3 [(required) = true]; } diff --git a/model/src/main/proto/javaclasses/mealorder/identifiers.proto b/model/src/main/proto/javaclasses/mealorder/identifiers.proto index 8d13a5c5..0673c4fd 100644 --- a/model/src/main/proto/javaclasses/mealorder/identifiers.proto +++ b/model/src/main/proto/javaclasses/mealorder/identifiers.proto @@ -40,7 +40,7 @@ import "javaclasses/mealorder/attributes.proto"; message VendorListId { // The ID of the vendor list - string value = 1; + string value = 1 [(required) = true]; } // The ID of the purchase order list. @@ -48,7 +48,7 @@ message VendorListId { message PurchaseOrderListId { // The ID of the purchase order list. - string value = 1; + string value = 1 [(required) = true]; } // The ID of the calendar. @@ -56,7 +56,7 @@ message PurchaseOrderListId { message MenuCalendarId { // The ID of the calendar. - string value = 1; + string value = 1 [(required) = true]; } // The ID of a user. @@ -66,7 +66,7 @@ message MenuCalendarId { message UserId { // The user's email. - spine.net.EmailAddress email = 1; + spine.net.EmailAddress email = 1 [(required) = true]; } // The ID of a vendor. @@ -74,7 +74,7 @@ message UserId { message VendorId { // Represented by the vendor name value in the next form 'vendor:<`VendorName`>'. - string value = 1; + string value = 1 [(required) = true]; } // The ID of a order. @@ -84,13 +84,13 @@ message VendorId { message OrderId { // The identifier of the vendor. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // The identifier of the user who makes an order. - UserId user_id = 2; + UserId user_id = 2 [(required) = true]; // The date of an order. - spine.time.LocalDate order_date = 3; + spine.time.LocalDate order_date = 3 [(required) = true]; } // The ID of a menu. @@ -100,10 +100,10 @@ message OrderId { message MenuId { // The identifier of the vendor. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // Was imported at this time. - google.protobuf.Timestamp when_imported = 2; + google.protobuf.Timestamp when_imported = 2 [(required) = true]; } // The ID of a dish. @@ -113,10 +113,10 @@ message MenuId { message DishId { // The sequence number of a dish in the menu. - int32 sequential_number = 1; + int32 sequential_number = 1 [(required) = true]; // The identifier of the menu. - MenuId menu_id = 2; + MenuId menu_id = 2 [(required) = true]; } // The ID of a purchase order. @@ -126,10 +126,10 @@ message DishId { message PurchaseOrderId { // The identifier of the vendor. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // The date on which a purchase order is formed. - spine.time.LocalDate po_date = 2; + spine.time.LocalDate po_date = 2 [(required) = true]; } // The ID of a menu list projection for UI role User. @@ -137,7 +137,7 @@ message PurchaseOrderId { message MenuListId { // The date on which the a list is formed. - spine.time.LocalDate date = 1; + spine.time.LocalDate date = 1 [(required) = true]; } // The ID of an order list projection for UI role User. @@ -145,10 +145,10 @@ message MenuListId { message OrderListId { // The date on which an order list is formed. - spine.time.LocalDate order_date = 1; + spine.time.LocalDate order_date = 1 [(required) = true]; // The identifier of the user who made orders. - UserId user_id = 2; + UserId user_id = 2 [(required) = true]; } // The ID of a monthly spendings report projection for UI role Admin. @@ -156,5 +156,5 @@ message OrderListId { message MonthlySpendingsReportId { // The month on which spendings are calculated. - LocalMonth month = 1; + LocalMonth month = 1 [(required) = true]; } diff --git a/model/src/main/proto/javaclasses/mealorder/model.proto b/model/src/main/proto/javaclasses/mealorder/model.proto index ca1e5ce9..383ec7e9 100644 --- a/model/src/main/proto/javaclasses/mealorder/model.proto +++ b/model/src/main/proto/javaclasses/mealorder/model.proto @@ -43,16 +43,16 @@ import "spine/net/email_address.proto"; message Dish { // The identifier of a dish. - DishId id = 1; + DishId id = 1 [(required) = true]; // The name of a dish. - string name = 2; + string name = 2 [(required) = true]; // A dish category. - string category = 3; + string category = 3 [(required) = true]; // A dish price. - spine.money.Money price = 4; + spine.money.Money price = 4 [(required) = true]; } // The model of a menu. @@ -62,10 +62,10 @@ message Dish { message Menu { // The identifier of a menu. - MenuId id = 1; + MenuId id = 1 [(required) = true]; // The date range when available. - MenuDateRange menu_date_range = 2; + MenuDateRange menu_date_range = 2 [(required) = true]; // The collection of dishes. repeated Dish dish = 3; @@ -87,7 +87,7 @@ message Menu { message Order { // The identifier of an order. - OrderId id = 1; + OrderId id = 1 [(required) = true]; // The collection of dishes. repeated Dish dish = 2; @@ -127,7 +127,7 @@ message Order { message PurchaseOrder { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The collection of orders. repeated Order order = 2; @@ -141,13 +141,13 @@ message PurchaseOrder { message Vendor { // The identifier of a vendor. - VendorId id = 1; + VendorId id = 1 [(required) = true]; // The name of a vendor - VendorName vendor_name = 2; + VendorName vendor_name = 2 [(required) = true]; // The email address to send a purchase order. - spine.net.EmailAddress email = 3; + spine.net.EmailAddress email = 3 [(required) = true]; // The phone numbers of a vendor. repeated PhoneNumber phone_number = 4; @@ -156,7 +156,7 @@ message Vendor { // // Time when orders for this vendor are closed for editing. // The purchase order for the specified vendor will be created exactly at this time. - spine.time.LocalTime po_daily_deadline = 5; + spine.time.LocalTime po_daily_deadline = 5 [(required) = true]; // The collection of menus. repeated Menu menu = 6; diff --git a/model/src/main/proto/javaclasses/mealorder/q/projections.proto b/model/src/main/proto/javaclasses/mealorder/q/projections.proto index 667cd1d5..6e2e0195 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/projections.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/projections.proto @@ -52,15 +52,10 @@ import "javaclasses/mealorder/values.proto"; // this date. This time is defined in a menu vendor aggregate. See `Vendor` // for more details. // -// Subscribes following events: -// 1. `DateRangeForMenuSet` -// 2. `PurchaseOrderCreated` -// 3. `MenuImported` -// message MenuListView { // The identifier of a menu list. - MenuListId list_id = 1; + MenuListId list_id = 1 [(required) = true]; // The collection of menus. repeated MenuItem menu = 2; @@ -72,12 +67,12 @@ message MenuListView { // today to the same day next week. (8 elements) // The each date contains information about the menus availability for it. // -// Subscribes on `DateRangeForMenuSet` +// Singleton, because the calendar is global. // message MenuCalendarView { // The identifier of the calendar. - MenuCalendarId menu_calendar_id = 1; + MenuCalendarId menu_calendar_id = 1 [(required) = true]; // The collection of calendar items (dates). repeated MenuCalendarItem calendar_item = 2; @@ -90,36 +85,26 @@ message MenuCalendarView { // // The order date and the user ID are specified by `OrderListId` value. // -// Subscribes following events: -// 1. `DishAddedToOrder` -// 2. `DishRemovedFromOrder` -// 3. `OrderCanceled` -// 4. `OrderProcessed` -// + message OrderListView { // The identifier of an order list. - OrderListId list_id = 1; + OrderListId list_id = 1 [(required) = true]; // The collection of user's orders. repeated OrderItem order = 2; - - // If true user cannot add or remove dishes. - bool processed = 3; } // **** Projections for UI role Admin. **** // The projection state of the vendor list. // -// Subscribes following events: -// 1. `VendorAdded` -// 2. `VendorUpdated` +// Singleton, because there is only one list of vendors. // message VendorListView { // The identifier of the vendor list singleton. - VendorListId vendor_list_id = 1; + VendorListId vendor_list_id = 1 [(required) = true]; // The collection of all vendors. repeated VendorItem vendor = 2; @@ -130,19 +115,10 @@ message VendorListView { // This view includes the list of all purchase orders, // sorted by date. // -// Subscribes following events: -// 1. `PurchaseOrderCreated` -// 2. `PurchaseOrderDelivered` -// 3. `PurchaseOrderSent` -// 4. `PurchaseOrderValidationFailed` -// 5. `PurchaseOrderValidationOverruled` -// 6. `PurchaseOrderValidationPassed` -// 7. `PurchaseOrderCanceled` -// message PurchaseOrderListView { // The identifier of the purchase order list singleton. - PurchaseOrderListId purchase_order_list_id = 1; + PurchaseOrderListId purchase_order_list_id = 1 [(required) = true]; // The collection of all purchase orders. repeated PurchaseOrderItem purchase_order = 2; @@ -151,19 +127,10 @@ message PurchaseOrderListView { // The projection state of a purchase order details view // grouped by dish. // -// Subscribes following events: -// 1. `PurchaseOrderCreated` -// 2. `PurchaseOrderDelivered` -// 3. `PurchaseOrderSent` -// 4. `PurchaseOrderValidationFailed` -// 5. `PurchaseOrderValidationOverruled` -// 6. `PurchaseOrderValidationPassed` -// 7. `PurchaseOrderCanceled` -// message PurchaseOrderDetailsByDishView { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The purchase order status. PurchaseOrderStatus purchase_order_status = 2; @@ -178,19 +145,10 @@ message PurchaseOrderDetailsByDishView { // When a purchase order is created its validation may complete with failure. // Those orders which caused that failure are marked as invalid. // -// Subscribes following events: -// 1. `PurchaseOrderCreated` -// 2. `PurchaseOrderDelivered` -// 3. `PurchaseOrderSent` -// 4. `PurchaseOrderValidationFailed` -// 5. `PurchaseOrderValidationOverruled` -// 6. `PurchaseOrderValidationPassed` -// 7. `PurchaseOrderCanceled` -// message PurchaseOrderDetailsByUserView { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The purchase order status. PurchaseOrderStatus purchase_order_status = 2; @@ -208,14 +166,10 @@ message PurchaseOrderDetailsByUserView { // It contains users spendings for period from month first // date till today if a report is formed for the current month. // -// Subscribes following events: -// 1. `PurchaseOrderDelivered` -// 2. `PurchaseOrderSent` -// message MonthlySpendingsReportView { // The identifier of a monthly spendings report. - MonthlySpendingsReportId report_id = 1; + MonthlySpendingsReportId report_id = 1 [(required) = true]; // The collection of users spendings for the specified month. repeated UserSpendings user_spending = 2; diff --git a/model/src/main/proto/javaclasses/mealorder/q/values.proto b/model/src/main/proto/javaclasses/mealorder/q/values.proto index 413ff83f..0619e509 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/values.proto @@ -45,7 +45,7 @@ import "javaclasses/mealorder/values.proto"; message MenuItem { // The vendor name. - VendorName vendor_name = 1; + VendorName vendor_name = 1 [(required) = true]; // The collection of categories. repeated DishesByCategory dishesByCategory = 2; @@ -59,7 +59,7 @@ message MenuItem { message DishesByCategory { // Category of dishes. - CategoryName category = 1; + CategoryName category = 1 [(required) = true]; // The collection of dishes. repeated DishItem dishes = 2; @@ -69,13 +69,13 @@ message DishesByCategory { message DishItem { // The identifier of a dish. - DishId id = 1; + DishId id = 1 [(required) = true]; // The name of a dish. - string name = 2; + string name = 2 [(required) = true]; // The dish price. - spine.money.Money price = 3; + spine.money.Money price = 3 [(required) = true]; } // The item of the menu calendar. @@ -86,10 +86,10 @@ message DishItem { message MenuCalendarItem { // A date in the menu calendar. - spine.time.LocalDate date = 1; + spine.time.LocalDate date = 1 [(required) = true]; // Indicates presence of attached menus on a specified date. - bool has_menu = 2; + bool has_menu = 2 [(required) = true]; } // The item of an order list. @@ -107,13 +107,13 @@ message MenuCalendarItem { message OrderItem { // The identifier of an order. - OrderId id = 1; + OrderId id = 1 [(required) = true]; // The collection of ordered dishes. repeated DishItem dish = 2; // Indicates an order is processed or not. - bool is_processed = 3; + bool is_processed = 3 [(required) = true]; } // The item of the vendor list. @@ -121,19 +121,19 @@ message OrderItem { message VendorItem { // The identifier of a vendor. - VendorId id = 1; + VendorId id = 1 [(required) = true]; // The vendor name. - VendorName vendor_name = 2; + VendorName vendor_name = 2 [(required) = true]; // The vendor email address. - spine.net.EmailAddress email = 3; + spine.net.EmailAddress email = 3 [(required) = true]; // Phone numbers of a vendor. repeated PhoneNumber phone_number = 4; // Daily purchase order creation deadline time. - spine.time.LocalTime po_daily_deadline = 5; + spine.time.LocalTime po_daily_deadline = 5 [(required) = true]; } // The item of the purchase order list. @@ -141,7 +141,7 @@ message VendorItem { message PurchaseOrderItem { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The purchase order status. PurchaseOrderStatus purchase_order_status = 2; @@ -157,7 +157,7 @@ message PurchaseOrderItem { message UserOrderDetails { // The identifier of the user. - UserId id = 1; + UserId id = 1 [(required) = true]; // The collection of dishes. repeated DishItem dish = 2; @@ -173,7 +173,7 @@ message UserOrderDetails { message UserSpendings { // The identifier of a user. - UserId id = 1; + UserId id = 1 [(required) = true]; // Amount of spendings. spine.money.Money amount = 2; diff --git a/model/src/main/proto/javaclasses/mealorder/values.proto b/model/src/main/proto/javaclasses/mealorder/values.proto index 22fe4fa4..d5c0773e 100644 --- a/model/src/main/proto/javaclasses/mealorder/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/values.proto @@ -43,10 +43,10 @@ import "spine/time/time.proto"; message MenuForDay { // Menu date - spine.time.LocalDate date = 1; + spine.time.LocalDate date = 1 [(required) = true]; // If available a user can add dishes to his order. - bool is_available = 2; + bool is_available = 2 [(required) = true]; } // Name of a category. @@ -55,7 +55,7 @@ message MenuForDay { message CategoryName { // Category of a dish. - string value = 1; + string value = 1 [(required) = true]; } // The model representing a date range. @@ -63,10 +63,10 @@ message CategoryName { message MenuDateRange { // The range start date. - spine.time.LocalDate range_start = 1; + spine.time.LocalDate range_start = 1 [(required) = true]; // The range end date. - spine.time.LocalDate range_end = 2; + spine.time.LocalDate range_end = 2 [(required) = true]; } // The model representing a phone number. @@ -74,7 +74,7 @@ message MenuDateRange { message PhoneNumber { // String representation of a phone number. - string value = 1; + string value = 1 [(required) = true]; } // The model representing a vendor name. @@ -82,7 +82,7 @@ message PhoneNumber { message VendorName { // The name of a vendor, unique for each vendor. - string value = 1; + string value = 1 [(required) = true]; } // The representation of changes in a vendor profile. @@ -90,28 +90,28 @@ message VendorName { message VendorChange { // The name that's changing. - VendorName previous_vendor_name = 1; + VendorName previous_vendor_name = 1 [(required) = true]; // The email address that's changing. - spine.net.EmailAddress previous_email = 2; + spine.net.EmailAddress previous_email = 2 [(required) = true]; // Phone numbers that are changing. repeated PhoneNumber previous_phone_number = 3; // Daily deadline time that's changing. - spine.time.LocalTime previous_po_daily_deadline = 4; + spine.time.LocalTime previous_po_daily_deadline = 4 [(required) = true]; // The new name. - VendorName new_vendor_name = 5; + VendorName new_vendor_name = 5 [(required) = true]; // The new email adress. - spine.net.EmailAddress new_email = 6; + spine.net.EmailAddress new_email = 6 [(required) = true]; // New phone numbers. - repeated PhoneNumber new_phone_number = 7; + repeated PhoneNumber new_phone_number = 7 [(required) = true]; // The new daily deadline time. - spine.time.LocalTime new_po_daily_deadline = 8; + spine.time.LocalTime new_po_daily_deadline = 8 [(required) = true]; } // A purchase order status values. @@ -158,8 +158,8 @@ enum OrderStatus { message VendorMismatch { // The vendor id in an order. - VendorId target = 1; + VendorId target = 1 [(required) = true]; // The vendor id in a dish. - VendorId actual = 2; + VendorId actual = 2 [(required) = true]; } diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestOrderCommandFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestOrderCommandFactory.java index 6bd62875..a8daa065 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestOrderCommandFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestOrderCommandFactory.java @@ -35,6 +35,7 @@ import static javaclasses.mealorder.testdata.TestValues.ORDER_ID; import static javaclasses.mealorder.testdata.TestValues.ORDER_ID_WITH_INVALID_DATE; import static javaclasses.mealorder.testdata.TestValues.ORDER_ID_WITH_INVALID_VENDOR; +import static javaclasses.mealorder.testdata.TestValues.USER_ID2; /** * @author Vlad Kozachenko @@ -72,6 +73,7 @@ public static CancelOrder cancelOrderInstance() { public static CancelOrder cancelOrderInstance(OrderId orderId) { return CancelOrder.newBuilder() .setOrderId(orderId) + .setWhoCancels(USER_ID2) .build(); } diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestPurchaseOrderCommandFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestPurchaseOrderCommandFactory.java index 4be24826..ceb6effe 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestPurchaseOrderCommandFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestPurchaseOrderCommandFactory.java @@ -37,9 +37,11 @@ import java.util.List; import static javaclasses.mealorder.OrderStatus.ORDER_CANCELED; +import static javaclasses.mealorder.testdata.TestValues.EMAIL; import static javaclasses.mealorder.testdata.TestValues.ORDER; import static javaclasses.mealorder.testdata.TestValues.PURCHASE_ORDER_ID; import static javaclasses.mealorder.testdata.TestValues.USER_ID; +import static javaclasses.mealorder.testdata.TestValues.USER_ID2; /** * A factory of the purchase order commands for the test needs. @@ -61,6 +63,7 @@ public static CreatePurchaseOrder createPurchaseOrderInstance() { .setId(PURCHASE_ORDER_ID) .setWhoCreates(USER_ID) .addOrder(ORDER) + .setVendorEmail(EMAIL) .build(); return result; } @@ -158,6 +161,8 @@ public static CreatePurchaseOrder createPurchaseOrderWithEmptyListInstance() { final PurchaseOrderId id = validCmd.getId(); final CreatePurchaseOrder result = CreatePurchaseOrder.newBuilder() .setId(id) + .setVendorEmail(EMAIL) + .setWhoCreates(USER_ID2) .build(); return result; } @@ -197,6 +202,7 @@ public static MarkPurchaseOrderAsValid markPurchaseOrderAsValidInstance() { .setId(PURCHASE_ORDER_ID) .setReason("Because I can.") .setUserId(USER_ID) + .setVendorEmail(EMAIL) .build(); return result; } From f06c37380c0605b21d23ccc9e452e6d60384468f Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 23 Apr 2018 19:48:38 +0300 Subject: [PATCH 34/66] Add tests for the `MonthlySpendingsReportViewProjection` projection --- .../MonthlySpendingsReportViewProjection.java | 32 +++----- ...thlySpendingsReportViewProjectionTest.java | 81 +++++++++++++++++++ .../mealorder/testdata/TestValues.java | 8 +- 3 files changed, 97 insertions(+), 24 deletions(-) create mode 100644 api-java/src/test/java/javaclasses/mealorder/q/projection/MonthlySpendingsReportViewProjectionTest.java diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java index 992c1415..2c9a9844 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java @@ -24,12 +24,7 @@ import io.spine.money.Money; import io.spine.server.projection.Projection; import javaclasses.mealorder.MonthlySpendingsReportId; -import javaclasses.mealorder.PurchaseOrderId; -import io.spine.time.LocalDate; import javaclasses.mealorder.Dish; -import javaclasses.mealorder.LocalMonth; -import javaclasses.mealorder.MenuListId; -import javaclasses.mealorder.MonthlySpendingsReportId; import javaclasses.mealorder.Order; import javaclasses.mealorder.PurchaseOrder; import javaclasses.mealorder.UserId; @@ -38,11 +33,10 @@ import javaclasses.mealorder.q.projection.MonthlySpendingsReportView; import javaclasses.mealorder.q.projection.MonthlySpendingsReportViewVBuilder; -public class MonthlySpendingsReportViewProjection extends Projection { import java.util.ArrayList; import java.util.List; -public class MonthlySpendingsReportViewProjection extends Projection { +public class MonthlySpendingsReportViewProjection extends Projection { /** * Creates a new instance. @@ -57,6 +51,7 @@ public MonthlySpendingsReportViewProjection(MonthlySpendingsReportId id) { @Subscribe void on(PurchaseOrderSent event) { final PurchaseOrder purchaseOrder = event.getPurchaseOrder(); + final List userOrderDetailsList = new ArrayList<>(); final List dishItemList = new ArrayList<>(); final List orders = purchaseOrder.getOrderList(); @@ -69,12 +64,15 @@ void on(PurchaseOrderSent event) { .getDishList(); for (int j = 0; j < dishList.size(); j++) { final DishItem dishItem = DishItem.newBuilder() - .setId(dishList.get(i) + .setId(dishList.get(j) .getId()) - .setName(dishList.get(i) + .setName(dishList.get(j) .getName()) - .setPrice(dishItemList.get(i) - .getPrice()) + .setPrice(Money.newBuilder() + .setAmount(dishList.get(j) + .getPrice() + .getAmount()) + .build()) .build(); dishItemList.add(dishItem); } @@ -84,18 +82,8 @@ void on(PurchaseOrderSent event) { .build(); userOrderDetailsList.add(userOrderDetails); } - - final LocalDate localDate = purchaseOrder.getId() - .getPoDate(); - final LocalMonth localMonth = LocalMonth.newBuilder() - .setMonth(localDate.getMonth()) - .setYear(localDate.getYear()) - .build(); - - getBuilder().setReportId(MonthlySpendingsReportId.newBuilder() - .setMonth(localMonth) - .build()); getBuilder().addAllOrder(userOrderDetailsList); + } @Subscribe diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/MonthlySpendingsReportViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/MonthlySpendingsReportViewProjectionTest.java new file mode 100644 index 00000000..0261e9ba --- /dev/null +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/MonthlySpendingsReportViewProjectionTest.java @@ -0,0 +1,81 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.projection; + +import javaclasses.mealorder.LocalMonth; +import javaclasses.mealorder.MonthlySpendingsReportId; +import javaclasses.mealorder.c.event.PurchaseOrderDelivered; +import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.q.MonthlySpendingsReportViewProjection; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderDeliveredInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderSentInstance; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class MonthlySpendingsReportViewProjectionTest extends ProjectionTest { + + private MonthlySpendingsReportViewProjection projection; + + @BeforeEach + void setUp() { + final LocalMonth localMonth = LocalMonth.newBuilder() + .setMonthValue(2) + .setYear(2019) + .build(); + + projection = new MonthlySpendingsReportViewProjection(MonthlySpendingsReportId.newBuilder() + .setMonth( + localMonth) + .build()); + } + + @Nested + @DisplayName("PurchaseOrderSent event should be interpreted by MonthlySpendingsReportViewProjection") + class PurchaseOrderSentEvent { + @Test + @DisplayName("Should add orders for a projection") + void addView() { + final PurchaseOrderSent purchaseOrderSent = purchaseOrderSentInstance(); + dispatch(projection, createEvent(purchaseOrderSent)); + assertEquals(1 , projection.getState().getOrderCount()); + } + } + + @Nested + @DisplayName("PurchaseOrderDelivered event should be interpreted by MonthlySpendingsReportViewProjection") + class PurchaseOrderDeliveredEvent { + @Test + @DisplayName("Should add user's spendings for a projection") + void addView() { + final PurchaseOrderSent purchaseOrderSent = purchaseOrderSentInstance(); + dispatch(projection, createEvent(purchaseOrderSent)); + final PurchaseOrderDelivered purchaseOrderDelivered = purchaseOrderDeliveredInstance(); + dispatch(projection, createEvent(purchaseOrderDelivered)); + assertEquals(1, projection.getState().getUserSpendingCount()); + } + } + +} diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java index d9c21587..09f59460 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java @@ -211,7 +211,9 @@ public class TestValues { .build()) .setName("dishName1") .setCategory("category") - .setPrice(Money.getDefaultInstance()) + .setPrice(Money.newBuilder() + .setAmount(56) + .build()) .build(); public static final Dish DISH2 = Dish.newBuilder() @@ -221,7 +223,9 @@ public class TestValues { .build()) .setName("dishName2") .setCategory("category") - .setPrice(Money.getDefaultInstance()) + .setPrice(Money.newBuilder() + .setAmount(56) + .build()) .build(); public static final Dish DISH3 = Dish.newBuilder() From 252040da0b37c7b8b76de781b327fc21cefac484 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 23 Apr 2018 20:40:02 +0300 Subject: [PATCH 35/66] Simplify event subscribers --- .../MonthlySpendingsReportViewProjection.java | 47 ++++++------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java index 2c9a9844..e674450f 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java @@ -51,27 +51,21 @@ public MonthlySpendingsReportViewProjection(MonthlySpendingsReportId id) { @Subscribe void on(PurchaseOrderSent event) { final PurchaseOrder purchaseOrder = event.getPurchaseOrder(); - final List userOrderDetailsList = new ArrayList<>(); final List dishItemList = new ArrayList<>(); final List orders = purchaseOrder.getOrderList(); - for (int i = 0; i < orders.size(); i++) { - final UserId userId = orders.get(i) - .getId() - .getUserId(); - final List dishList = orders.get(i) - .getDishList(); - for (int j = 0; j < dishList.size(); j++) { + for (Order order : orders) { + final UserId userId = order.getId() + .getUserId(); + final List dishList = order.getDishList(); + for (Dish aDishList : dishList) { final DishItem dishItem = DishItem.newBuilder() - .setId(dishList.get(j) - .getId()) - .setName(dishList.get(j) - .getName()) + .setId(aDishList.getId()) + .setName(aDishList.getName()) .setPrice(Money.newBuilder() - .setAmount(dishList.get(j) - .getPrice() - .getAmount()) + .setAmount(aDishList.getPrice() + .getAmount()) .build()) .build(); dishItemList.add(dishItem); @@ -83,36 +77,25 @@ void on(PurchaseOrderSent event) { userOrderDetailsList.add(userOrderDetails); } getBuilder().addAllOrder(userOrderDetailsList); - } @Subscribe void on(PurchaseOrderDelivered event) { final List userSpendingsList = new ArrayList<>(); + final List userOrderDetailsList = getBuilder().getOrder(); - for (int i = 0; i < getBuilder().getOrder() - .size(); i++) { - + for (UserOrderDetails userOrderDetails : userOrderDetailsList) { long money = 0; - for (int j = 0; j < getBuilder().getOrder() - .get(i) - .getDishList() - .size(); j++) { - money += getBuilder().getOrder() - .get(j) - .getDish(j) - .getPrice() - .getAmount(); + for (DishItem dishItem : userOrderDetails.getDishList()) { + money += dishItem.getPrice() + .getAmount(); } - final Money usersMoney = Money.newBuilder() .setAmount(money) .build(); final UserSpendings userSpendings = UserSpendings.newBuilder() - .setId(getBuilder().getOrder() - .get(i) - .getId()) + .setId(userOrderDetails.getId()) .setAmount(usersMoney) .build(); userSpendingsList.add(userSpendings); From 923a2de21c960ec4543cdc0b5a9b4270adac1cad Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Tue, 24 Apr 2018 11:04:22 +0300 Subject: [PATCH 36/66] Refactor required options in model --- .../javaclasses/mealorder/attributes.proto | 4 +-- .../javaclasses/mealorder/identifiers.proto | 36 +++++++++---------- .../proto/javaclasses/mealorder/model.proto | 24 ++++++------- .../javaclasses/mealorder/q/projections.proto | 16 ++++----- .../javaclasses/mealorder/q/values.proto | 32 ++++++++--------- .../proto/javaclasses/mealorder/values.proto | 2 +- 6 files changed, 57 insertions(+), 57 deletions(-) diff --git a/model/src/main/proto/javaclasses/mealorder/attributes.proto b/model/src/main/proto/javaclasses/mealorder/attributes.proto index 37c6681b..86fd7e87 100644 --- a/model/src/main/proto/javaclasses/mealorder/attributes.proto +++ b/model/src/main/proto/javaclasses/mealorder/attributes.proto @@ -37,8 +37,8 @@ import "spine/time/time.proto"; message LocalMonth { // The month value. - spine.time.MonthOfYear month = 1 [(required) = true]; + spine.time.MonthOfYear month = 1; // The year value. - int32 year = 2 [(required) = true]; + int32 year = 2; } diff --git a/model/src/main/proto/javaclasses/mealorder/identifiers.proto b/model/src/main/proto/javaclasses/mealorder/identifiers.proto index 0673c4fd..8d13a5c5 100644 --- a/model/src/main/proto/javaclasses/mealorder/identifiers.proto +++ b/model/src/main/proto/javaclasses/mealorder/identifiers.proto @@ -40,7 +40,7 @@ import "javaclasses/mealorder/attributes.proto"; message VendorListId { // The ID of the vendor list - string value = 1 [(required) = true]; + string value = 1; } // The ID of the purchase order list. @@ -48,7 +48,7 @@ message VendorListId { message PurchaseOrderListId { // The ID of the purchase order list. - string value = 1 [(required) = true]; + string value = 1; } // The ID of the calendar. @@ -56,7 +56,7 @@ message PurchaseOrderListId { message MenuCalendarId { // The ID of the calendar. - string value = 1 [(required) = true]; + string value = 1; } // The ID of a user. @@ -66,7 +66,7 @@ message MenuCalendarId { message UserId { // The user's email. - spine.net.EmailAddress email = 1 [(required) = true]; + spine.net.EmailAddress email = 1; } // The ID of a vendor. @@ -74,7 +74,7 @@ message UserId { message VendorId { // Represented by the vendor name value in the next form 'vendor:<`VendorName`>'. - string value = 1 [(required) = true]; + string value = 1; } // The ID of a order. @@ -84,13 +84,13 @@ message VendorId { message OrderId { // The identifier of the vendor. - VendorId vendor_id = 1 [(required) = true]; + VendorId vendor_id = 1; // The identifier of the user who makes an order. - UserId user_id = 2 [(required) = true]; + UserId user_id = 2; // The date of an order. - spine.time.LocalDate order_date = 3 [(required) = true]; + spine.time.LocalDate order_date = 3; } // The ID of a menu. @@ -100,10 +100,10 @@ message OrderId { message MenuId { // The identifier of the vendor. - VendorId vendor_id = 1 [(required) = true]; + VendorId vendor_id = 1; // Was imported at this time. - google.protobuf.Timestamp when_imported = 2 [(required) = true]; + google.protobuf.Timestamp when_imported = 2; } // The ID of a dish. @@ -113,10 +113,10 @@ message MenuId { message DishId { // The sequence number of a dish in the menu. - int32 sequential_number = 1 [(required) = true]; + int32 sequential_number = 1; // The identifier of the menu. - MenuId menu_id = 2 [(required) = true]; + MenuId menu_id = 2; } // The ID of a purchase order. @@ -126,10 +126,10 @@ message DishId { message PurchaseOrderId { // The identifier of the vendor. - VendorId vendor_id = 1 [(required) = true]; + VendorId vendor_id = 1; // The date on which a purchase order is formed. - spine.time.LocalDate po_date = 2 [(required) = true]; + spine.time.LocalDate po_date = 2; } // The ID of a menu list projection for UI role User. @@ -137,7 +137,7 @@ message PurchaseOrderId { message MenuListId { // The date on which the a list is formed. - spine.time.LocalDate date = 1 [(required) = true]; + spine.time.LocalDate date = 1; } // The ID of an order list projection for UI role User. @@ -145,10 +145,10 @@ message MenuListId { message OrderListId { // The date on which an order list is formed. - spine.time.LocalDate order_date = 1 [(required) = true]; + spine.time.LocalDate order_date = 1; // The identifier of the user who made orders. - UserId user_id = 2 [(required) = true]; + UserId user_id = 2; } // The ID of a monthly spendings report projection for UI role Admin. @@ -156,5 +156,5 @@ message OrderListId { message MonthlySpendingsReportId { // The month on which spendings are calculated. - LocalMonth month = 1 [(required) = true]; + LocalMonth month = 1; } diff --git a/model/src/main/proto/javaclasses/mealorder/model.proto b/model/src/main/proto/javaclasses/mealorder/model.proto index 383ec7e9..ca1e5ce9 100644 --- a/model/src/main/proto/javaclasses/mealorder/model.proto +++ b/model/src/main/proto/javaclasses/mealorder/model.proto @@ -43,16 +43,16 @@ import "spine/net/email_address.proto"; message Dish { // The identifier of a dish. - DishId id = 1 [(required) = true]; + DishId id = 1; // The name of a dish. - string name = 2 [(required) = true]; + string name = 2; // A dish category. - string category = 3 [(required) = true]; + string category = 3; // A dish price. - spine.money.Money price = 4 [(required) = true]; + spine.money.Money price = 4; } // The model of a menu. @@ -62,10 +62,10 @@ message Dish { message Menu { // The identifier of a menu. - MenuId id = 1 [(required) = true]; + MenuId id = 1; // The date range when available. - MenuDateRange menu_date_range = 2 [(required) = true]; + MenuDateRange menu_date_range = 2; // The collection of dishes. repeated Dish dish = 3; @@ -87,7 +87,7 @@ message Menu { message Order { // The identifier of an order. - OrderId id = 1 [(required) = true]; + OrderId id = 1; // The collection of dishes. repeated Dish dish = 2; @@ -127,7 +127,7 @@ message Order { message PurchaseOrder { // The identifier of a purchase order. - PurchaseOrderId id = 1 [(required) = true]; + PurchaseOrderId id = 1; // The collection of orders. repeated Order order = 2; @@ -141,13 +141,13 @@ message PurchaseOrder { message Vendor { // The identifier of a vendor. - VendorId id = 1 [(required) = true]; + VendorId id = 1; // The name of a vendor - VendorName vendor_name = 2 [(required) = true]; + VendorName vendor_name = 2; // The email address to send a purchase order. - spine.net.EmailAddress email = 3 [(required) = true]; + spine.net.EmailAddress email = 3; // The phone numbers of a vendor. repeated PhoneNumber phone_number = 4; @@ -156,7 +156,7 @@ message Vendor { // // Time when orders for this vendor are closed for editing. // The purchase order for the specified vendor will be created exactly at this time. - spine.time.LocalTime po_daily_deadline = 5 [(required) = true]; + spine.time.LocalTime po_daily_deadline = 5; // The collection of menus. repeated Menu menu = 6; diff --git a/model/src/main/proto/javaclasses/mealorder/q/projections.proto b/model/src/main/proto/javaclasses/mealorder/q/projections.proto index 6e2e0195..b9e4c6e4 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/projections.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/projections.proto @@ -55,7 +55,7 @@ import "javaclasses/mealorder/values.proto"; message MenuListView { // The identifier of a menu list. - MenuListId list_id = 1 [(required) = true]; + MenuListId list_id = 1; // The collection of menus. repeated MenuItem menu = 2; @@ -72,7 +72,7 @@ message MenuListView { message MenuCalendarView { // The identifier of the calendar. - MenuCalendarId menu_calendar_id = 1 [(required) = true]; + MenuCalendarId menu_calendar_id = 1; // The collection of calendar items (dates). repeated MenuCalendarItem calendar_item = 2; @@ -89,7 +89,7 @@ message MenuCalendarView { message OrderListView { // The identifier of an order list. - OrderListId list_id = 1 [(required) = true]; + OrderListId list_id = 1; // The collection of user's orders. repeated OrderItem order = 2; @@ -104,7 +104,7 @@ message OrderListView { message VendorListView { // The identifier of the vendor list singleton. - VendorListId vendor_list_id = 1 [(required) = true]; + VendorListId vendor_list_id = 1; // The collection of all vendors. repeated VendorItem vendor = 2; @@ -118,7 +118,7 @@ message VendorListView { message PurchaseOrderListView { // The identifier of the purchase order list singleton. - PurchaseOrderListId purchase_order_list_id = 1 [(required) = true]; + PurchaseOrderListId purchase_order_list_id = 1; // The collection of all purchase orders. repeated PurchaseOrderItem purchase_order = 2; @@ -130,7 +130,7 @@ message PurchaseOrderListView { message PurchaseOrderDetailsByDishView { // The identifier of a purchase order. - PurchaseOrderId id = 1 [(required) = true]; + PurchaseOrderId id = 1; // The purchase order status. PurchaseOrderStatus purchase_order_status = 2; @@ -148,7 +148,7 @@ message PurchaseOrderDetailsByDishView { message PurchaseOrderDetailsByUserView { // The identifier of a purchase order. - PurchaseOrderId id = 1 [(required) = true]; + PurchaseOrderId id = 1; // The purchase order status. PurchaseOrderStatus purchase_order_status = 2; @@ -169,7 +169,7 @@ message PurchaseOrderDetailsByUserView { message MonthlySpendingsReportView { // The identifier of a monthly spendings report. - MonthlySpendingsReportId report_id = 1 [(required) = true]; + MonthlySpendingsReportId report_id = 1; // The collection of users spendings for the specified month. repeated UserSpendings user_spending = 2; diff --git a/model/src/main/proto/javaclasses/mealorder/q/values.proto b/model/src/main/proto/javaclasses/mealorder/q/values.proto index 0619e509..413ff83f 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/values.proto @@ -45,7 +45,7 @@ import "javaclasses/mealorder/values.proto"; message MenuItem { // The vendor name. - VendorName vendor_name = 1 [(required) = true]; + VendorName vendor_name = 1; // The collection of categories. repeated DishesByCategory dishesByCategory = 2; @@ -59,7 +59,7 @@ message MenuItem { message DishesByCategory { // Category of dishes. - CategoryName category = 1 [(required) = true]; + CategoryName category = 1; // The collection of dishes. repeated DishItem dishes = 2; @@ -69,13 +69,13 @@ message DishesByCategory { message DishItem { // The identifier of a dish. - DishId id = 1 [(required) = true]; + DishId id = 1; // The name of a dish. - string name = 2 [(required) = true]; + string name = 2; // The dish price. - spine.money.Money price = 3 [(required) = true]; + spine.money.Money price = 3; } // The item of the menu calendar. @@ -86,10 +86,10 @@ message DishItem { message MenuCalendarItem { // A date in the menu calendar. - spine.time.LocalDate date = 1 [(required) = true]; + spine.time.LocalDate date = 1; // Indicates presence of attached menus on a specified date. - bool has_menu = 2 [(required) = true]; + bool has_menu = 2; } // The item of an order list. @@ -107,13 +107,13 @@ message MenuCalendarItem { message OrderItem { // The identifier of an order. - OrderId id = 1 [(required) = true]; + OrderId id = 1; // The collection of ordered dishes. repeated DishItem dish = 2; // Indicates an order is processed or not. - bool is_processed = 3 [(required) = true]; + bool is_processed = 3; } // The item of the vendor list. @@ -121,19 +121,19 @@ message OrderItem { message VendorItem { // The identifier of a vendor. - VendorId id = 1 [(required) = true]; + VendorId id = 1; // The vendor name. - VendorName vendor_name = 2 [(required) = true]; + VendorName vendor_name = 2; // The vendor email address. - spine.net.EmailAddress email = 3 [(required) = true]; + spine.net.EmailAddress email = 3; // Phone numbers of a vendor. repeated PhoneNumber phone_number = 4; // Daily purchase order creation deadline time. - spine.time.LocalTime po_daily_deadline = 5 [(required) = true]; + spine.time.LocalTime po_daily_deadline = 5; } // The item of the purchase order list. @@ -141,7 +141,7 @@ message VendorItem { message PurchaseOrderItem { // The identifier of a purchase order. - PurchaseOrderId id = 1 [(required) = true]; + PurchaseOrderId id = 1; // The purchase order status. PurchaseOrderStatus purchase_order_status = 2; @@ -157,7 +157,7 @@ message PurchaseOrderItem { message UserOrderDetails { // The identifier of the user. - UserId id = 1 [(required) = true]; + UserId id = 1; // The collection of dishes. repeated DishItem dish = 2; @@ -173,7 +173,7 @@ message UserOrderDetails { message UserSpendings { // The identifier of a user. - UserId id = 1 [(required) = true]; + UserId id = 1; // Amount of spendings. spine.money.Money amount = 2; diff --git a/model/src/main/proto/javaclasses/mealorder/values.proto b/model/src/main/proto/javaclasses/mealorder/values.proto index d5c0773e..62c13bf2 100644 --- a/model/src/main/proto/javaclasses/mealorder/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/values.proto @@ -96,7 +96,7 @@ message VendorChange { spine.net.EmailAddress previous_email = 2 [(required) = true]; // Phone numbers that are changing. - repeated PhoneNumber previous_phone_number = 3; + repeated PhoneNumber previous_phone_number = 3 [(required) = true]; // Daily deadline time that's changing. spine.time.LocalTime previous_po_daily_deadline = 4 [(required) = true]; From 900229d2069d90f766533a7a0554eb120439a0e5 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Tue, 24 Apr 2018 12:39:40 +0300 Subject: [PATCH 37/66] Fix required fields in proto model --- .../c/vendor/SetDateRangeForMenuTest.java | 8 +++++ .../javaclasses/mealorder/attributes.proto | 4 +-- .../javaclasses/mealorder/identifiers.proto | 36 +++++++++---------- .../proto/javaclasses/mealorder/model.proto | 34 +++++++++--------- .../javaclasses/mealorder/q/values.proto | 36 +++++++++---------- .../mealorder/testdata/TestValues.java | 2 +- 6 files changed, 64 insertions(+), 56 deletions(-) diff --git a/api-java/src/test/java/javaclasses/mealorder/c/vendor/SetDateRangeForMenuTest.java b/api-java/src/test/java/javaclasses/mealorder/c/vendor/SetDateRangeForMenuTest.java index 4a3e4a34..09a91463 100644 --- a/api-java/src/test/java/javaclasses/mealorder/c/vendor/SetDateRangeForMenuTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/c/vendor/SetDateRangeForMenuTest.java @@ -66,6 +66,8 @@ public void setUp() { @Test @DisplayName("produce `DateRangeForMenuSet` event") void produceEvent() { + final AddVendor addVendor = TestVendorCommandFactory.addVendorInstance(); + dispatchCommand(aggregate, envelopeOf(addVendor)); final ImportMenu importMenu = TestVendorCommandFactory.importMenuInstance(); dispatchCommand(aggregate, envelopeOf(importMenu)); @@ -119,6 +121,8 @@ void setDateRange() { @Test @DisplayName("produce `CannotSetDateRange` rejection if date range is not valid") void produceRejection() { + final AddVendor addVendor = TestVendorCommandFactory.addVendorInstance(); + dispatchCommand(aggregate, envelopeOf(addVendor)); final ImportMenu importMenu = TestVendorCommandFactory.importMenuInstance(); dispatchCommand(aggregate, envelopeOf(importMenu)); @@ -144,6 +148,8 @@ void produceRejection() { @Test @DisplayName("produce `CannotSetDateRange` rejection if the order date is from the past") void produceCannotSetDateRangeRejection() { + final AddVendor addVendor = TestVendorCommandFactory.addVendorInstance(); + dispatchCommand(aggregate, envelopeOf(addVendor)); final ImportMenu importMenu = TestVendorCommandFactory.importMenuInstance(); dispatchCommand(aggregate, envelopeOf(importMenu)); @@ -167,6 +173,8 @@ void produceCannotSetDateRangeRejection() { @Test @DisplayName("produce `CannotSetDateRange` rejection if vendor already has menu on this date range") void produceRejectionIfMenuExists() { + final AddVendor addVendor = TestVendorCommandFactory.addVendorInstance(); + dispatchCommand(aggregate, envelopeOf(addVendor)); final ImportMenu importMenu = TestVendorCommandFactory.importMenuInstance(); dispatchCommand(aggregate, envelopeOf(importMenu)); diff --git a/model/src/main/proto/javaclasses/mealorder/attributes.proto b/model/src/main/proto/javaclasses/mealorder/attributes.proto index 86fd7e87..37c6681b 100644 --- a/model/src/main/proto/javaclasses/mealorder/attributes.proto +++ b/model/src/main/proto/javaclasses/mealorder/attributes.proto @@ -37,8 +37,8 @@ import "spine/time/time.proto"; message LocalMonth { // The month value. - spine.time.MonthOfYear month = 1; + spine.time.MonthOfYear month = 1 [(required) = true]; // The year value. - int32 year = 2; + int32 year = 2 [(required) = true]; } diff --git a/model/src/main/proto/javaclasses/mealorder/identifiers.proto b/model/src/main/proto/javaclasses/mealorder/identifiers.proto index 8d13a5c5..0673c4fd 100644 --- a/model/src/main/proto/javaclasses/mealorder/identifiers.proto +++ b/model/src/main/proto/javaclasses/mealorder/identifiers.proto @@ -40,7 +40,7 @@ import "javaclasses/mealorder/attributes.proto"; message VendorListId { // The ID of the vendor list - string value = 1; + string value = 1 [(required) = true]; } // The ID of the purchase order list. @@ -48,7 +48,7 @@ message VendorListId { message PurchaseOrderListId { // The ID of the purchase order list. - string value = 1; + string value = 1 [(required) = true]; } // The ID of the calendar. @@ -56,7 +56,7 @@ message PurchaseOrderListId { message MenuCalendarId { // The ID of the calendar. - string value = 1; + string value = 1 [(required) = true]; } // The ID of a user. @@ -66,7 +66,7 @@ message MenuCalendarId { message UserId { // The user's email. - spine.net.EmailAddress email = 1; + spine.net.EmailAddress email = 1 [(required) = true]; } // The ID of a vendor. @@ -74,7 +74,7 @@ message UserId { message VendorId { // Represented by the vendor name value in the next form 'vendor:<`VendorName`>'. - string value = 1; + string value = 1 [(required) = true]; } // The ID of a order. @@ -84,13 +84,13 @@ message VendorId { message OrderId { // The identifier of the vendor. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // The identifier of the user who makes an order. - UserId user_id = 2; + UserId user_id = 2 [(required) = true]; // The date of an order. - spine.time.LocalDate order_date = 3; + spine.time.LocalDate order_date = 3 [(required) = true]; } // The ID of a menu. @@ -100,10 +100,10 @@ message OrderId { message MenuId { // The identifier of the vendor. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // Was imported at this time. - google.protobuf.Timestamp when_imported = 2; + google.protobuf.Timestamp when_imported = 2 [(required) = true]; } // The ID of a dish. @@ -113,10 +113,10 @@ message MenuId { message DishId { // The sequence number of a dish in the menu. - int32 sequential_number = 1; + int32 sequential_number = 1 [(required) = true]; // The identifier of the menu. - MenuId menu_id = 2; + MenuId menu_id = 2 [(required) = true]; } // The ID of a purchase order. @@ -126,10 +126,10 @@ message DishId { message PurchaseOrderId { // The identifier of the vendor. - VendorId vendor_id = 1; + VendorId vendor_id = 1 [(required) = true]; // The date on which a purchase order is formed. - spine.time.LocalDate po_date = 2; + spine.time.LocalDate po_date = 2 [(required) = true]; } // The ID of a menu list projection for UI role User. @@ -137,7 +137,7 @@ message PurchaseOrderId { message MenuListId { // The date on which the a list is formed. - spine.time.LocalDate date = 1; + spine.time.LocalDate date = 1 [(required) = true]; } // The ID of an order list projection for UI role User. @@ -145,10 +145,10 @@ message MenuListId { message OrderListId { // The date on which an order list is formed. - spine.time.LocalDate order_date = 1; + spine.time.LocalDate order_date = 1 [(required) = true]; // The identifier of the user who made orders. - UserId user_id = 2; + UserId user_id = 2 [(required) = true]; } // The ID of a monthly spendings report projection for UI role Admin. @@ -156,5 +156,5 @@ message OrderListId { message MonthlySpendingsReportId { // The month on which spendings are calculated. - LocalMonth month = 1; + LocalMonth month = 1 [(required) = true]; } diff --git a/model/src/main/proto/javaclasses/mealorder/model.proto b/model/src/main/proto/javaclasses/mealorder/model.proto index ca1e5ce9..89316f0f 100644 --- a/model/src/main/proto/javaclasses/mealorder/model.proto +++ b/model/src/main/proto/javaclasses/mealorder/model.proto @@ -43,16 +43,16 @@ import "spine/net/email_address.proto"; message Dish { // The identifier of a dish. - DishId id = 1; + DishId id = 1 [(required) = true]; // The name of a dish. - string name = 2; + string name = 2 [(required) = true]; // A dish category. - string category = 3; + string category = 3 [(required) = true]; // A dish price. - spine.money.Money price = 4; + spine.money.Money price = 4 [(required) = true]; } // The model of a menu. @@ -62,13 +62,13 @@ message Dish { message Menu { // The identifier of a menu. - MenuId id = 1; + MenuId id = 1 [(required) = true]; // The date range when available. - MenuDateRange menu_date_range = 2; + MenuDateRange menu_date_range = 2 [(required) = true]; // The collection of dishes. - repeated Dish dish = 3; + repeated Dish dish = 3 [(required) = true]; } // The model representing the `Order` aggregate. @@ -87,13 +87,13 @@ message Menu { message Order { // The identifier of an order. - OrderId id = 1; + OrderId id = 1 [(required) = true]; // The collection of dishes. repeated Dish dish = 2; // The status of an order. - OrderStatus status = 3; + OrderStatus status = 3 [(required) = true]; } // The model representing the `PurchaseOrder` aggregate. @@ -127,13 +127,13 @@ message Order { message PurchaseOrder { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The collection of orders. - repeated Order order = 2; + repeated Order order = 2 [(required) = true]; // The status of a purchase order. - PurchaseOrderStatus status = 3; + PurchaseOrderStatus status = 3 [(required) = true]; } // The model representing the `Vendor` aggregate. @@ -141,22 +141,22 @@ message PurchaseOrder { message Vendor { // The identifier of a vendor. - VendorId id = 1; + VendorId id = 1 [(required) = true]; // The name of a vendor - VendorName vendor_name = 2; + VendorName vendor_name = 2 [(required) = true]; // The email address to send a purchase order. - spine.net.EmailAddress email = 3; + spine.net.EmailAddress email = 3 [(required) = true]; // The phone numbers of a vendor. - repeated PhoneNumber phone_number = 4; + repeated PhoneNumber phone_number = 4 [(required) = true]; // Daily deadline time. // // Time when orders for this vendor are closed for editing. // The purchase order for the specified vendor will be created exactly at this time. - spine.time.LocalTime po_daily_deadline = 5; + spine.time.LocalTime po_daily_deadline = 5 [(required) = true]; // The collection of menus. repeated Menu menu = 6; diff --git a/model/src/main/proto/javaclasses/mealorder/q/values.proto b/model/src/main/proto/javaclasses/mealorder/q/values.proto index 413ff83f..953da5c5 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/values.proto @@ -45,10 +45,10 @@ import "javaclasses/mealorder/values.proto"; message MenuItem { // The vendor name. - VendorName vendor_name = 1; + VendorName vendor_name = 1 [(required) = true]; // The collection of categories. - repeated DishesByCategory dishesByCategory = 2; + repeated DishesByCategory dishesByCategory = 2 [(required) = true]; // Date range when a menu is available. repeated MenuForDay menu_days = 3; @@ -59,7 +59,7 @@ message MenuItem { message DishesByCategory { // Category of dishes. - CategoryName category = 1; + CategoryName category = 1 [(required) = true]; // The collection of dishes. repeated DishItem dishes = 2; @@ -69,13 +69,13 @@ message DishesByCategory { message DishItem { // The identifier of a dish. - DishId id = 1; + DishId id = 1 [(required) = true]; // The name of a dish. - string name = 2; + string name = 2 [(required) = true]; // The dish price. - spine.money.Money price = 3; + spine.money.Money price = 3 [(required) = true]; } // The item of the menu calendar. @@ -86,10 +86,10 @@ message DishItem { message MenuCalendarItem { // A date in the menu calendar. - spine.time.LocalDate date = 1; + spine.time.LocalDate date = 1 [(required) = true]; // Indicates presence of attached menus on a specified date. - bool has_menu = 2; + bool has_menu = 2 [(required) = true]; } // The item of an order list. @@ -107,7 +107,7 @@ message MenuCalendarItem { message OrderItem { // The identifier of an order. - OrderId id = 1; + OrderId id = 1 [(required) = true]; // The collection of ordered dishes. repeated DishItem dish = 2; @@ -121,19 +121,19 @@ message OrderItem { message VendorItem { // The identifier of a vendor. - VendorId id = 1; + VendorId id = 1 [(required) = true]; // The vendor name. - VendorName vendor_name = 2; + VendorName vendor_name = 2 [(required) = true]; // The vendor email address. - spine.net.EmailAddress email = 3; + spine.net.EmailAddress email = 3 [(required) = true]; // Phone numbers of a vendor. repeated PhoneNumber phone_number = 4; // Daily purchase order creation deadline time. - spine.time.LocalTime po_daily_deadline = 5; + spine.time.LocalTime po_daily_deadline = 5 [(required) = true]; } // The item of the purchase order list. @@ -141,10 +141,10 @@ message VendorItem { message PurchaseOrderItem { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The purchase order status. - PurchaseOrderStatus purchase_order_status = 2; + PurchaseOrderStatus purchase_order_status = 2 [(required) = true]; } // The item of an order list. @@ -157,7 +157,7 @@ message PurchaseOrderItem { message UserOrderDetails { // The identifier of the user. - UserId id = 1; + UserId id = 1 [(required) = true]; // The collection of dishes. repeated DishItem dish = 2; @@ -173,8 +173,8 @@ message UserOrderDetails { message UserSpendings { // The identifier of a user. - UserId id = 1; + UserId id = 1 [(required) = true]; // Amount of spendings. - spine.money.Money amount = 2; + spine.money.Money amount = 2 [(required) = true]; } diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java index 09f59460..e2a2389f 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java @@ -118,7 +118,7 @@ public class TestValues { .setNewEmail(EMAIL) .addNewPhoneNumber(PHONE_NUMBER1) .addNewPhoneNumber(PHONE_NUMBER2) - .setPreviousPoDailyDeadline( + .setNewPoDailyDeadline( PO_DAILY_DEADLINE) .build(); From 14705101845b1a49090271e7e9461368d81981f7 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Tue, 24 Apr 2018 16:40:59 +0300 Subject: [PATCH 38/66] Rework `OrderListViewProjection` and test --- .../mealorder/q/OrderListViewProjection.java | 20 ++-- .../q/PurchaseOrderItemViewProjection.java | 78 ++++++++++++++ .../q/PurchaseOrderListViewProjection.java | 102 ------------------ .../OrderListViewProjectionTest.java | 35 +++++- ...eOrderDetailsByUserViewProjectionTest.java | 2 +- ... PurchaseOrderItemViewProjectionTest.java} | 54 ++++++---- .../javaclasses/mealorder/q/projections.proto | 10 +- .../javaclasses/mealorder/q/values.proto | 11 -- .../testdata/TestMealOrderEventFactory.java | 23 ++++ 9 files changed, 181 insertions(+), 154 deletions(-) create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderItemViewProjection.java delete mode 100644 api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java rename api-java/src/test/java/javaclasses/mealorder/q/projection/{PurchaseOrderListViewProjectionTest.java => PurchaseOrderItemViewProjectionTest.java} (60%) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java index 8a69f805..e6a00a6b 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java @@ -60,8 +60,7 @@ void on(DishAddedToOrder event) { .setPrice(event.getDish() .getPrice()) .build(); - if (getBuilder().getOrder() - .contains(getOrderById(orderId))) { + if (getOrderById(orderId).isPresent()) { final OrderListId listId = OrderListId.newBuilder() .setUserId(event.getOrderId() .getUserId()) @@ -69,8 +68,8 @@ void on(DishAddedToOrder event) { .getOrderDate()) .build(); getBuilder().setOrder(getBuilder().getOrder() - .indexOf(getOrderById(orderId)), - OrderItem.newBuilder(getOrderById(orderId)) + .indexOf(getOrderById(orderId).get()), + OrderItem.newBuilder(getOrderById(orderId).get()) .addDish(dish) .build()) .setListId(listId); @@ -85,8 +84,9 @@ void on(DishAddedToOrder event) { @Subscribe void on(DishRemovedFromOrder event) { final List orderItems = getBuilder().getOrder(); - final int removeIndex = getDishFromOrder(event.getDish(), getOrderById(event.getOrderId())); - final OrderItem newOrder = OrderItem.newBuilder(getOrderById(event.getOrderId())) + final int removeIndex = getDishFromOrder(event.getDish(), + getOrderById(event.getOrderId()).get()); + final OrderItem newOrder = OrderItem.newBuilder(getOrderById(event.getOrderId()).get()) .removeDish(removeIndex) .build(); getBuilder().setOrder(orderItems.indexOf(getOrderById(event.getOrderId())), newOrder); @@ -94,7 +94,7 @@ void on(DishRemovedFromOrder event) { @Subscribe void on(OrderCanceled event) { - final OrderItem order = getOrderById(event.getOrderId()); + final OrderItem order = getOrderById(event.getOrderId()).get(); getBuilder().removeOrder(getBuilder().getOrder() .indexOf(order)); } @@ -103,21 +103,21 @@ void on(OrderCanceled event) { void on(OrderProcessed event) { final OrderItem order = getOrderById(event.getOrder() - .getId()); + .getId()).get(); getBuilder().setOrder(getBuilder().getOrder() .indexOf(order), OrderItem.newBuilder(order) .setIsProcessed(true) .build()); } - private OrderItem getOrderById(OrderId orderId) { + private Optional getOrderById(OrderId orderId) { final List orderItems = getBuilder().getOrder(); final Optional inventoryItem = orderItems.stream() .filter(item -> item.getId() .equals(orderId)) .findFirst(); - return inventoryItem.get(); + return inventoryItem; } private int getDishFromOrder(Dish dish, OrderItem order) { diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderItemViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderItemViewProjection.java new file mode 100644 index 00000000..5c09c4f3 --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderItemViewProjection.java @@ -0,0 +1,78 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q; + +import io.spine.core.Subscribe; +import io.spine.server.entity.storage.Column; +import io.spine.server.projection.Projection; +import javaclasses.mealorder.PurchaseOrderId; +import javaclasses.mealorder.PurchaseOrderListId; +import javaclasses.mealorder.PurchaseOrderStatus; +import javaclasses.mealorder.c.event.PurchaseOrderDelivered; +import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.c.event.PurchaseOrderValidationFailed; +import javaclasses.mealorder.q.projection.PurchaseOrderItemView; +import javaclasses.mealorder.q.projection.PurchaseOrderItemViewVBuilder; + +import javax.annotation.Nullable; + +public class PurchaseOrderItemViewProjection extends Projection { + + /** + * Creates a new instance. + * + * @param id the ID for the new instance + * @throws IllegalArgumentException if the ID is not of one of the supported types + */ + public PurchaseOrderItemViewProjection(PurchaseOrderListId id) { + super(id); + } + + @Column + @Nullable + public PurchaseOrderId getPurchaseOrderId() { + return getState().getId(); + } + + @Column + @Nullable + public PurchaseOrderStatus getPurchaseOrderStatus() { + return getState().getPurchaseOrderStatus(); + } + + @Subscribe + void on(PurchaseOrderSent event) { + getBuilder().setId(event.getPurchaseOrder() + .getId()); + getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.SENT); + } + + @Subscribe + void on(PurchaseOrderDelivered event) { + getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.DELIVERED); + + } + + @Subscribe + void on(PurchaseOrderValidationFailed event) { + getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.INVALID); + } +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java deleted file mode 100644 index eff690b2..00000000 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderListViewProjection.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2018, TeamDev Ltd. All rights reserved. - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package javaclasses.mealorder.q; - -import io.spine.core.Subscribe; -import io.spine.server.projection.Projection; -import javaclasses.mealorder.PurchaseOrderId; -import javaclasses.mealorder.PurchaseOrderListId; -import javaclasses.mealorder.PurchaseOrderStatus; -import javaclasses.mealorder.c.event.PurchaseOrderDelivered; -import javaclasses.mealorder.c.event.PurchaseOrderSent; -import javaclasses.mealorder.c.event.PurchaseOrderValidationFailed; -import javaclasses.mealorder.q.projection.PurchaseOrderListView; -import javaclasses.mealorder.q.projection.PurchaseOrderListViewVBuilder; - -import java.util.List; -import java.util.stream.IntStream; - -public class PurchaseOrderListViewProjection extends Projection { - - /** - * {@link MenuCalendarViewProjection} is a singleton. - * - *

The {@code ID} value should be the same for all JVMs - * to support work with the same projection from execution to execution. - */ - public static final PurchaseOrderListId ID = PurchaseOrderListId.newBuilder() - .setValue( - "PurchaseOrderListViewProjectionSingleton") - .build(); - - /** - * Creates a new instance. - * - * @param id the ID for the new instance - * @throws IllegalArgumentException if the ID is not of one of the supported types - */ - public PurchaseOrderListViewProjection(PurchaseOrderListId id) { - super(id); - } - - @Subscribe - void on(PurchaseOrderSent event) { - final PurchaseOrderItem purchaseOrderItem = PurchaseOrderItem.newBuilder() - .setId(event.getPurchaseOrder() - .getId()) - .setPurchaseOrderStatus( - PurchaseOrderStatus.SENT) - .build(); - getBuilder().addPurchaseOrder(purchaseOrderItem); - } - - @Subscribe - void on(PurchaseOrderDelivered event) { - final PurchaseOrderItem purchaseOrderItem = PurchaseOrderItem.newBuilder() - .setId(event.getId()) - .setPurchaseOrderStatus( - PurchaseOrderStatus.DELIVERED) - .build(); - getBuilder().setPurchaseOrder(getPurchaseOrderItemById(event.getId()), purchaseOrderItem); - - } - - @Subscribe - void on(PurchaseOrderValidationFailed event) { - final PurchaseOrderItem purchaseOrderItem = PurchaseOrderItem.newBuilder() - .setId(event.getId()) - .setPurchaseOrderStatus( - PurchaseOrderStatus.INVALID) - .build(); - getBuilder().setPurchaseOrder(getPurchaseOrderItemById(event.getId()), purchaseOrderItem); - } - - private int getPurchaseOrderItemById(PurchaseOrderId id) { - final List orderList = getBuilder().getPurchaseOrder(); - final int index = IntStream.range(0, orderList.size()) - .filter(i -> orderList.get(i) - .getId() - .equals(id)) - .findFirst() - .getAsInt(); - return index; - } -} diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java index 4dcc357e..db1aeeef 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java @@ -21,6 +21,7 @@ package javaclasses.mealorder.q.projection; import javaclasses.mealorder.OrderListId; +import javaclasses.mealorder.c.event.DishAddedToOrder; import javaclasses.mealorder.q.OrderListViewProjection; import javaclasses.mealorder.testdata.TestValues; import org.junit.jupiter.api.BeforeEach; @@ -28,6 +29,10 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.OrderEvents.dishAddedToOrderInstance; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class OrderListViewProjectionTest extends ProjectionTest { private OrderListViewProjection projection; @@ -44,10 +49,34 @@ class DishAddedToOrderEvent { @Test @DisplayName("Should add dish to the order") - void addView() { -// final DishAddedToOrder dishAddedToOrder = dshAddedToOrderInstance(); -// dispatch(projection, createEvent(dishAddedToOrder)); + void addDish() { + final DishAddedToOrder dishAddedToOrder = dishAddedToOrderInstance(); + dispatch(projection, createEvent(dishAddedToOrder)); + + assertEquals(1, projection.getState() + .getOrderList() + .size()); + assertEquals("dishName1", projection.getState() + .getOrderList() + .get(0) + .getDishList() + .get(0) + .getName()); + } + + @Test + @DisplayName("Should add 3 dishes to the order") + void addThreeDishes() { + final DishAddedToOrder dishAddedToOrder = dishAddedToOrderInstance(); + dispatch(projection, createEvent(dishAddedToOrder)); + dispatch(projection, createEvent(dishAddedToOrder)); + dispatch(projection, createEvent(dishAddedToOrder)); + assertEquals(3, projection.getState() + .getOrderList() + .get(0) + .getDishList() + .size()); } } } diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java index 50f81c25..0ee38fdb 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java @@ -55,7 +55,7 @@ void setUp() { } @Nested - @DisplayName("PurchaseOrderSent event should be interpreted by PurchaseOrderListViewProjection") + @DisplayName("PurchaseOrderSent event should be interpreted by PurchaseOrderItemViewProjection") class PurchaseOrderSentEvent { @Test diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderItemViewProjectionTest.java similarity index 60% rename from api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java rename to api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderItemViewProjectionTest.java index 7ce4ced4..cc638362 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderItemViewProjectionTest.java @@ -20,31 +20,33 @@ package javaclasses.mealorder.q.projection; +import javaclasses.mealorder.PurchaseOrderListId; +import javaclasses.mealorder.PurchaseOrderStatus; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; -import javaclasses.mealorder.q.PurchaseOrderItem; -import javaclasses.mealorder.q.PurchaseOrderListViewProjection; +import javaclasses.mealorder.q.PurchaseOrderItemViewProjection; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import java.util.List; - import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderDeliveredInstance; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderSentInstance; import static org.junit.jupiter.api.Assertions.assertEquals; -public class PurchaseOrderListViewProjectionTest extends ProjectionTest { - private PurchaseOrderListViewProjection projection; + +public class PurchaseOrderItemViewProjectionTest extends ProjectionTest { + private PurchaseOrderItemViewProjection projection; @BeforeEach void setUp() { - projection = new PurchaseOrderListViewProjection(PurchaseOrderListViewProjection.ID); + projection = new PurchaseOrderItemViewProjection(PurchaseOrderListId.newBuilder() + .setValue("dsda") + .build()); } @Nested - @DisplayName("PurchaseOrderSent event should be interpreted by PurchaseOrderListViewProjection") + @DisplayName("PurchaseOrderSent event should be interpreted by PurchaseOrderItemViewProjection") class PurchaseOrderSentEvent { @Test @@ -53,18 +55,30 @@ void addView() { final PurchaseOrderSent purchaseOrderSent = purchaseOrderSentInstance(); dispatch(projection, createEvent(purchaseOrderSent)); - final List purchaseOrderList = projection.getState() - .getPurchaseOrderList(); - assertEquals(1, purchaseOrderList.size()); - assertEquals(15, purchaseOrderList.get(0) - .getId() - .getPoDate() - .getDay()); + assertEquals("vendor:value: \"VendorName1\"", projection.getState() + .getId() + .getVendorId() + .getValue() + .trim()); + assertEquals(15, projection.getState() + .getId() + .getPoDate() + .getDay()); + assertEquals(2019, projection.getState() + .getId() + .getPoDate() + .getYear()); + assertEquals(2, projection.getState() + .getId() + .getPoDate() + .getMonthValue()); + assertEquals(PurchaseOrderStatus.SENT, projection.getState() + .getPurchaseOrderStatus()); } } @Nested - @DisplayName("PurchaseOrderDelivered event should be interpreted by PurchaseOrderListViewProjection") + @DisplayName("PurchaseOrderDelivered event should be interpreted by PurchaseOrderItemViewProjection") class PurchaseOrderDeliveredEvent { @Test @@ -74,12 +88,8 @@ void addView() { dispatch(projection, createEvent(purchaseOrderSent)); final PurchaseOrderDelivered purchaseOrderDelivered = purchaseOrderDeliveredInstance(); dispatch(projection, createEvent(purchaseOrderDelivered)); - final List purchaseOrderList = projection.getState() - .getPurchaseOrderList(); - assertEquals(1, purchaseOrderList.size()); - assertEquals("DELIVERED", purchaseOrderList.get(0) - .getPurchaseOrderStatus() - .name()); + assertEquals(PurchaseOrderStatus.DELIVERED, projection.getState() + .getPurchaseOrderStatus()); } } } diff --git a/model/src/main/proto/javaclasses/mealorder/q/projections.proto b/model/src/main/proto/javaclasses/mealorder/q/projections.proto index b9e4c6e4..1fec8040 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/projections.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/projections.proto @@ -115,13 +115,13 @@ message VendorListView { // This view includes the list of all purchase orders, // sorted by date. // -message PurchaseOrderListView { +message PurchaseOrderItemView { - // The identifier of the purchase order list singleton. - PurchaseOrderListId purchase_order_list_id = 1; + // The identifier of a purchase order. + PurchaseOrderId id = 1 [(required) = true]; - // The collection of all purchase orders. - repeated PurchaseOrderItem purchase_order = 2; + // The purchase order status. + PurchaseOrderStatus purchase_order_status = 2 [(required) = true]; } // The projection state of a purchase order details view diff --git a/model/src/main/proto/javaclasses/mealorder/q/values.proto b/model/src/main/proto/javaclasses/mealorder/q/values.proto index 953da5c5..9a9147b9 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/values.proto @@ -136,17 +136,6 @@ message VendorItem { spine.time.LocalTime po_daily_deadline = 5 [(required) = true]; } -// The item of the purchase order list. -// -message PurchaseOrderItem { - - // The identifier of a purchase order. - PurchaseOrderId id = 1 [(required) = true]; - - // The purchase order status. - PurchaseOrderStatus purchase_order_status = 2 [(required) = true]; -} - // The item of an order list. // // Used in a purchase order details veiw grouped by User. diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java index 56745ae9..c0d7872c 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java @@ -26,12 +26,14 @@ import javaclasses.mealorder.MenuDateRange; import javaclasses.mealorder.MenuId; import javaclasses.mealorder.Order; +import javaclasses.mealorder.OrderId; import javaclasses.mealorder.PurchaseOrder; import javaclasses.mealorder.PurchaseOrderId; import javaclasses.mealorder.PurchaseOrderStatus; import javaclasses.mealorder.UserId; import javaclasses.mealorder.VendorId; import javaclasses.mealorder.c.event.DateRangeForMenuSet; +import javaclasses.mealorder.c.event.DishAddedToOrder; import javaclasses.mealorder.c.event.MenuImported; import javaclasses.mealorder.c.event.PurchaseOrderCreated; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; @@ -159,4 +161,25 @@ private static MenuImported menuImportedInstance(VendorId vendorId, MenuId menuI return result; } } + + public static class OrderEvents { + private OrderEvents() { + } + + public static DishAddedToOrder dishAddedToOrderInstance() { + return dishAddedToOrderInstance(TestValues.ORDER_ID, TestValues.DISH1); + } + + private static DishAddedToOrder dishAddedToOrderInstance(OrderId orderId, Dish dish) { + final Timestamp currentTime = getCurrentTime(); + final DishAddedToOrder result = + DishAddedToOrder.newBuilder() + .setOrderId(orderId) + .setDish(dish) + .setWhenAdded(currentTime) + .build(); + return result; + } + + } } From 132754ef3116d6478930b4e6abca78d2870d0a0b Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Tue, 24 Apr 2018 17:04:15 +0300 Subject: [PATCH 39/66] Add tests for `VendorListViewProjection` --- .../OrderListViewProjectionTest.java | 6 +++ .../VendorListViewProjectionTest.java | 42 +++++++++++++--- .../testdata/TestMealOrderEventFactory.java | 49 +++++++++++++++++++ .../mealorder/testdata/TestValues.java | 12 ++++- 4 files changed, 101 insertions(+), 8 deletions(-) diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java index db1aeeef..9e822f3b 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java @@ -77,6 +77,12 @@ void addThreeDishes() { .get(0) .getDishList() .size()); + assertEquals("dishName1", projection.getState() + .getOrderList() + .get(0) + .getDishList() + .get(2) + .getName()); } } } diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/VendorListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/VendorListViewProjectionTest.java index 349f4c83..6807f355 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/VendorListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/VendorListViewProjectionTest.java @@ -20,12 +20,19 @@ package javaclasses.mealorder.q.projection; +import javaclasses.mealorder.c.event.VendorAdded; +import javaclasses.mealorder.c.event.VendorUpdated; import javaclasses.mealorder.q.VendorListViewProjection; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.VendorEvents.vendorAddedInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.VendorEvents.vendorUpdatedInstance; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class VendorListViewProjectionTest extends ProjectionTest { private VendorListViewProjection projection; @@ -41,9 +48,21 @@ class VendorAddedEvent { @Test @DisplayName("Should add new vendor") void addView() { -// final VendorAdded vendorAdded = vendorAddedInstance(); -// dispatch(projection, createEvent(vendorAdded)); - + final VendorAdded vendorAdded = vendorAddedInstance(); + dispatch(projection, createEvent(vendorAdded)); + assertEquals(1, projection.getState() + .getVendorList() + .size()); + assertEquals("vendor1@example.com", projection.getState() + .getVendorList() + .get(0) + .getEmail() + .getValue()); + assertEquals("vendor:value: \"VendorName1\"", projection.getState() + .getVendorList() + .get(0) + .getId() + .getValue()); } } @@ -54,9 +73,20 @@ class VendorUpdatedEvent { @Test @DisplayName("Should update vendor") void addView() { -// final VendorUpdated vendorUpdated = VendorUpdatedInstance(); -// dispatch(projection, createEvent(vendorUpdated)); - + final VendorAdded vendorAdded = vendorAddedInstance(); + dispatch(projection, createEvent(vendorAdded)); + assertEquals("VendorName1", projection.getState() + .getVendorList() + .get(0) + .getVendorName() + .getValue()); + final VendorUpdated vendorUpdated = vendorUpdatedInstance(); + dispatch(projection, createEvent(vendorUpdated)); + assertEquals("VendorName2", projection.getState() + .getVendorList() + .get(0) + .getVendorName() + .getValue()); } } } diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java index c0d7872c..2f897af1 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java @@ -22,22 +22,28 @@ import com.google.protobuf.Timestamp; import io.spine.net.EmailAddress; +import io.spine.time.LocalTime; import javaclasses.mealorder.Dish; import javaclasses.mealorder.MenuDateRange; import javaclasses.mealorder.MenuId; import javaclasses.mealorder.Order; import javaclasses.mealorder.OrderId; +import javaclasses.mealorder.PhoneNumber; import javaclasses.mealorder.PurchaseOrder; import javaclasses.mealorder.PurchaseOrderId; import javaclasses.mealorder.PurchaseOrderStatus; import javaclasses.mealorder.UserId; +import javaclasses.mealorder.VendorChange; import javaclasses.mealorder.VendorId; +import javaclasses.mealorder.VendorName; import javaclasses.mealorder.c.event.DateRangeForMenuSet; import javaclasses.mealorder.c.event.DishAddedToOrder; import javaclasses.mealorder.c.event.MenuImported; import javaclasses.mealorder.c.event.PurchaseOrderCreated; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.c.event.VendorAdded; +import javaclasses.mealorder.c.event.VendorUpdated; import java.util.List; @@ -160,6 +166,49 @@ private static MenuImported menuImportedInstance(VendorId vendorId, MenuId menuI .build(); return result; } + + public static VendorAdded vendorAddedInstance() { + return vendorAddedInstance(TestValues.VENDOR_ID, TestValues.USER_ID, + TestValues.VENDOR_NAME, TestValues.EMAIL, + TestValues.PHONE_NUMBERS, TestValues.PO_DAILY_DEADLINE); + } + + private static VendorAdded vendorAddedInstance(VendorId vendorId, UserId userId, + VendorName vendorName, EmailAddress email, + List numbers, + LocalTime deadline) { + final Timestamp currentTime = getCurrentTime(); + final VendorAdded result = + VendorAdded.newBuilder() + .setVendorId(vendorId) + .setWhoAdded(userId) + .setWhenAdded(currentTime) + .setVendorName(vendorName) + .addAllPhoneNumber(numbers) + .setEmail(email) + .setPoDailyDeadline(deadline) + .build(); + return result; + } + + public static VendorUpdated vendorUpdatedInstance() { + return vendorUpdatedInstance(TestValues.VENDOR_ID, TestValues.USER_ID, + TestValues.VENDOR_CHANGE); + } + + private static VendorUpdated vendorUpdatedInstance(VendorId vendorId, UserId userId, + VendorChange vendorChange) { + final Timestamp currentTime = getCurrentTime(); + final VendorUpdated result = + VendorUpdated.newBuilder() + .setVendorId(vendorId) + .setWhoUploaded(userId) + .setVendorChange(vendorChange) + .setWhenUpdated(currentTime) + .build(); + return result; + } + } public static class OrderEvents { diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java index e2a2389f..9676252a 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java @@ -104,6 +104,7 @@ public class TestValues { public static final PhoneNumber PHONE_NUMBER2 = PhoneNumber.newBuilder() .setValue("0987654321") .build(); + public static final List PHONE_NUMBERS = getPhoneNumbers(); public static final VendorChange VENDOR_CHANGE = VendorChange.newBuilder() .setPreviousVendorName(VENDOR_NAME) @@ -199,9 +200,9 @@ public class TestValues { public static final MenuDateRange MENU_DATE_RANGE_FROM_PAST = MenuDateRange.newBuilder() .setRangeStart( - START_DATE_FROM_PAST) + START_DATE_FROM_PAST) .setRangeEnd( - END_DATE_FROM_PAST) + END_DATE_FROM_PAST) .build(); public static final Dish DISH1 = Dish.newBuilder() @@ -365,6 +366,13 @@ private static List createMenu() { return menu; } + private static List getPhoneNumbers() { + final List numbers = new ArrayList<>(); + numbers.add(PHONE_NUMBER1); + numbers.add(PHONE_NUMBER2); + return numbers; + } + private static List createOrder() { List orders = new ArrayList<>(); final Order order1 = Order.newBuilder() From 920dabf6cc34503877cdd981260969126d4d894f Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Tue, 24 Apr 2018 17:27:10 +0300 Subject: [PATCH 40/66] Add more use cases for `PurchaseOrderByUserView` --- ...chaseOrderDetailsByUserViewProjection.java | 1 + ...eOrderDetailsByUserViewProjectionTest.java | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java index 8cb0cbaa..b05cb3d8 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java @@ -89,6 +89,7 @@ private List getUserOrders(PurchaseOrderCreated event) { .getId() .getUserId()) .addAllDish(dishItems) + .setIsValid(true) .build(); dishes.add(dish); } diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java index 0ee38fdb..0a07f2ab 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java @@ -22,8 +22,10 @@ import io.spine.time.LocalDate; import javaclasses.mealorder.PurchaseOrderId; +import javaclasses.mealorder.PurchaseOrderStatus; import javaclasses.mealorder.VendorId; import javaclasses.mealorder.c.event.PurchaseOrderCreated; +import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.q.PurchaseOrderDetailsByUserViewProjection; import javaclasses.mealorder.q.UserOrderDetails; import org.junit.jupiter.api.BeforeEach; @@ -35,6 +37,8 @@ import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderCreatedInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderDeliveredInstance; +import static org.junit.jupiter.api.Assertions.assertEquals; public class PurchaseOrderDetailsByUserViewProjectionTest extends ProjectionTest { private PurchaseOrderDetailsByUserViewProjection projection; @@ -65,6 +69,39 @@ void addView() { dispatch(projection, createEvent(purchaseOrderCreated)); final List orderList = projection.getState() .getOrderList(); + assertEquals(2, orderList.size()); + assertEquals("user@example.com", orderList.get(0) + .getId() + .getEmail() + .getValue()); + assertEquals("petr@example.com", orderList.get(1) + .getId() + .getEmail() + .getValue()); + assertEquals(true, orderList.get(0) + .getIsValid()); + assertEquals(5, orderList.get(0) + .getDishList() + .size()); + assertEquals(8, orderList.get(1) + .getDishList() + .size()); + } + } + + @Nested + @DisplayName("PurchaseOrderDelivered event should be interpreted") + class PurchaseOrderDeliveredEvent { + + @Test + @DisplayName("Should change status") + void addView() { + final PurchaseOrderCreated purchaseOrderCreated = purchaseOrderCreatedInstance(); + dispatch(projection, createEvent(purchaseOrderCreated)); + final PurchaseOrderDelivered purchaseOrderDelivered = purchaseOrderDeliveredInstance(); + dispatch(projection, createEvent(purchaseOrderDelivered)); + assertEquals(PurchaseOrderStatus.DELIVERED, projection.getState() + .getPurchaseOrderStatus()); } } } From d791242e3f0520352203da9463d6b917c93a3c31 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 25 Apr 2018 11:08:08 +0300 Subject: [PATCH 41/66] Date to disable menu now is taken from event ID --- .../mealorder/q/MenuListViewProjection.java | 11 ++++---- .../javaclasses/mealorder/q/Projections.java | 20 ++++++++++++++- .../MenuListViewProjectionTest.java | 25 +++++++++++++++++++ .../VendorListViewProjectionTest.java | 3 ++- .../testdata/TestMealOrderEventFactory.java | 4 +++ .../mealorder/testdata/TestValues.java | 15 ++++++++++- 6 files changed, 69 insertions(+), 9 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java index c9d7f196..5192057a 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java @@ -20,7 +20,6 @@ package javaclasses.mealorder.q; -import com.google.protobuf.Timestamp; import io.spine.core.Subscribe; import io.spine.server.projection.Projection; import io.spine.time.LocalDate; @@ -42,7 +41,6 @@ import java.util.stream.IntStream; import static javaclasses.mealorder.q.Projections.getDatesBetween; -import static javaclasses.mealorder.q.Projections.timeStampToLocalDate; public class MenuListViewProjection extends Projection { @@ -102,14 +100,15 @@ void on(DateRangeForMenuSet event) { @Subscribe void on(PurchaseOrderCreated event) { - final List newMenu = getBuilder().getMenu(); + final List newMenu = new ArrayList<>(getBuilder().getMenu()); for (int i = 0; i < newMenu.size(); i++) { final MenuItem menuItem = newMenu.get(i); - final List menuDaysList = menuItem.getMenuDaysList(); + final List menuDaysList = new ArrayList<>(menuItem.getMenuDaysList()); + final LocalDate date = event.getId() + .getPoDate(); for (int j = 0; j < menuDaysList.size(); j++) { final MenuForDay menuForDay = menuDaysList.get(j); - final Timestamp whenCreated = event.getWhenCreated(); - final LocalDate date = timeStampToLocalDate(whenCreated); + if (menuForDay.getDate() .equals(date)) { final MenuForDay newMenuForDay = MenuForDay.newBuilder() diff --git a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java index 7078ec8c..e6136a1b 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java @@ -22,12 +22,16 @@ import com.google.protobuf.Timestamp; import io.spine.time.LocalDate; +import io.spine.time.MonthOfYear; import java.time.temporal.ChronoUnit; +import java.util.Calendar; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; +import static io.spine.time.Timestamps2.toDate; + final class Projections { /** @@ -60,6 +64,20 @@ static LocalDate toLocalDate(java.time.LocalDate date) { } static LocalDate timeStampToLocalDate(Timestamp timestamp) { - return null; + final Calendar calendar = Calendar.getInstance(); + calendar.setTime(toDate(timestamp)); + final LocalDate localDate = calendarToLocalDate(calendar); + return localDate; + } + + private static LocalDate calendarToLocalDate(Calendar calendar) { + final LocalDate date = LocalDate.newBuilder() + .setDay(calendar.get(Calendar.DAY_OF_MONTH)) + .setMonth( + MonthOfYear.valueOf( + calendar.get(Calendar.MONTH) + 1)) + .setYear(calendar.get(Calendar.YEAR)) + .build(); + return date; } } diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java index b351d358..9aac0657 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java @@ -23,6 +23,7 @@ import javaclasses.mealorder.MenuListId; import javaclasses.mealorder.c.event.DateRangeForMenuSet; import javaclasses.mealorder.c.event.MenuImported; +import javaclasses.mealorder.c.event.PurchaseOrderCreated; import javaclasses.mealorder.q.MenuListViewProjection; import javaclasses.mealorder.testdata.TestValues; import org.junit.jupiter.api.BeforeEach; @@ -31,8 +32,10 @@ import org.junit.jupiter.api.Test; import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderCreatedInstance2; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.VendorEvents.dateRangeForMenuSetInstance; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.VendorEvents.menuImportedInstance; +import static org.junit.jupiter.api.Assertions.assertEquals; public class MenuListViewProjectionTest extends ProjectionTest { private MenuListViewProjection projection; @@ -67,5 +70,27 @@ void addView() { dispatch(projection, createEvent(dateRangeForMenuSet)); } } + + @Nested + @DisplayName("PurchaseOrderCreated event should be interpreted by MenuListViewProjection") + class PurchaseOrderCreatedEvent { + @Test + @DisplayName("Should disable menu") + void addView() { + final MenuImported menuImported = menuImportedInstance(); + dispatch(projection, createEvent(menuImported)); + final DateRangeForMenuSet dateRangeForMenuSet = dateRangeForMenuSetInstance(); + dispatch(projection, createEvent(dateRangeForMenuSet)); + final PurchaseOrderCreated purchaseOrderCreated = purchaseOrderCreatedInstance2(); + dispatch(projection, createEvent(purchaseOrderCreated)); + + assertEquals(false, projection.getState() + .getMenuList() + .get(0) + .getMenuDaysList() + .get(18) + .getIsAvailable()); + } + } } diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/VendorListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/VendorListViewProjectionTest.java index 6807f355..bd53b1ec 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/VendorListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/VendorListViewProjectionTest.java @@ -62,7 +62,8 @@ void addView() { .getVendorList() .get(0) .getId() - .getValue()); + .getValue() + .trim()); } } diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java index 2f897af1..6566d6db 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java @@ -108,6 +108,10 @@ public static PurchaseOrderCreated purchaseOrderCreatedInstance() { TestValues.BIG_ORDER); } + public static PurchaseOrderCreated purchaseOrderCreatedInstance2() { + return purchaseOrderCreatedInstance(TestValues.PURCHASE_ORDER_ID2, TestValues.USER_ID, + TestValues.BIG_ORDER); + } public static PurchaseOrderCreated purchaseOrderCreatedInstance( PurchaseOrderId purchaseOrderId, UserId userId, List orders) { diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java index 9676252a..c8365f06 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java @@ -42,6 +42,7 @@ import java.util.List; import static io.spine.time.MonthOfYear.FEBRUARY; +import static io.spine.time.MonthOfYear.MARCH; import static io.spine.time.Time.getCurrentTime; import static javaclasses.mealorder.OrderStatus.ORDER_ACTIVE; @@ -304,6 +305,14 @@ public class TestValues { .setDay(15) .build(); + public static final LocalDate DATE2 = LocalDate.newBuilder() + .setYear( + 2017) + .setMonth( + MARCH) + .setDay(3) + .build(); + public static final OrderId ORDER_ID = OrderId.newBuilder() .setUserId(USER_ID) .setVendorId(VENDOR_ID) @@ -345,7 +354,11 @@ public class TestValues { .setVendorId(VENDOR_ID) .setPoDate(DATE) .build(); - + public static final PurchaseOrderId PURCHASE_ORDER_ID2 = PurchaseOrderId + .newBuilder() + .setVendorId(VENDOR_ID) + .setPoDate(DATE2) + .build(); public static final Order ORDER = Order.newBuilder() .setId(ORDER_ID) .addDish(DISH1) From 8bb1b5cc02ce4f57dab560f5978d3e767c599018 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 25 Apr 2018 11:12:33 +0300 Subject: [PATCH 42/66] Delete util methods that worked with dates --- .../javaclasses/mealorder/q/Projections.java | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java index e6136a1b..8d96d55c 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java @@ -20,18 +20,13 @@ package javaclasses.mealorder.q; -import com.google.protobuf.Timestamp; import io.spine.time.LocalDate; -import io.spine.time.MonthOfYear; import java.time.temporal.ChronoUnit; -import java.util.Calendar; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; -import static io.spine.time.Timestamps2.toDate; - final class Projections { /** @@ -62,22 +57,4 @@ static LocalDate toLocalDate(java.time.LocalDate date) { .setYear(date.getYear()) .build(); } - - static LocalDate timeStampToLocalDate(Timestamp timestamp) { - final Calendar calendar = Calendar.getInstance(); - calendar.setTime(toDate(timestamp)); - final LocalDate localDate = calendarToLocalDate(calendar); - return localDate; - } - - private static LocalDate calendarToLocalDate(Calendar calendar) { - final LocalDate date = LocalDate.newBuilder() - .setDay(calendar.get(Calendar.DAY_OF_MONTH)) - .setMonth( - MonthOfYear.valueOf( - calendar.get(Calendar.MONTH) + 1)) - .setYear(calendar.get(Calendar.YEAR)) - .build(); - return date; - } } From 59c0bf197724c2f0763da34b567c3d5f40da9d01 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 25 Apr 2018 11:37:46 +0300 Subject: [PATCH 43/66] Add for event instances for tests --- ...chaseOrderDetailsByDishViewProjection.java | 1 + ...chaseOrderDetailsByUserViewProjection.java | 1 + .../testdata/TestMealOrderEventFactory.java | 49 +++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java index 15e57e03..0ef19600 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java @@ -70,6 +70,7 @@ void on(PurchaseOrderSent event) { @Subscribe void on(PurchaseOrderValidationFailed event) { getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.INVALID); + //todo : set what failed } private List getDishItems(List orderList) { diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java index b05cb3d8..18bbf1fb 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java @@ -68,6 +68,7 @@ void on(PurchaseOrderSent event) { @Subscribe void on(PurchaseOrderValidationFailed event) { getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.INVALID); + //todo set which failed } private List getUserOrders(PurchaseOrderCreated event) { diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java index 6566d6db..9be8d85b 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java @@ -39,9 +39,12 @@ import javaclasses.mealorder.c.event.DateRangeForMenuSet; import javaclasses.mealorder.c.event.DishAddedToOrder; import javaclasses.mealorder.c.event.MenuImported; +import javaclasses.mealorder.c.event.OrderCanceled; +import javaclasses.mealorder.c.event.OrderProcessed; import javaclasses.mealorder.c.event.PurchaseOrderCreated; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.c.event.PurchaseOrderValidationFailed; import javaclasses.mealorder.c.event.VendorAdded; import javaclasses.mealorder.c.event.VendorUpdated; @@ -67,6 +70,23 @@ public static class PurchaseOrderEvents { private PurchaseOrderEvents() { } + public static PurchaseOrderValidationFailed purchaseOrderValidationFailedInstance() { + return purchaseOrderValidationFailedInstance(TestValues.PURCHASE_ORDER_ID, + TestValues.ORDER); + } + + public static PurchaseOrderValidationFailed purchaseOrderValidationFailedInstance( + PurchaseOrderId purchaseOrderId, Order order) { + final Timestamp currentTime = getCurrentTime(); + final PurchaseOrderValidationFailed result = + PurchaseOrderValidationFailed.newBuilder() + .setId(purchaseOrderId) + .addFailureOrder(order) + .setWhenFailed(currentTime) + .build(); + return result; + } + public static PurchaseOrderSent purchaseOrderSentInstance() { return purchaseOrderSentInstance(PURCHASE_ORDER, TestValues.USER_ID.getEmail(), TestValues.EMAIL); @@ -112,6 +132,7 @@ public static PurchaseOrderCreated purchaseOrderCreatedInstance2() { return purchaseOrderCreatedInstance(TestValues.PURCHASE_ORDER_ID2, TestValues.USER_ID, TestValues.BIG_ORDER); } + public static PurchaseOrderCreated purchaseOrderCreatedInstance( PurchaseOrderId purchaseOrderId, UserId userId, List orders) { @@ -234,5 +255,33 @@ private static DishAddedToOrder dishAddedToOrderInstance(OrderId orderId, Dish d return result; } + public static OrderCanceled orderCanceledInstance() { + return orderCanceledInstance(TestValues.ORDER_ID, TestValues.USER_ID); + } + + private static OrderCanceled orderCanceledInstance(OrderId orderId, UserId userId) { + final Timestamp currentTime = getCurrentTime(); + final OrderCanceled result = + OrderCanceled.newBuilder() + .setOrderId(orderId) + .setWhoCanceled(userId) + .setWhenCanceled(currentTime) + .build(); + return result; + } + + public static OrderProcessed orderProcessedInstance() { + return orderProcessedInstance(TestValues.ORDER); + } + + private static OrderProcessed orderProcessedInstance(Order order) { + final Timestamp currentTime = getCurrentTime(); + final OrderProcessed result = + OrderProcessed.newBuilder() + .setOrder(order) + .setWhenProcessed(currentTime) + .build(); + return result; + } } } From e4c2668553919c8e6f1492ccb64eda55bcbe568b Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 25 Apr 2018 11:53:26 +0300 Subject: [PATCH 44/66] Invalid PO now sets separate records invalid --- ...chaseOrderDetailsByUserViewProjection.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java index 18bbf1fb..3d3222a5 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java @@ -35,6 +35,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.stream.IntStream; public class PurchaseOrderDetailsByUserViewProjection extends Projection { @@ -68,9 +69,21 @@ void on(PurchaseOrderSent event) { @Subscribe void on(PurchaseOrderValidationFailed event) { getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.INVALID); - //todo set which failed + event.getFailureOrderList() + .forEach(order -> { + final UserId userId = order.getId() + .getUserId(); + final int index = getOrderIndexByUserId(userId); + final UserOrderDetails newOrder = UserOrderDetails.newBuilder( + getBuilder().getOrder() + .get(index)) + .setIsValid(false) + .build(); + getBuilder().setOrder(index, newOrder); + }); } + private List getUserOrders(PurchaseOrderCreated event) { final List dishes = new ArrayList<>(); for (int i = 0; i < event.getOrderList() @@ -125,4 +138,15 @@ private List getDishItemsForUser(UserId user, List orderList) { }); return dishItems; } + + private int getOrderIndexByUserId(UserId userId) { + final List orders = getState().getOrderList(); + final int index = IntStream.range(0, orders.size()) + .filter(i -> orders.get(i) + .getId() + .equals(userId)) + .findFirst() + .getAsInt(); + return index; + } } From 29c8072ae46313eeca5d5a6c2260daa13d1dd058 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 25 Apr 2018 12:32:41 +0300 Subject: [PATCH 45/66] Add `DishRemoved` event instance for tests --- ...urchaseOrderDetailsByDishViewProjection.java | 1 - .../testdata/TestMealOrderEventFactory.java | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java index 0ef19600..15e57e03 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java @@ -70,7 +70,6 @@ void on(PurchaseOrderSent event) { @Subscribe void on(PurchaseOrderValidationFailed event) { getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.INVALID); - //todo : set what failed } private List getDishItems(List orderList) { diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java index 9be8d85b..935b7bd6 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java @@ -38,6 +38,7 @@ import javaclasses.mealorder.VendorName; import javaclasses.mealorder.c.event.DateRangeForMenuSet; import javaclasses.mealorder.c.event.DishAddedToOrder; +import javaclasses.mealorder.c.event.DishRemovedFromOrder; import javaclasses.mealorder.c.event.MenuImported; import javaclasses.mealorder.c.event.OrderCanceled; import javaclasses.mealorder.c.event.OrderProcessed; @@ -283,5 +284,21 @@ private static OrderProcessed orderProcessedInstance(Order order) { .build(); return result; } + + public static DishRemovedFromOrder dishRemovedFromOrderInstance() { + return dishRemovedFromOrderInstance(TestValues.ORDER_ID, TestValues.DISH1); + } + + private static DishRemovedFromOrder dishRemovedFromOrderInstance(OrderId orderId, + Dish dish) { + final Timestamp currentTime = getCurrentTime(); + final DishRemovedFromOrder result = + DishRemovedFromOrder.newBuilder() + .setOrderId(orderId) + .setDish(dish) + .setWhenRemoved(currentTime) + .build(); + return result; + } } } From f82c14bb1af6c63b2a454a634fb3ac4b69dffefd Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 25 Apr 2018 12:51:44 +0300 Subject: [PATCH 46/66] Add `DishRemoved` test --- .../OrderListViewProjectionTest.java | 41 +++++++++++++++++++ .../testdata/TestMealOrderEventFactory.java | 3 ++ .../mealorder/testdata/TestValues.java | 5 +++ 3 files changed, 49 insertions(+) diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java index 9e822f3b..36be8c0f 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java @@ -31,6 +31,7 @@ import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.OrderEvents.dishAddedToOrderInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.OrderEvents.dishAddedToOrderInstance2; import static org.junit.jupiter.api.Assertions.assertEquals; public class OrderListViewProjectionTest extends ProjectionTest { @@ -85,4 +86,44 @@ void addThreeDishes() { .getName()); } } + + @Test + @DisplayName("Should add 2 dishes to different orders") + void addThreeDishes() { + final DishAddedToOrder dishAddedToOrder = dishAddedToOrderInstance(); + dispatch(projection, createEvent(dishAddedToOrder)); + final DishAddedToOrder dishAddedToOrder2 = dishAddedToOrderInstance2(); + dispatch(projection, createEvent(dishAddedToOrder2)); + + assertEquals(2, projection.getState() + .getOrderList() + .size()); + assertEquals(1, projection.getState() + .getOrderList() + .get(1) + .getDishList() + .size()); + assertEquals("dishName1", projection.getState() + .getOrderList() + .get(0) + .getDish(0) + .getName()); + assertEquals("dishName2", projection.getState() + .getOrderList() + .get(1) + .getDish(0) + .getName()); + } + + @Test + @DisplayName("Should remove 1 dish from order") + void remove() { + final DishAddedToOrder dishAddedToOrder = dishAddedToOrderInstance(); + dispatch(projection, createEvent(dishAddedToOrder)); +// dispatch(projection, createEvent(dishAddedToOrder)); +// final DishRemovedFromOrder dishRemovedFromOrder=dishRemovedFromOrderInstance(); +// dispatch(projection, createEvent(dishRemovedFromOrder)); +// assertEquals(1, projection.getState() +// .getOrderList().get(0).getDishList().size()); + } } diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java index 935b7bd6..a16df08e 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java @@ -245,6 +245,9 @@ public static DishAddedToOrder dishAddedToOrderInstance() { return dishAddedToOrderInstance(TestValues.ORDER_ID, TestValues.DISH1); } + public static DishAddedToOrder dishAddedToOrderInstance2() { + return dishAddedToOrderInstance(TestValues.ORDER_ID2, TestValues.DISH2); + } private static DishAddedToOrder dishAddedToOrderInstance(OrderId orderId, Dish dish) { final Timestamp currentTime = getCurrentTime(); final DishAddedToOrder result = diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java index c8365f06..8ad00ff4 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java @@ -318,6 +318,11 @@ public class TestValues { .setVendorId(VENDOR_ID) .setOrderDate(DATE) .build(); + public static final OrderId ORDER_ID2 = OrderId.newBuilder() + .setUserId(USER_ID2) + .setVendorId(VENDOR_ID2) + .setOrderDate(DATE) + .build(); public static final VendorId INVALID_VENDOR_ID = VendorId.newBuilder() .setValue("vendor:INVALID") From 3feeb21c67c88c1185249cf8d0abc2ad650f8496 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 25 Apr 2018 13:41:35 +0300 Subject: [PATCH 47/66] Refactor finding dish logic in `OrderListViewProjection` --- .../q/MenuCalendarViewProjection.java | 1 - .../MonthlySpendingsReportViewProjection.java | 19 +++++++++++- .../mealorder/q/OrderListViewProjection.java | 26 ++++++++++++----- .../OrderListViewProjectionTest.java | 29 +++++++++++++++---- 4 files changed, 59 insertions(+), 16 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java index 0e788df5..d0372ffb 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java @@ -23,7 +23,6 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; import javaclasses.mealorder.MenuCalendarId; -import javaclasses.mealorder.MenuDateRange; import javaclasses.mealorder.c.event.DateRangeForMenuSet; import javaclasses.mealorder.q.projection.MenuCalendarView; import javaclasses.mealorder.q.projection.MenuCalendarViewVBuilder; diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java index e674450f..d6b4aae8 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java @@ -23,8 +23,9 @@ import io.spine.core.Subscribe; import io.spine.money.Money; import io.spine.server.projection.Projection; -import javaclasses.mealorder.MonthlySpendingsReportId; import javaclasses.mealorder.Dish; +import javaclasses.mealorder.LocalMonth; +import javaclasses.mealorder.MonthlySpendingsReportId; import javaclasses.mealorder.Order; import javaclasses.mealorder.PurchaseOrder; import javaclasses.mealorder.UserId; @@ -50,6 +51,22 @@ public MonthlySpendingsReportViewProjection(MonthlySpendingsReportId id) { @Subscribe void on(PurchaseOrderSent event) { + if (getBuilder().getReportId() == null) { + final LocalMonth localMonth = LocalMonth.newBuilder() + .setMonth(event.getPurchaseOrder() + .getId() + .getPoDate() + .getMonth()) + .setYear(event.getPurchaseOrder() + .getId() + .getPoDate() + .getYear()) + .build(); + final MonthlySpendingsReportId reportId = MonthlySpendingsReportId.newBuilder() + .setMonth(localMonth) + .build(); + getBuilder().setReportId(reportId); + } final PurchaseOrder purchaseOrder = event.getPurchaseOrder(); final List userOrderDetailsList = new ArrayList<>(); final List dishItemList = new ArrayList<>(); diff --git a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java index e6a00a6b..ef4a35c5 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java @@ -22,7 +22,7 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; -import javaclasses.mealorder.Dish; +import javaclasses.mealorder.DishId; import javaclasses.mealorder.OrderId; import javaclasses.mealorder.OrderListId; import javaclasses.mealorder.c.event.DishAddedToOrder; @@ -59,6 +59,8 @@ void on(DishAddedToOrder event) { .getName()) .setPrice(event.getDish() .getPrice()) + .setId(event.getDish() + .getId()) .build(); if (getOrderById(orderId).isPresent()) { final OrderListId listId = OrderListId.newBuilder() @@ -84,12 +86,13 @@ void on(DishAddedToOrder event) { @Subscribe void on(DishRemovedFromOrder event) { final List orderItems = getBuilder().getOrder(); - final int removeIndex = getDishFromOrder(event.getDish(), - getOrderById(event.getOrderId()).get()); + final int removeIndex = getDishIndexFromOrder(event.getDish() + .getId(), + getOrderById(event.getOrderId()).get()); final OrderItem newOrder = OrderItem.newBuilder(getOrderById(event.getOrderId()).get()) .removeDish(removeIndex) .build(); - getBuilder().setOrder(orderItems.indexOf(getOrderById(event.getOrderId())), newOrder); + getBuilder().setOrder(orderItems.indexOf(getOrderById(event.getOrderId()).get()), newOrder); } @Subscribe @@ -100,7 +103,6 @@ void on(OrderCanceled event) { } @Subscribe - void on(OrderProcessed event) { final OrderItem order = getOrderById(event.getOrder() .getId()).get(); @@ -120,9 +122,17 @@ private Optional getOrderById(OrderId orderId) { return inventoryItem; } - private int getDishFromOrder(Dish dish, OrderItem order) { - return order.getDishList() - .indexOf(dish); + private int getDishIndexFromOrder(DishId dishId, OrderItem order) { + final int[] index = {-1}; + order.getDishList() + .forEach(dishItem -> { + if (dishItem.getId() + .equals(dishId)) { + index[0] = order.getDishList() + .indexOf(dishItem); + } + }); + return index[0]; } } diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java index 36be8c0f..9229649f 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java @@ -22,6 +22,7 @@ import javaclasses.mealorder.OrderListId; import javaclasses.mealorder.c.event.DishAddedToOrder; +import javaclasses.mealorder.c.event.DishRemovedFromOrder; import javaclasses.mealorder.q.OrderListViewProjection; import javaclasses.mealorder.testdata.TestValues; import org.junit.jupiter.api.BeforeEach; @@ -32,6 +33,7 @@ import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.OrderEvents.dishAddedToOrderInstance; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.OrderEvents.dishAddedToOrderInstance2; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.OrderEvents.dishRemovedFromOrderInstance; import static org.junit.jupiter.api.Assertions.assertEquals; public class OrderListViewProjectionTest extends ProjectionTest { @@ -116,14 +118,29 @@ void addThreeDishes() { } @Test - @DisplayName("Should remove 1 dish from order") + @DisplayName("Should remove 1 dish from the correct order") void remove() { final DishAddedToOrder dishAddedToOrder = dishAddedToOrderInstance(); dispatch(projection, createEvent(dishAddedToOrder)); -// dispatch(projection, createEvent(dishAddedToOrder)); -// final DishRemovedFromOrder dishRemovedFromOrder=dishRemovedFromOrderInstance(); -// dispatch(projection, createEvent(dishRemovedFromOrder)); -// assertEquals(1, projection.getState() -// .getOrderList().get(0).getDishList().size()); + dispatch(projection, createEvent(dishAddedToOrder)); + final DishAddedToOrder dishAddedToOrder2 = dishAddedToOrderInstance2(); + dispatch(projection, createEvent(dishAddedToOrder2)); + assertEquals(2, projection.getState() + .getOrderList() + .get(0) + .getDishList() + .size()); + final DishRemovedFromOrder dishRemovedFromOrder = dishRemovedFromOrderInstance(); + dispatch(projection, createEvent(dishRemovedFromOrder)); + assertEquals(1, projection.getState() + .getOrderList() + .get(0) + .getDishList() + .size()); + assertEquals(1, projection.getState() + .getOrderList() + .get(1) + .getDishList() + .size()); } } From f05f5c66c66a143b70fe440218b849bd13b8bef3 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 25 Apr 2018 13:55:20 +0300 Subject: [PATCH 48/66] Add tests for `DishProcessed` and `RemoveOrder` --- .../OrderListViewProjectionTest.java | 141 +++++++++++------- 1 file changed, 91 insertions(+), 50 deletions(-) diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java index 9229649f..fab40ee0 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java @@ -23,6 +23,8 @@ import javaclasses.mealorder.OrderListId; import javaclasses.mealorder.c.event.DishAddedToOrder; import javaclasses.mealorder.c.event.DishRemovedFromOrder; +import javaclasses.mealorder.c.event.OrderCanceled; +import javaclasses.mealorder.c.event.OrderProcessed; import javaclasses.mealorder.q.OrderListViewProjection; import javaclasses.mealorder.testdata.TestValues; import org.junit.jupiter.api.BeforeEach; @@ -34,6 +36,8 @@ import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.OrderEvents.dishAddedToOrderInstance; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.OrderEvents.dishAddedToOrderInstance2; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.OrderEvents.dishRemovedFromOrderInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.OrderEvents.orderCanceledInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.OrderEvents.orderProcessedInstance; import static org.junit.jupiter.api.Assertions.assertEquals; public class OrderListViewProjectionTest extends ProjectionTest { @@ -87,60 +91,97 @@ void addThreeDishes() { .get(2) .getName()); } + + @Test + @DisplayName("Should add 2 dishes to different orders") + void addTwoDishes() { + final DishAddedToOrder dishAddedToOrder = dishAddedToOrderInstance(); + dispatch(projection, createEvent(dishAddedToOrder)); + final DishAddedToOrder dishAddedToOrder2 = dishAddedToOrderInstance2(); + dispatch(projection, createEvent(dishAddedToOrder2)); + + assertEquals(2, projection.getState() + .getOrderList() + .size()); + assertEquals(1, projection.getState() + .getOrderList() + .get(1) + .getDishList() + .size()); + assertEquals("dishName1", projection.getState() + .getOrderList() + .get(0) + .getDish(0) + .getName()); + assertEquals("dishName2", projection.getState() + .getOrderList() + .get(1) + .getDish(0) + .getName()); + } } - @Test - @DisplayName("Should add 2 dishes to different orders") - void addThreeDishes() { - final DishAddedToOrder dishAddedToOrder = dishAddedToOrderInstance(); - dispatch(projection, createEvent(dishAddedToOrder)); - final DishAddedToOrder dishAddedToOrder2 = dishAddedToOrderInstance2(); - dispatch(projection, createEvent(dishAddedToOrder2)); + @Nested + @DisplayName("DishAddedToOrder event should be interpreted by OrderListViewProjection") + class DishRemovedFromOrderEvent { + @Test + @DisplayName("Should remove 1 dish from the correct order") + void remove() { + final DishAddedToOrder dishAddedToOrder = dishAddedToOrderInstance(); + dispatch(projection, createEvent(dishAddedToOrder)); + dispatch(projection, createEvent(dishAddedToOrder)); + final DishAddedToOrder dishAddedToOrder2 = dishAddedToOrderInstance2(); + dispatch(projection, createEvent(dishAddedToOrder2)); + assertEquals(2, projection.getState() + .getOrderList() + .get(0) + .getDishList() + .size()); + final DishRemovedFromOrder dishRemovedFromOrder = dishRemovedFromOrderInstance(); + dispatch(projection, createEvent(dishRemovedFromOrder)); + assertEquals(1, projection.getState() + .getOrderList() + .get(0) + .getDishList() + .size()); + assertEquals(1, projection.getState() + .getOrderList() + .get(1) + .getDishList() + .size()); + } + } - assertEquals(2, projection.getState() - .getOrderList() - .size()); - assertEquals(1, projection.getState() - .getOrderList() - .get(1) - .getDishList() - .size()); - assertEquals("dishName1", projection.getState() - .getOrderList() - .get(0) - .getDish(0) - .getName()); - assertEquals("dishName2", projection.getState() - .getOrderList() - .get(1) - .getDish(0) - .getName()); + @Nested + @DisplayName("OrderCanceled event should be interpreted by OrderListViewProjection") + class OrderCanceledEvent { + @Test + @DisplayName("Should remove correct order ") + void remove() { + final DishAddedToOrder dishAddedToOrder = dishAddedToOrderInstance(); + dispatch(projection, createEvent(dishAddedToOrder)); + final OrderCanceled orderCanceled = orderCanceledInstance(); + dispatch(projection, createEvent(orderCanceled)); + assertEquals(0, projection.getState() + .getOrderList() + .size()); + } } - @Test - @DisplayName("Should remove 1 dish from the correct order") - void remove() { - final DishAddedToOrder dishAddedToOrder = dishAddedToOrderInstance(); - dispatch(projection, createEvent(dishAddedToOrder)); - dispatch(projection, createEvent(dishAddedToOrder)); - final DishAddedToOrder dishAddedToOrder2 = dishAddedToOrderInstance2(); - dispatch(projection, createEvent(dishAddedToOrder2)); - assertEquals(2, projection.getState() - .getOrderList() - .get(0) - .getDishList() - .size()); - final DishRemovedFromOrder dishRemovedFromOrder = dishRemovedFromOrderInstance(); - dispatch(projection, createEvent(dishRemovedFromOrder)); - assertEquals(1, projection.getState() - .getOrderList() - .get(0) - .getDishList() - .size()); - assertEquals(1, projection.getState() - .getOrderList() - .get(1) - .getDishList() - .size()); + @Nested + @DisplayName("OrderProcessed event should be interpreted by OrderListViewProjection") + class OrderProcessedEvent { + @Test + @DisplayName("Should process correct order") + void remove() { + final DishAddedToOrder dishAddedToOrder = dishAddedToOrderInstance(); + dispatch(projection, createEvent(dishAddedToOrder)); + final OrderProcessed orderProcessed = orderProcessedInstance(); + dispatch(projection, createEvent(orderProcessed)); + assertEquals(true, projection.getState() + .getOrderList() + .get(0) + .getIsProcessed()); + } } } From 997cd24eff29fe71e0e960fa47ca203844c0cd64 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 25 Apr 2018 13:57:36 +0300 Subject: [PATCH 49/66] Delete `Enricher` from `BoundedContext` --- .../javaclasses/mealorder/c/BoundedContexts.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java b/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java index ee78c9c6..74684f35 100644 --- a/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java +++ b/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java @@ -21,8 +21,6 @@ package javaclasses.mealorder.c; import io.spine.server.BoundedContext; -import io.spine.server.event.EventBus; -import io.spine.server.event.EventEnricher; import io.spine.server.storage.StorageFactory; import io.spine.server.storage.memory.InMemoryStorageFactory; import javaclasses.mealorder.c.order.OrderRepository; @@ -100,16 +98,4 @@ public static BoundedContext createBoundedContext(StorageFactory storageFactory) .setName(NAME) .build(); } - - private static EventBus.Builder createEventBus(StorageFactory storageFactory, - PurchaseOrderRepository poRepository) { - final EventEnricher enricher = MealOrderEnrichments.newBuilder() - .setPurchaseOrderRepository(poRepository) - .build() - .createEnricher(); - final EventBus.Builder eventBus = EventBus.newBuilder() - .setEnricher(enricher) - .setStorageFactory(storageFactory); - return eventBus; - } } From a857686b11e7866693b8a05c8dd407030921a879 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 25 Apr 2018 13:59:24 +0300 Subject: [PATCH 50/66] Delete `MealOrderEnrichments` file` --- .../mealorder/c/MealOrderEnrichments.java | 105 ------------------ 1 file changed, 105 deletions(-) delete mode 100644 api-java/src/main/java/javaclasses/mealorder/c/MealOrderEnrichments.java diff --git a/api-java/src/main/java/javaclasses/mealorder/c/MealOrderEnrichments.java b/api-java/src/main/java/javaclasses/mealorder/c/MealOrderEnrichments.java deleted file mode 100644 index 4909ef9d..00000000 --- a/api-java/src/main/java/javaclasses/mealorder/c/MealOrderEnrichments.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2018, TeamDev Ltd. All rights reserved. - * - * Redistribution and use in source and/or binary forms, with or without - * modification, must retain the above copyright notice and the following - * disclaimer. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -package javaclasses.mealorder.c; - -import com.google.common.base.Function; -import com.google.common.base.Optional; -import io.spine.server.event.EventEnricher; -import javaclasses.mealorder.PurchaseOrder; -import javaclasses.mealorder.PurchaseOrderId; -import javaclasses.mealorder.c.po.PurchaseOrderAggregate; -import javaclasses.mealorder.c.po.PurchaseOrderRepository; - -import static com.google.common.base.Preconditions.checkNotNull; - -@SuppressWarnings("Guava") // Spine Java 7 API. -final class MealOrderEnrichments { - - private final PurchaseOrderRepository poRepository; - - private MealOrderEnrichments(Builder builder) { - this.poRepository = builder.poRepository; - } - - /** - * Creates an instance of {@link EventEnricher} for the TodoList bounded context. - * - *

The enricher enriches the events in the system by predefined rules. - * - * @return TodoList {@code EventEnricher} - */ - EventEnricher createEnricher() { - final EventEnricher enricher = - EventEnricher.newBuilder() - .add(PurchaseOrderId.class, PurchaseOrder.class, poIdToPo()) - .build(); - return enricher; - } - - private Function poIdToPo() { - final Function result = poId -> { - if (poId == null) { - return PurchaseOrder.getDefaultInstance(); - } - final Optional aggregate = poRepository.find(poId); - if (!aggregate.isPresent()) { - return PurchaseOrder.getDefaultInstance(); - } - final PurchaseOrder po = aggregate.get() - .getState(); - return po; - }; - return result; - } - - /** - * Creates a new builder for (@code TodoListEnrichments). - * - * @return new builder instance - */ - static Builder newBuilder() { - return new Builder(); - } - - /** - * A builder for {@code EventEnricherSupplier} instances. - */ - static class Builder { - - private PurchaseOrderRepository poRepository; - - /** - * The {@code private} constructor prevents direct instantiation. - */ - private Builder() { - } - - Builder setPurchaseOrderRepository(PurchaseOrderRepository definitionRepository) { - checkNotNull(definitionRepository); - this.poRepository = definitionRepository; - return this; - } - - MealOrderEnrichments build() { - return new MealOrderEnrichments(this); - } - } -} From 397b86e03c667dd0475802c419c660665bcf5b13 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 25 Apr 2018 14:27:15 +0300 Subject: [PATCH 51/66] Add tests for `PurchaseOrderDetailsByUserViewProjection` --- .../MonthlySpendingsReportViewProjection.java | 17 ----- ...eOrderDetailsByUserViewProjectionTest.java | 63 ++++++++++++++++++- 2 files changed, 61 insertions(+), 19 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java index d6b4aae8..40020423 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java @@ -24,7 +24,6 @@ import io.spine.money.Money; import io.spine.server.projection.Projection; import javaclasses.mealorder.Dish; -import javaclasses.mealorder.LocalMonth; import javaclasses.mealorder.MonthlySpendingsReportId; import javaclasses.mealorder.Order; import javaclasses.mealorder.PurchaseOrder; @@ -51,22 +50,6 @@ public MonthlySpendingsReportViewProjection(MonthlySpendingsReportId id) { @Subscribe void on(PurchaseOrderSent event) { - if (getBuilder().getReportId() == null) { - final LocalMonth localMonth = LocalMonth.newBuilder() - .setMonth(event.getPurchaseOrder() - .getId() - .getPoDate() - .getMonth()) - .setYear(event.getPurchaseOrder() - .getId() - .getPoDate() - .getYear()) - .build(); - final MonthlySpendingsReportId reportId = MonthlySpendingsReportId.newBuilder() - .setMonth(localMonth) - .build(); - getBuilder().setReportId(reportId); - } final PurchaseOrder purchaseOrder = event.getPurchaseOrder(); final List userOrderDetailsList = new ArrayList<>(); final List dishItemList = new ArrayList<>(); diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java index 0a07f2ab..e6afc0a3 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByUserViewProjectionTest.java @@ -26,6 +26,8 @@ import javaclasses.mealorder.VendorId; import javaclasses.mealorder.c.event.PurchaseOrderCreated; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; +import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.c.event.PurchaseOrderValidationFailed; import javaclasses.mealorder.q.PurchaseOrderDetailsByUserViewProjection; import javaclasses.mealorder.q.UserOrderDetails; import org.junit.jupiter.api.BeforeEach; @@ -38,7 +40,10 @@ import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderCreatedInstance; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderDeliveredInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderSentInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderValidationFailedInstance; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; public class PurchaseOrderDetailsByUserViewProjectionTest extends ProjectionTest { private PurchaseOrderDetailsByUserViewProjection projection; @@ -59,8 +64,8 @@ void setUp() { } @Nested - @DisplayName("PurchaseOrderSent event should be interpreted by PurchaseOrderItemViewProjection") - class PurchaseOrderSentEvent { + @DisplayName("PurchaseOrderCreated event should be interpreted by PurchaseOrderItemViewProjection") + class PurchaseOrderCreatedEvent { @Test @DisplayName("Should set order for a projection") @@ -104,4 +109,58 @@ void addView() { .getPurchaseOrderStatus()); } } + + @Nested + @DisplayName("PurchaseOrderSent event should be interpreted") + class PurchaseOrderSentEvent { + + @Test + @DisplayName("Should change status") + void addView() { + final PurchaseOrderCreated purchaseOrderCreated = purchaseOrderCreatedInstance(); + dispatch(projection, createEvent(purchaseOrderCreated)); + dispatch(projection, createEvent(purchaseOrderCreated)); + final PurchaseOrderSent purchaseOrderSent = purchaseOrderSentInstance(); + dispatch(projection, createEvent(purchaseOrderSent)); + + assertEquals(PurchaseOrderStatus.SENT, projection.getState() + .getPurchaseOrderStatus()); + } + } + + @Nested + @DisplayName("PurchaseOrderValidationFailed event should be interpreted") + class PurchaseOrderValidationFailedEvent { + + @Test + @DisplayName("Should set invalid for correct user") + void addView() { + final PurchaseOrderCreated purchaseOrderCreated = purchaseOrderCreatedInstance(); + dispatch(projection, createEvent(purchaseOrderCreated)); + final PurchaseOrderValidationFailed poValidationFailed = purchaseOrderValidationFailedInstance(); + dispatch(projection, createEvent(poValidationFailed)); + + assertEquals(false, projection.getState() + .getOrderList() + .get(0) + .getIsValid()); + assertEquals(poValidationFailed.getFailureOrder(0) + .getId() + .getUserId(), projection.getState() + .getOrderList() + .get(0) + .getId()); + + assertEquals(true, projection.getState() + .getOrderList() + .get(1) + .getIsValid()); + assertNotEquals(poValidationFailed.getFailureOrder(0) + .getId() + .getUserId(), projection.getState() + .getOrderList() + .get(1) + .getId()); + } + } } From 6df2cf7efbe0e6c93dd94c17bf8780374ffee176 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 25 Apr 2018 14:37:43 +0300 Subject: [PATCH 52/66] Add tests for `PurchaseOrderValidationFailed` event --- ...eOrderDetailsByDishViewProjectionTest.java | 19 ++++++++++++++++++- .../PurchaseOrderItemViewProjectionTest.java | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByDishViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByDishViewProjectionTest.java index c98e296c..00b24924 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByDishViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderDetailsByDishViewProjectionTest.java @@ -27,6 +27,7 @@ import javaclasses.mealorder.c.event.PurchaseOrderCreated; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.c.event.PurchaseOrderValidationFailed; import javaclasses.mealorder.q.DishItem; import javaclasses.mealorder.q.PurchaseOrderDetailsByDishViewProjection; import org.junit.jupiter.api.BeforeEach; @@ -40,6 +41,7 @@ import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderCreatedInstance; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderDeliveredInstance; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderSentInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderValidationFailedInstance; import static org.junit.jupiter.api.Assertions.assertEquals; public class PurchaseOrderDetailsByDishViewProjectionTest extends ProjectionTest { @@ -79,6 +81,22 @@ void addView() { } } + @Nested + @DisplayName("PurchaseOrderSent event should be interpreted by PurchaseOrderDetailsByDishViewProjection") + class PurchaseOrderValidationFailedEvent { + + @Test + @DisplayName("Should change status for a projection") + void addView() { + final PurchaseOrderCreated purchaseOrderCreated = purchaseOrderCreatedInstance(); + dispatch(projection, createEvent(purchaseOrderCreated)); + final PurchaseOrderValidationFailed poValidationFailed = purchaseOrderValidationFailedInstance(); + dispatch(projection, createEvent(poValidationFailed)); + assertEquals(PurchaseOrderStatus.INVALID, projection.getState() + .getPurchaseOrderStatus()); + } + } + @Nested @DisplayName("PurchaseOrderSent event should be interpreted by PurchaseOrderDetailsByDishViewProjection") class PurchaseOrderSentEvent { @@ -94,7 +112,6 @@ void addView() { .getPurchaseOrderStatus()); } } - @Nested @DisplayName("PurchaseOrderDelivered event should be interpreted by PurchaseOrderDetailsByDishViewProjection") class PurchaseOrderDeliveredEvent { diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderItemViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderItemViewProjectionTest.java index cc638362..2ba13bc5 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderItemViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderItemViewProjectionTest.java @@ -24,6 +24,7 @@ import javaclasses.mealorder.PurchaseOrderStatus; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.c.event.PurchaseOrderValidationFailed; import javaclasses.mealorder.q.PurchaseOrderItemViewProjection; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -33,6 +34,7 @@ import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderDeliveredInstance; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderSentInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderValidationFailedInstance; import static org.junit.jupiter.api.Assertions.assertEquals; public class PurchaseOrderItemViewProjectionTest extends ProjectionTest { @@ -92,4 +94,20 @@ void addView() { .getPurchaseOrderStatus()); } } + + @Nested + @DisplayName("PurchaseOrderValidationFailed event should be interpreted by PurchaseOrderItemViewProjection") + class PurchaseOrderValidationFailedEvent { + + @Test + @DisplayName("Should change status of the PO") + void addView() { + final PurchaseOrderSent purchaseOrderSent = purchaseOrderSentInstance(); + dispatch(projection, createEvent(purchaseOrderSent)); + final PurchaseOrderValidationFailed poValidationFailed = purchaseOrderValidationFailedInstance(); + dispatch(projection, createEvent(poValidationFailed)); + assertEquals(PurchaseOrderStatus.INVALID, projection.getState() + .getPurchaseOrderStatus()); + } + } } From 21dcb1e71c8c29abff438f6c7a571af0aa0074a3 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 25 Apr 2018 14:44:46 +0300 Subject: [PATCH 53/66] Add test for `Projections` ctor --- .../javaclasses/mealorder/q/Projections.java | 2 +- .../q/projection/ProjectionsTest.java | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionsTest.java diff --git a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java index 8d96d55c..3506a3b9 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java @@ -27,7 +27,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -final class Projections { +public final class Projections { /** * The {@code private} constructor prevents the utility class instantiation. diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionsTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionsTest.java new file mode 100644 index 00000000..e86a3d4b --- /dev/null +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/ProjectionsTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.projection; + +import javaclasses.mealorder.q.Projections; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static io.spine.test.Tests.assertHasPrivateParameterlessCtor; + +@DisplayName("Projections should") +public class ProjectionsTest { + @Test + @DisplayName("have the private constructor") + void havePrivateConstructor() { + assertHasPrivateParameterlessCtor(Projections.class); + } +} From 439d0659e25cb42e37bccee60b0452778c57a016 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Thu, 26 Apr 2018 13:50:55 +0300 Subject: [PATCH 54/66] Rework subscribers and tests for monthly report --- .../MonthlySpendingsReportViewProjection.java | 98 ++++++++++++------- .../MenuListViewProjectionTest.java | 64 ++++++++++-- ...thlySpendingsReportViewProjectionTest.java | 68 ++++++++++++- .../javaclasses/mealorder/q/values.proto | 3 + .../testdata/TestMealOrderEventFactory.java | 16 ++- .../mealorder/testdata/TestValues.java | 9 +- 6 files changed, 214 insertions(+), 44 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java index 40020423..c9a333c4 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java @@ -25,7 +25,6 @@ import io.spine.server.projection.Projection; import javaclasses.mealorder.Dish; import javaclasses.mealorder.MonthlySpendingsReportId; -import javaclasses.mealorder.Order; import javaclasses.mealorder.PurchaseOrder; import javaclasses.mealorder.UserId; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; @@ -35,6 +34,8 @@ import java.util.ArrayList; import java.util.List; +import java.util.OptionalInt; +import java.util.stream.IntStream; public class MonthlySpendingsReportViewProjection extends Projection { @@ -50,56 +51,85 @@ public MonthlySpendingsReportViewProjection(MonthlySpendingsReportId id) { @Subscribe void on(PurchaseOrderSent event) { - final PurchaseOrder purchaseOrder = event.getPurchaseOrder(); final List userOrderDetailsList = new ArrayList<>(); - final List dishItemList = new ArrayList<>(); - final List orders = purchaseOrder.getOrderList(); - for (Order order : orders) { - final UserId userId = order.getId() - .getUserId(); + final PurchaseOrder purchaseOrder = event.getPurchaseOrder(); + purchaseOrder.getOrderList() + .forEach(order -> { + final List dishItemList = new ArrayList<>(); final List dishList = order.getDishList(); - for (Dish aDishList : dishList) { + dishList.forEach(dish -> { final DishItem dishItem = DishItem.newBuilder() - .setId(aDishList.getId()) - .setName(aDishList.getName()) - .setPrice(Money.newBuilder() - .setAmount(aDishList.getPrice() - .getAmount()) - .build()) + .setId(dish.getId()) + .setPrice(dish.getPrice()) + .setName(dish.getName()) .build(); dishItemList.add(dishItem); - } + }); + final UserId userId = order.getId() + .getUserId(); final UserOrderDetails userOrderDetails = UserOrderDetails.newBuilder() .setId(userId) .addAllDish(dishItemList) + .setPurchaseOrderId( + event.getPurchaseOrder() + .getId()) .build(); userOrderDetailsList.add(userOrderDetails); - } + }); getBuilder().addAllOrder(userOrderDetailsList); } @Subscribe void on(PurchaseOrderDelivered event) { - final List userSpendingsList = new ArrayList<>(); - final List userOrderDetailsList = getBuilder().getOrder(); - - for (UserOrderDetails userOrderDetails : userOrderDetailsList) { - long money = 0; - for (DishItem dishItem : userOrderDetails.getDishList()) { - money += dishItem.getPrice() - .getAmount(); + final List orderDetailsList = getBuilder().getOrder(); + orderDetailsList.forEach(userOrderDetails -> { + if (userOrderDetails.getPurchaseOrderId() + .equals(event.getId())) { + long money = 0; + for (DishItem dishItem : userOrderDetails.getDishList()) { + money += dishItem.getPrice() + .getAmount(); + } + final int index = getUserSpendingsIndex(userOrderDetails.getId()); + if (index == -1) { + final Money cost = Money.newBuilder() + .setAmount(money) + .build(); + final UserSpendings spendings = UserSpendings.newBuilder() + .setAmount(cost) + .setId(userOrderDetails.getId()) + .build(); + getBuilder().addUserSpending(spendings); + getBuilder().removeOrder(getBuilder().getOrder() + .indexOf(userOrderDetails)); + } else { + final Money cost = Money.newBuilder() + .setAmount(getBuilder().getUserSpending() + .get(index) + .getAmount() + .getAmount() + money) + .build(); + final UserSpendings spendings = UserSpendings.newBuilder( + getBuilder().getUserSpending() + .get(index)) + .setAmount(cost) + .build(); + getBuilder().setUserSpending(index, spendings); + getBuilder().removeOrder(getBuilder().getOrder() + .indexOf(userOrderDetails)); + } } - final Money usersMoney = Money.newBuilder() - .setAmount(money) - .build(); + }); + } - final UserSpendings userSpendings = UserSpendings.newBuilder() - .setId(userOrderDetails.getId()) - .setAmount(usersMoney) - .build(); - userSpendingsList.add(userSpendings); - } - getBuilder().addAllUserSpending(userSpendingsList); + private int getUserSpendingsIndex(UserId id) { + final List userSpendingsList = getBuilder().getUserSpending(); + final OptionalInt optionalInt = IntStream.range(0, userSpendingsList.size()) + .filter(i -> userSpendingsList.get(i) + .getId() + .equals(id)) + .findFirst(); + return optionalInt.isPresent() ? optionalInt.getAsInt() : -1; } } diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java index 9aac0657..e641674a 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java @@ -24,6 +24,7 @@ import javaclasses.mealorder.c.event.DateRangeForMenuSet; import javaclasses.mealorder.c.event.MenuImported; import javaclasses.mealorder.c.event.PurchaseOrderCreated; +import javaclasses.mealorder.q.MenuItem; import javaclasses.mealorder.q.MenuListViewProjection; import javaclasses.mealorder.testdata.TestValues; import org.junit.jupiter.api.BeforeEach; @@ -31,11 +32,15 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import java.util.List; + import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderCreatedInstance2; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.VendorEvents.dateRangeForMenuSetInstance; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.VendorEvents.menuImportedInstance; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; public class MenuListViewProjectionTest extends ProjectionTest { private MenuListViewProjection projection; @@ -55,6 +60,27 @@ class MenuImportedEvent { void addView() { final MenuImported menuImported = menuImportedInstance(); dispatch(projection, createEvent(menuImported)); + final List menuList = projection.getState() + .getMenuList(); + assertEquals(3, menuList.get(0) + .getDishesByCategoryList() + .size()); + assertEquals("Второе блюдо", menuList.get(0) + .getDishesByCategoryList() + .get(0) + .getCategory() + .getValue()); + assertEquals(3, menuList.get(0) + .getDishesByCategoryList() + .get(0) + .getDishesList() + .size()); + assertEquals("Картофель", menuList.get(0) + .getDishesByCategoryList() + .get(0) + .getDishesList() + .get(0) + .getName()); } } @@ -68,6 +94,26 @@ void addView() { dispatch(projection, createEvent(menuImported)); final DateRangeForMenuSet dateRangeForMenuSet = dateRangeForMenuSetInstance(); dispatch(projection, createEvent(dateRangeForMenuSet)); + final List menuList = projection.getState() + .getMenuList(); + assertEquals(25, menuList.get(0) + .getMenuDaysList() + .size()); + assertEquals(18, menuList.get(0) + .getMenuDaysList() + .get(5) + .getDate() + .getDay()); + assertEquals(2, menuList.get(0) + .getMenuDaysList() + .get(5) + .getDate() + .getMonthValue()); + assertEquals(2017, menuList.get(0) + .getMenuDaysList() + .get(5) + .getDate() + .getYear()); } } @@ -84,12 +130,18 @@ void addView() { final PurchaseOrderCreated purchaseOrderCreated = purchaseOrderCreatedInstance2(); dispatch(projection, createEvent(purchaseOrderCreated)); - assertEquals(false, projection.getState() - .getMenuList() - .get(0) - .getMenuDaysList() - .get(18) - .getIsAvailable()); + assertFalse(projection.getState() + .getMenuList() + .get(0) + .getMenuDaysList() + .get(18) + .getIsAvailable()); + assertTrue(projection.getState() + .getMenuList() + .get(0) + .getMenuDaysList() + .get(17) + .getIsAvailable()); } } } diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/MonthlySpendingsReportViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/MonthlySpendingsReportViewProjectionTest.java index 0261e9ba..3bc37aba 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/MonthlySpendingsReportViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/MonthlySpendingsReportViewProjectionTest.java @@ -32,7 +32,9 @@ import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderDeliveredInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderDeliveredInstance2; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderSentInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderSentInstance2; import static org.junit.jupiter.api.Assertions.assertEquals; public class MonthlySpendingsReportViewProjectionTest extends ProjectionTest { @@ -61,6 +63,38 @@ void addView() { final PurchaseOrderSent purchaseOrderSent = purchaseOrderSentInstance(); dispatch(projection, createEvent(purchaseOrderSent)); assertEquals(1 , projection.getState().getOrderCount()); + assertEquals(1, projection.getState() + .getOrderList() + .get(0) + .getDishList() + .size()); + assertEquals(0, projection.getState() + .getUserSpendingList() + .size()); + } + + @Test + @DisplayName("Should add compicated orders for a projection") + void addView2() { + final PurchaseOrderSent purchaseOrderSent = purchaseOrderSentInstance(); + dispatch(projection, createEvent(purchaseOrderSent)); + final PurchaseOrderSent purchaseOrderSent2 = purchaseOrderSentInstance2(); + dispatch(projection, createEvent(purchaseOrderSent2)); + assertEquals(5, projection.getState() + .getOrderCount()); + assertEquals(1, projection.getState() + .getOrderList() + .get(0) + .getDishList() + .size()); + assertEquals(0, projection.getState() + .getUserSpendingList() + .size()); + assertEquals(2, projection.getState() + .getOrderList() + .get(3) + .getDishList() + .size()); } } @@ -72,9 +106,41 @@ class PurchaseOrderDeliveredEvent { void addView() { final PurchaseOrderSent purchaseOrderSent = purchaseOrderSentInstance(); dispatch(projection, createEvent(purchaseOrderSent)); + final PurchaseOrderSent purchaseOrderSent2 = purchaseOrderSentInstance2(); + dispatch(projection, createEvent(purchaseOrderSent2)); final PurchaseOrderDelivered purchaseOrderDelivered = purchaseOrderDeliveredInstance(); + final PurchaseOrderDelivered purchaseOrderDelivered2 = purchaseOrderDeliveredInstance2(); + dispatch(projection, createEvent(purchaseOrderDelivered)); - assertEquals(1, projection.getState().getUserSpendingCount()); + assertEquals("user@example.com", projection.getState() + .getUserSpendingList() + .get(0) + .getId() + .getEmail() + .getValue()); + assertEquals(56, projection.getState() + .getUserSpendingList() + .get(0) + .getAmount() + .getAmount()); + assertEquals(1, projection.getState() + .getUserSpendingList() + .size()); + + dispatch(projection, createEvent(purchaseOrderDelivered2)); + assertEquals(336, projection.getState() + .getUserSpendingList() + .get(0) + .getAmount() + .getAmount()); + assertEquals(2, projection.getState() + .getUserSpendingList() + .size()); + assertEquals(448, projection.getState() + .getUserSpendingList() + .get(1) + .getAmount() + .getAmount()); } } diff --git a/model/src/main/proto/javaclasses/mealorder/q/values.proto b/model/src/main/proto/javaclasses/mealorder/q/values.proto index 9a9147b9..2eefe327 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/values.proto @@ -153,6 +153,9 @@ message UserOrderDetails { // An order validation status. bool is_valid = 3; + + // The identifier of a purchase order. + PurchaseOrderId purchase_order_id = 4; } // The item of a monthly spendings report view. diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java index a16df08e..8b653948 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java @@ -63,7 +63,13 @@ public class TestMealOrderEventFactory { .setStatus( PurchaseOrderStatus.CREATED) .build(); - + private static final PurchaseOrder PURCHASE_ORDER2 = PurchaseOrder.newBuilder() + .addAllOrder( + TestValues.BIG_ORDER) + .setId(TestValues.PURCHASE_ORDER_ID2) + .setStatus( + PurchaseOrderStatus.CREATED) + .build(); private TestMealOrderEventFactory() { } @@ -93,6 +99,10 @@ public static PurchaseOrderSent purchaseOrderSentInstance() { TestValues.EMAIL); } + public static PurchaseOrderSent purchaseOrderSentInstance2() { + return purchaseOrderSentInstance(PURCHASE_ORDER2, TestValues.USER_ID3.getEmail(), + TestValues.EMAIL); + } public static PurchaseOrderSent purchaseOrderSentInstance(PurchaseOrder po, EmailAddress senderEmail, EmailAddress vendorEmail) { @@ -111,6 +121,10 @@ public static PurchaseOrderDelivered purchaseOrderDeliveredInstance() { return purchaseOrderDeliveredInstance(TestValues.PURCHASE_ORDER_ID, TestValues.USER_ID); } + public static PurchaseOrderDelivered purchaseOrderDeliveredInstance2() { + return purchaseOrderDeliveredInstance(TestValues.PURCHASE_ORDER_ID2, + TestValues.USER_ID); + } private static PurchaseOrderDelivered purchaseOrderDeliveredInstance( PurchaseOrderId purchaseOrderId, UserId userId) { diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java index 8ad00ff4..a2ca9070 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java @@ -92,7 +92,12 @@ public class TestValues { "petr@example.com") .build()) .build(); - + public static final UserId USER_ID3 = UserId.newBuilder() + .setEmail(EmailAddress.newBuilder() + .setValue( + "sasha@mail.com") + .build()) + .build(); public static final LocalTime PO_DAILY_DEADLINE = LocalTime.newBuilder() .setHours(10) .setMinutes(0) @@ -361,7 +366,7 @@ public class TestValues { .build(); public static final PurchaseOrderId PURCHASE_ORDER_ID2 = PurchaseOrderId .newBuilder() - .setVendorId(VENDOR_ID) + .setVendorId(VENDOR_ID2) .setPoDate(DATE2) .build(); public static final Order ORDER = Order.newBuilder() From 1cdc943dc5866ee66778b4ff0374fa04da4b4dc9 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Thu, 26 Apr 2018 17:12:12 +0300 Subject: [PATCH 55/66] Refactor model according to UI needs --- .../mealorder/c/vendor/VendorAggregate.java | 52 +---- .../c/vendor/VendorAggregateRejections.java | 4 +- .../mealorder/q/FullMenuViewProjection.java | 62 ++++++ .../q/MenuCalendarViewProjection.java | 4 +- .../mealorder/q/MenuListViewProjection.java | 117 ++--------- .../javaclasses/mealorder/q/Projections.java | 45 ++++ .../mealorder/c/MealOrderTest.java | 4 - .../mealorder/c/order/OrderCommandTest.java | 6 - .../mealorder/c/vendor/ImportMenuTest.java | 142 ++++++++++++- .../c/vendor/SetDateRangeForMenuTest.java | 197 ------------------ .../FullMenuViewProjectionTest.java | 63 ++++++ .../MenuCalendarViewProjectionTest.java | 12 +- .../MenuListViewProjectionTest.java | 84 ++------ .../javaclasses/mealorder/c/commands.proto | 16 +- .../javaclasses/mealorder/c/events.proto | 19 +- .../javaclasses/mealorder/identifiers.proto | 2 +- .../javaclasses/mealorder/q/projections.proto | 25 ++- .../javaclasses/mealorder/q/values.proto | 7 +- .../proto/javaclasses/mealorder/values.proto | 13 -- .../testdata/TestMealOrderEventFactory.java | 33 +-- .../testdata/TestVendorCommandFactory.java | 52 ++--- 21 files changed, 421 insertions(+), 538 deletions(-) create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/FullMenuViewProjection.java delete mode 100644 api-java/src/test/java/javaclasses/mealorder/c/vendor/SetDateRangeForMenuTest.java create mode 100644 api-java/src/test/java/javaclasses/mealorder/q/projection/FullMenuViewProjectionTest.java diff --git a/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorAggregate.java b/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorAggregate.java index e0a97a9c..e1dad124 100644 --- a/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorAggregate.java +++ b/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorAggregate.java @@ -25,7 +25,6 @@ import io.spine.server.command.Assign; import javaclasses.mealorder.Menu; import javaclasses.mealorder.MenuDateRange; -import javaclasses.mealorder.MenuId; import javaclasses.mealorder.Vendor; import javaclasses.mealorder.VendorChange; import javaclasses.mealorder.VendorId; @@ -33,18 +32,13 @@ import javaclasses.mealorder.VendorVBuilder; import javaclasses.mealorder.c.command.AddVendor; import javaclasses.mealorder.c.command.ImportMenu; -import javaclasses.mealorder.c.command.SetDateRangeForMenu; import javaclasses.mealorder.c.command.UpdateVendor; -import javaclasses.mealorder.c.event.DateRangeForMenuSet; import javaclasses.mealorder.c.event.MenuImported; import javaclasses.mealorder.c.event.VendorAdded; import javaclasses.mealorder.c.event.VendorUpdated; import javaclasses.mealorder.c.rejection.CannotSetDateRange; import javaclasses.mealorder.c.rejection.VendorAlreadyExists; -import java.util.List; -import java.util.stream.IntStream; - import static io.spine.time.Time.getCurrentTime; import static javaclasses.mealorder.c.vendor.VendorAggregateRejections.cannotSetDateRange; import static javaclasses.mealorder.c.vendor.VendorAggregateRejections.vendorAlreadyExists; @@ -96,36 +90,23 @@ VendorUpdated handle(UpdateVendor cmd) { } @Assign - MenuImported handle(ImportMenu cmd) { + MenuImported handle(ImportMenu cmd) throws CannotSetDateRange { + final MenuDateRange range = cmd.getMenuDateRange(); + final Vendor vendor = getState(); + if (!isValidDateRange(range) || isThereMenuForThisDateRange(vendor, range)) { + throw cannotSetDateRange(cmd); + } final MenuImported menuImported = MenuImported.newBuilder() .setVendorId(cmd.getVendorId()) .setMenuId(cmd.getMenuId()) .setWhoImported(cmd.getUserId()) .setWhenImported(getCurrentTime()) .addAllDish(cmd.getDishList()) + .setMenuDateRange(cmd.getMenuDateRange()) .build(); return menuImported; } - @Assign - DateRangeForMenuSet handle(SetDateRangeForMenu cmd) throws CannotSetDateRange { - final MenuDateRange range = cmd.getMenuDateRange(); - final Vendor vendor = getState(); - - if (!isValidDateRange(range) || isThereMenuForThisDateRange(vendor, range)) { - throw cannotSetDateRange(cmd); - } - final DateRangeForMenuSet dateRangeForMenuSet = - DateRangeForMenuSet.newBuilder() - .setVendorId(cmd.getVendorId()) - .setMenuId(cmd.getMenuId()) - .setWhoSet(cmd.getUserId()) - .setWhenSet(getCurrentTime()) - .setMenuDateRange(cmd.getMenuDateRange()) - .build(); - return dateRangeForMenuSet; - } - @Apply void vendorAdded(VendorAdded event) { getBuilder().setId(event.getVendorId()) @@ -150,24 +131,7 @@ void menuImported(MenuImported event) { getBuilder().addMenu(Menu.newBuilder() .setId(event.getMenuId()) .addAllDish(event.getDishList()) + .setMenuDateRange(event.getMenuDateRange()) .build()); } - - @Apply - void dateRangeForMenuSet(DateRangeForMenuSet event) { - final List

menus = getBuilder().getMenu(); - final MenuId menuId = event.getMenuId(); - - final int index = IntStream.range(0, menus.size()) - .filter(i -> menus.get(i) - .getId() - .equals(menuId)) - .findFirst() - .getAsInt(); - - final Menu menu = menus.get(index); - getBuilder().setMenu(index, Menu.newBuilder(menu) - .setMenuDateRange(event.getMenuDateRange()) - .build()); - } } diff --git a/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorAggregateRejections.java b/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorAggregateRejections.java index 7f06f1a2..f38feb09 100644 --- a/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorAggregateRejections.java +++ b/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorAggregateRejections.java @@ -21,7 +21,7 @@ package javaclasses.mealorder.c.vendor; import javaclasses.mealorder.c.command.AddVendor; -import javaclasses.mealorder.c.command.SetDateRangeForMenu; +import javaclasses.mealorder.c.command.ImportMenu; import javaclasses.mealorder.c.rejection.CannotSetDateRange; import javaclasses.mealorder.c.rejection.VendorAlreadyExists; @@ -62,7 +62,7 @@ static VendorAlreadyExists vendorAlreadyExists(AddVendor cmd) throws * @param cmd the {@code SetDateRangeForMenu} command which thrown the rejection * @throws CannotSetDateRange the rejection to throw */ - static CannotSetDateRange cannotSetDateRange(SetDateRangeForMenu cmd) throws + static CannotSetDateRange cannotSetDateRange(ImportMenu cmd) throws CannotSetDateRange { checkNotNull(cmd); final CannotSetDateRange cannotSetDateRange = new CannotSetDateRange(cmd.getVendorId(), diff --git a/api-java/src/main/java/javaclasses/mealorder/q/FullMenuViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/FullMenuViewProjection.java new file mode 100644 index 00000000..d16f42a4 --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/FullMenuViewProjection.java @@ -0,0 +1,62 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q; + +import io.spine.core.Subscribe; +import io.spine.server.projection.Projection; +import javaclasses.mealorder.MenuId; +import javaclasses.mealorder.VendorName; +import javaclasses.mealorder.c.event.MenuImported; +import javaclasses.mealorder.q.projection.FullMenuView; +import javaclasses.mealorder.q.projection.FullMenuViewVBuilder; + +import java.util.List; + +import static javaclasses.mealorder.q.Projections.getAllDishesByCategories; + +public class FullMenuViewProjection extends Projection { + + /** + * Creates a new instance. + * + * @param id the ID for the new instance + * @throws IllegalArgumentException if the ID is not of one of the supported types + */ + public FullMenuViewProjection(MenuId id) { + super(id); + } + + @Subscribe + void on(MenuImported event) { + final VendorName vendorName = VendorName.newBuilder() + .setValue(event.getVendorId() + .getValue()) + .build(); + + final List allDishesByCategories = getAllDishesByCategories( + event.getDishList()); + + getBuilder().addAllDishesByCategory(allDishesByCategories); + getBuilder().setVendorName(vendorName); + getBuilder().setMenuId(event.getMenuId()); + getBuilder().setMenuDateRange(event.getMenuDateRange()); + } +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java index d0372ffb..6505dace 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java @@ -23,7 +23,7 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; import javaclasses.mealorder.MenuCalendarId; -import javaclasses.mealorder.c.event.DateRangeForMenuSet; +import javaclasses.mealorder.c.event.MenuImported; import javaclasses.mealorder.q.projection.MenuCalendarView; import javaclasses.mealorder.q.projection.MenuCalendarViewVBuilder; @@ -57,7 +57,7 @@ public MenuCalendarViewProjection(MenuCalendarId id) { } @Subscribe - void on(DateRangeForMenuSet event) { + void on(MenuImported event) { final List datesBetween = getDatesBetween(event.getMenuDateRange() .getRangeStart(), event.getMenuDateRange() diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java index 5192057a..09a90f08 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java @@ -23,23 +23,17 @@ import io.spine.core.Subscribe; import io.spine.server.projection.Projection; import io.spine.time.LocalDate; -import javaclasses.mealorder.CategoryName; -import javaclasses.mealorder.Dish; import javaclasses.mealorder.MenuDateRange; -import javaclasses.mealorder.MenuForDay; import javaclasses.mealorder.MenuListId; import javaclasses.mealorder.VendorName; -import javaclasses.mealorder.c.event.DateRangeForMenuSet; import javaclasses.mealorder.c.event.MenuImported; import javaclasses.mealorder.c.event.PurchaseOrderCreated; import javaclasses.mealorder.q.projection.MenuListView; import javaclasses.mealorder.q.projection.MenuListViewVBuilder; -import java.util.ArrayList; import java.util.List; -import java.util.OptionalInt; -import java.util.stream.IntStream; +import static javaclasses.mealorder.q.Projections.getAllDishesByCategories; import static javaclasses.mealorder.q.Projections.getDatesBetween; public class MenuListViewProjection extends Projection { @@ -62,19 +56,6 @@ void on(MenuImported event) { .build(); final List allDishesByCategories = getAllDishesByCategories( event.getDishList()); - final MenuItem menuItem = MenuItem.newBuilder() - .setVendorName(vendorName) - .addAllDishesByCategory(allDishesByCategories) - .build(); - getBuilder().addMenu(menuItem); - - } - - @Subscribe - void on(DateRangeForMenuSet event) { - final List menuItems = getBuilder().getMenu(); - final MenuItem menuItem = menuItems.get(menuItems.size() - 1); - final List menuDays = new ArrayList<>(); final MenuDateRange menuDateRange = event.getMenuDateRange(); final List datesBetween = getDatesBetween( @@ -85,88 +66,34 @@ void on(DateRangeForMenuSet event) { .setMonthValue(date.getMonthValue()) .setYear(date.getYear()) .build(); - final MenuForDay menuForDay = MenuForDay.newBuilder() - .setDate(localDate) - .setIsAvailable(true) - .build(); - menuDays.add(menuForDay); + final MenuItem menuItem = MenuItem.newBuilder() + .setVendorName(vendorName) + .addAllDishesByCategory(allDishesByCategories) + .setMenuDate(localDate) + .setIsAvilable(true) + .build(); + getBuilder().addMenu(menuItem); }); - final MenuItem newMenuItem = MenuItem.newBuilder(menuItem) - .addAllMenuDays(menuDays) - .build(); - getBuilder().setMenu(menuItems.size() - 1, newMenuItem); } @Subscribe void on(PurchaseOrderCreated event) { - final List newMenu = new ArrayList<>(getBuilder().getMenu()); - for (int i = 0; i < newMenu.size(); i++) { - final MenuItem menuItem = newMenu.get(i); - final List menuDaysList = new ArrayList<>(menuItem.getMenuDaysList()); - final LocalDate date = event.getId() - .getPoDate(); - for (int j = 0; j < menuDaysList.size(); j++) { - final MenuForDay menuForDay = menuDaysList.get(j); - - if (menuForDay.getDate() - .equals(date)) { - final MenuForDay newMenuForDay = MenuForDay.newBuilder() - .setDate(date) - .setIsAvailable(false) - .build(); - menuDaysList.set(j, newMenuForDay); - } - } - final MenuItem newMenuItem = MenuItem.newBuilder(menuItem) - .clearMenuDays() - .addAllMenuDays(menuDaysList) - .build(); - newMenu.set(i, newMenuItem); - } - getBuilder().clearMenu() - .addAllMenu(newMenu); - } - - private List getAllDishesByCategories( - List dishList) { - final List dishesByCategoryList = new ArrayList<>(); - dishList.forEach(dish -> { - final int index = categoryIndex(dishesByCategoryList, dish.getCategory()); - final DishItem newDish = DishItem.newBuilder() - .setId(dish.getId()) - .setName(dish.getName()) - .setPrice(dish.getPrice()) - .build(); - if (index == -1) { - final CategoryName category = CategoryName.newBuilder() - .setValue(dish.getCategory()) - .build(); - - final DishesByCategory dishesByCategory = DishesByCategory.newBuilder() - .setCategory(category) - .addDishes(newDish) - .build(); - dishesByCategoryList.add(dishesByCategory); - } else { - final DishesByCategory newDishesByCategory = DishesByCategory.newBuilder( - dishesByCategoryList.get(index)) - .addDishes(newDish) - .build(); - dishesByCategoryList.set(index, newDishesByCategory); - } - }); - return dishesByCategoryList; - } + final LocalDate poDate = event.getId() + .getPoDate(); + getBuilder().getMenu() + .forEach(menuItem -> { + if (menuItem.getMenuDate() + .equals(poDate)) { + final MenuItem newMenuItem = MenuItem.newBuilder(menuItem) + .setIsAvilable(false) + .build(); + final int index = getBuilder().getMenu() + .indexOf(menuItem); + getBuilder().setMenu(index, newMenuItem); + } + }); - private int categoryIndex(List dishByCategory, String category) { - final OptionalInt optionalInt = IntStream.range(0, dishByCategory.size()) - .filter(i -> dishByCategory.get(i) - .getCategory() - .getValue() - .equals(category)) - .findFirst(); - return optionalInt.isPresent() ? optionalInt.getAsInt() : -1; } } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java index 3506a3b9..637c3738 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java @@ -21,9 +21,13 @@ package javaclasses.mealorder.q; import io.spine.time.LocalDate; +import javaclasses.mealorder.CategoryName; +import javaclasses.mealorder.Dish; import java.time.temporal.ChronoUnit; +import java.util.ArrayList; import java.util.List; +import java.util.OptionalInt; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -57,4 +61,45 @@ static LocalDate toLocalDate(java.time.LocalDate date) { .setYear(date.getYear()) .build(); } + + static List getAllDishesByCategories( + List dishList) { + final List dishesByCategoryList = new ArrayList<>(); + dishList.forEach(dish -> { + final int index = categoryIndex(dishesByCategoryList, dish.getCategory()); + final DishItem newDish = DishItem.newBuilder() + .setId(dish.getId()) + .setName(dish.getName()) + .setPrice(dish.getPrice()) + .build(); + if (index == -1) { + final CategoryName category = CategoryName.newBuilder() + .setValue(dish.getCategory()) + .build(); + + final DishesByCategory dishesByCategory = DishesByCategory.newBuilder() + .setCategory(category) + .addDishes(newDish) + .build(); + dishesByCategoryList.add(dishesByCategory); + } else { + final DishesByCategory newDishesByCategory = DishesByCategory.newBuilder( + dishesByCategoryList.get(index)) + .addDishes(newDish) + .build(); + dishesByCategoryList.set(index, newDishesByCategory); + } + }); + return dishesByCategoryList; + } + + static int categoryIndex(List dishByCategory, String category) { + final OptionalInt optionalInt = IntStream.range(0, dishByCategory.size()) + .filter(i -> dishByCategory.get(i) + .getCategory() + .getValue() + .equals(category)) + .findFirst(); + return optionalInt.isPresent() ? optionalInt.getAsInt() : -1; + } } diff --git a/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java b/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java index 56fcd878..b8c511f8 100644 --- a/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java @@ -47,7 +47,6 @@ import static javaclasses.mealorder.testdata.TestValues.PURCHASE_ORDER_ID; import static javaclasses.mealorder.testdata.TestVendorCommandFactory.addVendorInstance; import static javaclasses.mealorder.testdata.TestVendorCommandFactory.importMenuInstance; -import static javaclasses.mealorder.testdata.TestVendorCommandFactory.setDateRangeForMenuInstance; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -85,9 +84,6 @@ void firstFlow() { final Command importMenu = createCommand(importMenuInstance()); commandBus.post(importMenu, observer); - final Command setDateRangeForMenu = createCommand(setDateRangeForMenuInstance()); - commandBus.post(setDateRangeForMenu, observer); - final Command createOrderCommand = createCommand(createOrderInstance()); commandBus.post(createOrderCommand, observer); diff --git a/api-java/src/test/java/javaclasses/mealorder/c/order/OrderCommandTest.java b/api-java/src/test/java/javaclasses/mealorder/c/order/OrderCommandTest.java index 613802f7..d98507da 100644 --- a/api-java/src/test/java/javaclasses/mealorder/c/order/OrderCommandTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/c/order/OrderCommandTest.java @@ -23,7 +23,6 @@ import io.spine.client.ActorRequestFactory; import io.spine.client.TestActorRequestFactory; import io.spine.core.Command; -import io.spine.grpc.StreamObservers; import io.spine.server.BoundedContext; import io.spine.server.commandbus.CommandBus; import io.spine.server.event.EventBus; @@ -62,10 +61,5 @@ private void executeVendorCommands(ActorRequestFactory requestFactory, CommandBu requestFactory.command() .create(TestVendorCommandFactory.importMenuInstance()); commandBus.post(importMenu, noOpObserver()); - - final Command setDateRangeForMenu = - requestFactory.command() - .create(TestVendorCommandFactory.setDateRangeForMenuInstance()); - commandBus.post(setDateRangeForMenu, noOpObserver()); } } diff --git a/api-java/src/test/java/javaclasses/mealorder/c/vendor/ImportMenuTest.java b/api-java/src/test/java/javaclasses/mealorder/c/vendor/ImportMenuTest.java index f638b8be..61c4efc0 100644 --- a/api-java/src/test/java/javaclasses/mealorder/c/vendor/ImportMenuTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/c/vendor/ImportMenuTest.java @@ -20,12 +20,16 @@ package javaclasses.mealorder.c.vendor; +import com.google.common.base.Throwables; import com.google.protobuf.Message; import javaclasses.mealorder.Dish; +import javaclasses.mealorder.Menu; import javaclasses.mealorder.Vendor; import javaclasses.mealorder.c.command.AddVendor; import javaclasses.mealorder.c.command.ImportMenu; import javaclasses.mealorder.c.event.MenuImported; +import javaclasses.mealorder.c.rejection.CannotSetDateRange; +import javaclasses.mealorder.c.rejection.Rejections; import javaclasses.mealorder.testdata.TestVendorCommandFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -36,11 +40,18 @@ import static io.spine.server.aggregate.AggregateMessageDispatcher.dispatchCommand; import static javaclasses.mealorder.testdata.TestValues.DISH1; import static javaclasses.mealorder.testdata.TestValues.DISH2; +import static javaclasses.mealorder.testdata.TestValues.INVALID_MENU_DATE_RANGE; +import static javaclasses.mealorder.testdata.TestValues.MENU_DATE_RANGE; +import static javaclasses.mealorder.testdata.TestValues.MENU_DATE_RANGE_FROM_PAST; import static javaclasses.mealorder.testdata.TestValues.MENU_ID; import static javaclasses.mealorder.testdata.TestValues.USER_ID; import static javaclasses.mealorder.testdata.TestValues.VENDOR_ID; +import static javaclasses.mealorder.testdata.TestVendorCommandFactory.importMenuInstance; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.instanceOf; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; /** * @author Yurii Haidamaka @@ -60,14 +71,15 @@ void produceEvent() { final AddVendor addVendorCmd = TestVendorCommandFactory.addVendorInstance(); dispatchCommand(aggregate, envelopeOf(addVendorCmd)); - final ImportMenu importMenu = TestVendorCommandFactory.importMenuInstance(); + final ImportMenu importMenu = importMenuInstance(); final List messageList = dispatchCommand(aggregate, envelopeOf(importMenu)); assertNotNull(aggregate.getId()); assertEquals(1, messageList.size()); - assertEquals(MenuImported.class, messageList.get(0).getClass()); + assertEquals(MenuImported.class, messageList.get(0) + .getClass()); final MenuImported menuImported = (MenuImported) messageList.get(0); @@ -86,10 +98,134 @@ void importMenu() { final AddVendor addVendorCmd = TestVendorCommandFactory.addVendorInstance(); dispatchCommand(aggregate, envelopeOf(addVendorCmd)); - final ImportMenu importMenu = TestVendorCommandFactory.importMenuInstance(); + final ImportMenu importMenu = importMenuInstance(); dispatchCommand(aggregate, envelopeOf(importMenu)); final Vendor state = aggregate.getState(); assertEquals(state.getId(), importMenu.getVendorId()); } + + @Test + @DisplayName("create correct date range") + void createEvent() { + final AddVendor addVendor = TestVendorCommandFactory.addVendorInstance(); + dispatchCommand(aggregate, envelopeOf(addVendor)); + final ImportMenu importMenu = importMenuInstance(); + final List messageList = + dispatchCommand(aggregate, envelopeOf(importMenu)); + + assertNotNull(aggregate.getId()); + assertEquals(1, messageList.size()); + assertEquals(MenuImported.class, messageList.get(0) + .getClass()); + + final MenuImported menuImported = (MenuImported) messageList.get(0); + + assertEquals(VENDOR_ID, menuImported.getVendorId()); + assertEquals(MENU_ID, menuImported.getMenuId()); + assertEquals(USER_ID, menuImported.getWhoImported()); + assertEquals(MENU_DATE_RANGE, menuImported.getMenuDateRange()); + } + + @Test + @DisplayName("set date range for menu") + void setDateRange() { + final AddVendor addVendor = TestVendorCommandFactory.addVendorInstance(); + dispatchCommand(aggregate, envelopeOf(addVendor)); + + final ImportMenu importMenu = importMenuInstance(); + dispatchCommand(aggregate, envelopeOf(importMenu)); + + final Vendor state = aggregate.getState(); + assertEquals(state.getId(), importMenu.getVendorId()); + + final Menu menu = state.getMenuList() + .stream() + .filter(m -> m.getId() + .equals(importMenu.getMenuId())) + .findFirst() + .get(); + + assertEquals(VENDOR_ID, importMenu.getVendorId()); + assertEquals(MENU_ID, importMenu.getMenuId()); + assertEquals(USER_ID, importMenu.getUserId()); + assertEquals(menu.getMenuDateRange(), importMenu.getMenuDateRange()); + assertEquals(importMenu.getMenuDateRange(), state.getMenuList() + .get(0) + .getMenuDateRange()); + } + + @Test + @DisplayName("produce `CannotSetDateRange` rejection if date range is not valid") + void produceRejection() { + final AddVendor addVendor = TestVendorCommandFactory.addVendorInstance(); + dispatchCommand(aggregate, envelopeOf(addVendor)); + + final ImportMenu invalidImportMenu = + importMenuInstance(VENDOR_ID, USER_ID, MENU_ID, INVALID_MENU_DATE_RANGE, DISH1, + DISH2); + + final Throwable t = assertThrows(Throwable.class, + () -> dispatchCommand(aggregate, + envelopeOf( + invalidImportMenu))); + final Throwable cause = Throwables.getRootCause(t); + assertThat(cause, instanceOf(CannotSetDateRange.class)); + + @SuppressWarnings("ConstantConditions") // Instance type checked before. + final Rejections.CannotSetDateRange rejection = + ((CannotSetDateRange) cause).getMessageThrown(); + + assertEquals(invalidImportMenu.getVendorId(), rejection.getVendorId()); + assertEquals(invalidImportMenu.getMenuId(), rejection.getMenuId()); + assertEquals(invalidImportMenu.getMenuDateRange(), rejection.getMenuDateRange()); + } + + @Test + @DisplayName("produce `CannotSetDateRange` rejection if the order date is from the past") + void produceCannotSetDateRangeRejection() { + final AddVendor addVendor = TestVendorCommandFactory.addVendorInstance(); + dispatchCommand(aggregate, envelopeOf(addVendor)); + final ImportMenu importMenu = importMenuInstance(); + dispatchCommand(aggregate, envelopeOf(importMenu)); + final ImportMenu importMenuFromPast = + importMenuInstance(VENDOR_ID, USER_ID, MENU_ID, MENU_DATE_RANGE_FROM_PAST, DISH1, + DISH2); + + final Throwable t = + assertThrows(Throwable.class, () -> dispatchCommand(aggregate, + envelopeOf( + importMenuFromPast))); + final Throwable cause = Throwables.getRootCause(t); + + @SuppressWarnings("ConstantConditions") // Instance type checked before. + final Rejections.CannotSetDateRange rejection = + ((CannotSetDateRange) cause).getMessageThrown(); + + assertEquals(importMenuFromPast.getVendorId(), rejection.getVendorId()); + assertEquals(importMenuFromPast.getMenuId(), rejection.getMenuId()); + assertEquals(importMenuFromPast.getMenuDateRange(), rejection.getMenuDateRange()); + } + + @Test + @DisplayName("produce `CannotSetDateRange` rejection if vendor already has menu on this date range") + void produceRejectionIfMenuExists() { + final AddVendor addVendor = TestVendorCommandFactory.addVendorInstance(); + dispatchCommand(aggregate, envelopeOf(addVendor)); + final ImportMenu importMenu = importMenuInstance(); + dispatchCommand(aggregate, envelopeOf(importMenu)); + + final Throwable t = assertThrows(Throwable.class, + () -> dispatchCommand(aggregate, envelopeOf(importMenu))); + final Throwable cause = Throwables.getRootCause(t); + assertThat(cause, instanceOf(CannotSetDateRange.class)); + + @SuppressWarnings("ConstantConditions") // Instance type checked before. + final Rejections.CannotSetDateRange rejection = + ((CannotSetDateRange) cause).getMessageThrown(); + + assertEquals(importMenu.getVendorId(), rejection.getVendorId()); + assertEquals(importMenu.getMenuId(), rejection.getMenuId()); + assertEquals(importMenu.getMenuDateRange(), rejection.getMenuDateRange()); + } } diff --git a/api-java/src/test/java/javaclasses/mealorder/c/vendor/SetDateRangeForMenuTest.java b/api-java/src/test/java/javaclasses/mealorder/c/vendor/SetDateRangeForMenuTest.java deleted file mode 100644 index 09a91463..00000000 --- a/api-java/src/test/java/javaclasses/mealorder/c/vendor/SetDateRangeForMenuTest.java +++ /dev/null @@ -1,197 +0,0 @@ -// -// Copyright 2018, TeamDev Ltd. All rights reserved. -// -// Redistribution and use in source and/or binary gorms, with or without -// modification, must retain the above copyright notice and the following -// disclaimer. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -package javaclasses.mealorder.c.vendor; - -import com.google.common.base.Throwables; -import com.google.protobuf.Message; -import javaclasses.mealorder.Menu; -import javaclasses.mealorder.Vendor; -import javaclasses.mealorder.c.command.AddVendor; -import javaclasses.mealorder.c.command.ImportMenu; -import javaclasses.mealorder.c.command.SetDateRangeForMenu; -import javaclasses.mealorder.c.event.DateRangeForMenuSet; -import javaclasses.mealorder.c.rejection.CannotSetDateRange; -import javaclasses.mealorder.c.rejection.Rejections; -import javaclasses.mealorder.testdata.TestVendorCommandFactory; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.util.List; - -import static io.spine.server.aggregate.AggregateMessageDispatcher.dispatchCommand; -import static javaclasses.mealorder.testdata.TestValues.INVALID_MENU_DATE_RANGE; -import static javaclasses.mealorder.testdata.TestValues.MENU_DATE_RANGE; -import static javaclasses.mealorder.testdata.TestValues.MENU_DATE_RANGE_FROM_PAST; -import static javaclasses.mealorder.testdata.TestValues.MENU_ID; -import static javaclasses.mealorder.testdata.TestValues.USER_ID; -import static javaclasses.mealorder.testdata.TestValues.VENDOR_ID; -import static javaclasses.mealorder.testdata.TestVendorCommandFactory.setDateRangeForMenuInstance; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.instanceOf; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; - -/** - * @author Yurii Haidamaka - */ -@DisplayName("`SetDateRangeForMenu` command should be interpreted by `VendorAggregate` and") -public class SetDateRangeForMenuTest extends VendorCommandTest { - - @Override - @BeforeEach - public void setUp() { - super.setUp(); - } - - @Test - @DisplayName("produce `DateRangeForMenuSet` event") - void produceEvent() { - final AddVendor addVendor = TestVendorCommandFactory.addVendorInstance(); - dispatchCommand(aggregate, envelopeOf(addVendor)); - final ImportMenu importMenu = TestVendorCommandFactory.importMenuInstance(); - dispatchCommand(aggregate, envelopeOf(importMenu)); - - final SetDateRangeForMenu setDateRangeForMenuCmd = - TestVendorCommandFactory.setDateRangeForMenuInstance(); - - final List messageList = - dispatchCommand(aggregate, envelopeOf(setDateRangeForMenuCmd)); - - assertNotNull(aggregate.getId()); - assertEquals(1, messageList.size()); - assertEquals(DateRangeForMenuSet.class, messageList.get(0) - .getClass()); - - final DateRangeForMenuSet dateRangeForMenuSet = (DateRangeForMenuSet) messageList.get(0); - - assertEquals(VENDOR_ID, dateRangeForMenuSet.getVendorId()); - assertEquals(MENU_ID, dateRangeForMenuSet.getMenuId()); - assertEquals(USER_ID, dateRangeForMenuSet.getWhoSet()); - assertEquals(MENU_DATE_RANGE, dateRangeForMenuSet.getMenuDateRange()); - } - - @Test - @DisplayName("set date range for menu") - void setDateRange() { - final AddVendor addVendor = TestVendorCommandFactory.addVendorInstance(); - dispatchCommand(aggregate, envelopeOf(addVendor)); - - final ImportMenu importMenu = TestVendorCommandFactory.importMenuInstance(); - dispatchCommand(aggregate, envelopeOf(importMenu)); - - final SetDateRangeForMenu setDateRangeForMenu = TestVendorCommandFactory.setDateRangeForMenuInstance(); - dispatchCommand(aggregate, envelopeOf(setDateRangeForMenu)); - - final Vendor state = aggregate.getState(); - assertEquals(state.getId(), setDateRangeForMenu.getVendorId()); - - final Menu menu = state.getMenuList() - .stream() - .filter(m -> m.getId() - .equals(setDateRangeForMenu.getMenuId())) - .findFirst() - .get(); - - assertEquals(VENDOR_ID, setDateRangeForMenu.getVendorId()); - assertEquals(MENU_ID, setDateRangeForMenu.getMenuId()); - assertEquals(USER_ID, setDateRangeForMenu.getUserId()); - assertEquals(menu.getMenuDateRange(), setDateRangeForMenu.getMenuDateRange()); - } - - @Test - @DisplayName("produce `CannotSetDateRange` rejection if date range is not valid") - void produceRejection() { - final AddVendor addVendor = TestVendorCommandFactory.addVendorInstance(); - dispatchCommand(aggregate, envelopeOf(addVendor)); - final ImportMenu importMenu = TestVendorCommandFactory.importMenuInstance(); - dispatchCommand(aggregate, envelopeOf(importMenu)); - - final SetDateRangeForMenu setInvalidDateRangeForMenu = - setDateRangeForMenuInstance(VENDOR_ID, MENU_ID, USER_ID, INVALID_MENU_DATE_RANGE); - - final Throwable t = assertThrows(Throwable.class, - () -> dispatchCommand(aggregate, - envelopeOf( - setInvalidDateRangeForMenu))); - final Throwable cause = Throwables.getRootCause(t); - assertThat(cause, instanceOf(CannotSetDateRange.class)); - - @SuppressWarnings("ConstantConditions") // Instance type checked before. - final Rejections.CannotSetDateRange rejection = - ((CannotSetDateRange) cause).getMessageThrown(); - - assertEquals(setInvalidDateRangeForMenu.getVendorId(), rejection.getVendorId()); - assertEquals(setInvalidDateRangeForMenu.getMenuId(), rejection.getMenuId()); - assertEquals(setInvalidDateRangeForMenu.getMenuDateRange(), rejection.getMenuDateRange()); - } - - @Test - @DisplayName("produce `CannotSetDateRange` rejection if the order date is from the past") - void produceCannotSetDateRangeRejection() { - final AddVendor addVendor = TestVendorCommandFactory.addVendorInstance(); - dispatchCommand(aggregate, envelopeOf(addVendor)); - final ImportMenu importMenu = TestVendorCommandFactory.importMenuInstance(); - dispatchCommand(aggregate, envelopeOf(importMenu)); - - final SetDateRangeForMenu setRangeFromPast = - setDateRangeForMenuInstance(VENDOR_ID, MENU_ID, USER_ID, MENU_DATE_RANGE_FROM_PAST); - - final Throwable t = - assertThrows(Throwable.class, () -> dispatchCommand(aggregate, - envelopeOf(setRangeFromPast))); - final Throwable cause = Throwables.getRootCause(t); - - @SuppressWarnings("ConstantConditions") // Instance type checked before. - final Rejections.CannotSetDateRange rejection = - ((CannotSetDateRange) cause).getMessageThrown(); - - assertEquals(setRangeFromPast.getVendorId(), rejection.getVendorId()); - assertEquals(setRangeFromPast.getMenuId(), rejection.getMenuId()); - assertEquals(setRangeFromPast.getMenuDateRange(), rejection.getMenuDateRange()); - } - - @Test - @DisplayName("produce `CannotSetDateRange` rejection if vendor already has menu on this date range") - void produceRejectionIfMenuExists() { - final AddVendor addVendor = TestVendorCommandFactory.addVendorInstance(); - dispatchCommand(aggregate, envelopeOf(addVendor)); - final ImportMenu importMenu = TestVendorCommandFactory.importMenuInstance(); - dispatchCommand(aggregate, envelopeOf(importMenu)); - - final SetDateRangeForMenu setRange = TestVendorCommandFactory.setDateRangeForMenuInstance(); - dispatchCommand(aggregate, envelopeOf(setRange)); - - final Throwable t = assertThrows(Throwable.class, - () -> dispatchCommand(aggregate, envelopeOf(setRange))); - final Throwable cause = Throwables.getRootCause(t); - assertThat(cause, instanceOf(CannotSetDateRange.class)); - - @SuppressWarnings("ConstantConditions") // Instance type checked before. - final Rejections.CannotSetDateRange rejection = - ((CannotSetDateRange) cause).getMessageThrown(); - - assertEquals(setRange.getVendorId(), rejection.getVendorId()); - assertEquals(setRange.getMenuId(), rejection.getMenuId()); - assertEquals(setRange.getMenuDateRange(), rejection.getMenuDateRange()); - } -} diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/FullMenuViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/FullMenuViewProjectionTest.java new file mode 100644 index 00000000..8fb8a1f5 --- /dev/null +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/FullMenuViewProjectionTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.projection; + +import javaclasses.mealorder.c.event.MenuImported; +import javaclasses.mealorder.q.FullMenuViewProjection; +import javaclasses.mealorder.testdata.TestValues; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.VendorEvents.menuImportedInstance; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class FullMenuViewProjectionTest extends ProjectionTest { + private FullMenuViewProjection projection; + + @BeforeEach + void setUp() { + projection = new FullMenuViewProjection(TestValues.MENU_ID); + } + + @Nested + @DisplayName("MenuImported event should be interpreted by FullMenuViewProjection") + class MenuImportedEvent { + + @Test + @DisplayName("Should set dates with menus") + void addView() { + final MenuImported menuImported = menuImportedInstance(); + dispatch(projection, createEvent(menuImported)); + + assertEquals(menuImported.getMenuId(), projection.getState() + .getMenuId()); + assertEquals(menuImported.getMenuDateRange(), projection.getState() + .getMenuDateRange()); + assertEquals(3, projection.getState() + .getDishesByCategoryList() + .size()); + + } + } +} diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuCalendarViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuCalendarViewProjectionTest.java index 5809555f..2b7dd324 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuCalendarViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuCalendarViewProjectionTest.java @@ -20,7 +20,7 @@ package javaclasses.mealorder.q.projection; -import javaclasses.mealorder.c.event.DateRangeForMenuSet; +import javaclasses.mealorder.c.event.MenuImported; import javaclasses.mealorder.q.MenuCalendarItem; import javaclasses.mealorder.q.MenuCalendarViewProjection; import org.junit.jupiter.api.BeforeEach; @@ -31,7 +31,7 @@ import java.util.List; import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; -import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.VendorEvents.dateRangeForMenuSetInstance; +import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.VendorEvents.menuImportedInstance; import static org.junit.jupiter.api.Assertions.assertEquals; public class MenuCalendarViewProjectionTest extends ProjectionTest { @@ -43,14 +43,14 @@ void setUp() { } @Nested - @DisplayName("DateRangeForMenuSet event should be interpreted by MenuCalendarViewProjection") - class PurchaseOrderSentEvent { + @DisplayName("MenuImported event should be interpreted by MenuCalendarViewProjection") + class MenuImportedEvent { @Test @DisplayName("Should set dates with menus") void addView() { - final DateRangeForMenuSet dateRangeForMenuSet = dateRangeForMenuSetInstance(); - dispatch(projection, createEvent(dateRangeForMenuSet)); + final MenuImported menuImported = menuImportedInstance(); + dispatch(projection, createEvent(menuImported)); final List calendarItems = projection.getState() .getCalendarItemList(); assertEquals(25, calendarItems.size()); diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java index e641674a..6b94ae82 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java @@ -21,7 +21,6 @@ package javaclasses.mealorder.q.projection; import javaclasses.mealorder.MenuListId; -import javaclasses.mealorder.c.event.DateRangeForMenuSet; import javaclasses.mealorder.c.event.MenuImported; import javaclasses.mealorder.c.event.PurchaseOrderCreated; import javaclasses.mealorder.q.MenuItem; @@ -36,7 +35,6 @@ import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderCreatedInstance2; -import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.VendorEvents.dateRangeForMenuSetInstance; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.VendorEvents.menuImportedInstance; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -62,86 +60,38 @@ void addView() { dispatch(projection, createEvent(menuImported)); final List menuList = projection.getState() .getMenuList(); - assertEquals(3, menuList.get(0) - .getDishesByCategoryList() - .size()); - assertEquals("Второе блюдо", menuList.get(0) - .getDishesByCategoryList() - .get(0) - .getCategory() - .getValue()); - assertEquals(3, menuList.get(0) - .getDishesByCategoryList() - .get(0) - .getDishesList() - .size()); - assertEquals("Картофель", menuList.get(0) - .getDishesByCategoryList() - .get(0) - .getDishesList() - .get(0) - .getName()); - } - } - - @Nested - @DisplayName("DateRangeForMenuSet event should be interpreted by MenuListViewProjection") - class DateRangeForMenuSetEvent { - @Test - @DisplayName("Should set dates with menus") - void addView() { - final MenuImported menuImported = menuImportedInstance(); - dispatch(projection, createEvent(menuImported)); - final DateRangeForMenuSet dateRangeForMenuSet = dateRangeForMenuSetInstance(); - dispatch(projection, createEvent(dateRangeForMenuSet)); - final List menuList = projection.getState() - .getMenuList(); - assertEquals(25, menuList.get(0) - .getMenuDaysList() - .size()); - assertEquals(18, menuList.get(0) - .getMenuDaysList() - .get(5) - .getDate() + assertEquals(menuList.get(1) + .getDishesByCategoryList(), menuList.get(0) + .getDishesByCategoryList()); + assertEquals(25, menuList.size()); + assertEquals(18, menuList.get(5) + .getMenuDate() .getDay()); - assertEquals(2, menuList.get(0) - .getMenuDaysList() - .get(5) - .getDate() - .getMonthValue()); - assertEquals(2017, menuList.get(0) - .getMenuDaysList() - .get(5) - .getDate() + assertEquals(2017, menuList.get(5) + .getMenuDate() .getYear()); + assertEquals(2, menuList.get(5) + .getMenuDate() + .getMonthValue()); + assertEquals(true, menuList.get(5) + .getIsAvilable()); } - } - @Nested - @DisplayName("PurchaseOrderCreated event should be interpreted by MenuListViewProjection") - class PurchaseOrderCreatedEvent { @Test @DisplayName("Should disable menu") - void addView() { + void addView2() { final MenuImported menuImported = menuImportedInstance(); dispatch(projection, createEvent(menuImported)); - final DateRangeForMenuSet dateRangeForMenuSet = dateRangeForMenuSetInstance(); - dispatch(projection, createEvent(dateRangeForMenuSet)); final PurchaseOrderCreated purchaseOrderCreated = purchaseOrderCreatedInstance2(); dispatch(projection, createEvent(purchaseOrderCreated)); - assertFalse(projection.getState() .getMenuList() - .get(0) - .getMenuDaysList() .get(18) - .getIsAvailable()); + .getIsAvilable()); assertTrue(projection.getState() .getMenuList() - .get(0) - .getMenuDaysList() - .get(17) - .getIsAvailable()); + .get(19) + .getIsAvilable()); } } } diff --git a/model/src/main/proto/javaclasses/mealorder/c/commands.proto b/model/src/main/proto/javaclasses/mealorder/c/commands.proto index 3c4e4a10..398bbf4f 100644 --- a/model/src/main/proto/javaclasses/mealorder/c/commands.proto +++ b/model/src/main/proto/javaclasses/mealorder/c/commands.proto @@ -92,23 +92,9 @@ message ImportMenu { // The collection of dishes. repeated Dish dish = 4 [(required) = true]; -} - -// Sets a menu date range. -// -message SetDateRangeForMenu { - - // The identifier of a vendor. - VendorId vendor_id = 1 [(required) = true]; - - // The identifier of a menu. - MenuId menu_id = 2 [(required) = true]; - - // The identifier of the user who sets a menu date range. - UserId user_id = 3 [(required) = true]; // A menu date range that should be set. - MenuDateRange menu_date_range = 4 [(required) = true]; + MenuDateRange menu_date_range = 5 [(required) = true]; } // Creates a new order. diff --git a/model/src/main/proto/javaclasses/mealorder/c/events.proto b/model/src/main/proto/javaclasses/mealorder/c/events.proto index 64bd94af..02f71063 100644 --- a/model/src/main/proto/javaclasses/mealorder/c/events.proto +++ b/model/src/main/proto/javaclasses/mealorder/c/events.proto @@ -101,26 +101,9 @@ message MenuImported { // The collection of menu dishes. repeated Dish dish = 5 [(required) = true]; -} - -// The event reflecting a menu active date range set. -// -message DateRangeForMenuSet { - - // The identifier of a vendor. - VendorId vendor_id = 1 [(required) = true]; - - // The identifier of a menu. - MenuId menu_id = 2 [(required) = true]; - - // The identifier of the user who set date range. - UserId who_set = 3 [(required) = true]; - - // Was set at this time. - google.protobuf.Timestamp when_set = 4 [(required) = true]; // Date range that has been set. - MenuDateRange menu_date_range = 5 [(required) = true]; + MenuDateRange menu_date_range = 6 [(required) = true]; } // The event signalizing about the successful creation of an order. diff --git a/model/src/main/proto/javaclasses/mealorder/identifiers.proto b/model/src/main/proto/javaclasses/mealorder/identifiers.proto index 0673c4fd..1df8d9e3 100644 --- a/model/src/main/proto/javaclasses/mealorder/identifiers.proto +++ b/model/src/main/proto/javaclasses/mealorder/identifiers.proto @@ -39,7 +39,7 @@ import "javaclasses/mealorder/attributes.proto"; // message VendorListId { - // The ID of the vendor list + // The ID of the vendor list. string value = 1 [(required) = true]; } diff --git a/model/src/main/proto/javaclasses/mealorder/q/projections.proto b/model/src/main/proto/javaclasses/mealorder/q/projections.proto index 1fec8040..3d9cce5d 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/projections.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/projections.proto @@ -75,7 +75,7 @@ message MenuCalendarView { MenuCalendarId menu_calendar_id = 1; // The collection of calendar items (dates). - repeated MenuCalendarItem calendar_item = 2; + repeated MenuCalendarItem calendar_item = 2 [(required) = true]; } // The projection state of an order list. @@ -97,6 +97,25 @@ message OrderListView { // **** Projections for UI role Admin. **** +// The projection state of the full menu item. +// +// This view has menu with date range. +// +message FullMenuView { + + // // The identifier of a full menu. + MenuId menu_id = 1; + + // The vendor name. + VendorName vendor_name = 2 [(required) = true]; + + // The collection of categories. + repeated DishesByCategory dishesByCategory = 3; + + // A date range for a menu. + MenuDateRange menu_date_range = 4 [(required) = true]; +} + // The projection state of the vendor list. // // Singleton, because there is only one list of vendors. @@ -136,7 +155,7 @@ message PurchaseOrderDetailsByDishView { PurchaseOrderStatus purchase_order_status = 2; // The collection of dishes. - repeated DishItem dish = 3; + repeated DishItem dish = 3 [(required) = true]; } // The projection state of a purchase order details view @@ -154,7 +173,7 @@ message PurchaseOrderDetailsByUserView { PurchaseOrderStatus purchase_order_status = 2; // The collection of orders. - repeated UserOrderDetails order = 3; + repeated UserOrderDetails order = 3 [(required) = true]; } // The projection state of a monthly spendings report view. diff --git a/model/src/main/proto/javaclasses/mealorder/q/values.proto b/model/src/main/proto/javaclasses/mealorder/q/values.proto index 2eefe327..e18e0b9e 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/values.proto @@ -50,8 +50,11 @@ message MenuItem { // The collection of categories. repeated DishesByCategory dishesByCategory = 2 [(required) = true]; - // Date range when a menu is available. - repeated MenuForDay menu_days = 3; + // A date on which a menu is intended. + spine.time.LocalDate menu_date = 3 [(required) = true]; + + // Indicates if a menu is available for user. + bool is_avilable = 4 [(required) = true]; } // Dishes grouped by category. diff --git a/model/src/main/proto/javaclasses/mealorder/values.proto b/model/src/main/proto/javaclasses/mealorder/values.proto index 62c13bf2..150f5ca3 100644 --- a/model/src/main/proto/javaclasses/mealorder/values.proto +++ b/model/src/main/proto/javaclasses/mealorder/values.proto @@ -36,19 +36,6 @@ import "spine/change/change.proto"; import "spine/net/email_address.proto"; import "spine/time/time.proto"; -// Day with status. -// -// If not available this menu will be disabled on UI. -// -message MenuForDay { - - // Menu date - spine.time.LocalDate date = 1 [(required) = true]; - - // If available a user can add dishes to his order. - bool is_available = 2 [(required) = true]; -} - // Name of a category. // // Probably it has fixed values. diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java index 8b653948..93953bb0 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestMealOrderEventFactory.java @@ -36,7 +36,6 @@ import javaclasses.mealorder.VendorChange; import javaclasses.mealorder.VendorId; import javaclasses.mealorder.VendorName; -import javaclasses.mealorder.c.event.DateRangeForMenuSet; import javaclasses.mealorder.c.event.DishAddedToOrder; import javaclasses.mealorder.c.event.DishRemovedFromOrder; import javaclasses.mealorder.c.event.MenuImported; @@ -70,6 +69,7 @@ public class TestMealOrderEventFactory { .setStatus( PurchaseOrderStatus.CREATED) .build(); + private TestMealOrderEventFactory() { } @@ -103,6 +103,7 @@ public static PurchaseOrderSent purchaseOrderSentInstance2() { return purchaseOrderSentInstance(PURCHASE_ORDER2, TestValues.USER_ID3.getEmail(), TestValues.EMAIL); } + public static PurchaseOrderSent purchaseOrderSentInstance(PurchaseOrder po, EmailAddress senderEmail, EmailAddress vendorEmail) { @@ -125,6 +126,7 @@ public static PurchaseOrderDelivered purchaseOrderDeliveredInstance2() { return purchaseOrderDeliveredInstance(TestValues.PURCHASE_ORDER_ID2, TestValues.USER_ID); } + private static PurchaseOrderDelivered purchaseOrderDeliveredInstance( PurchaseOrderId purchaseOrderId, UserId userId) { @@ -167,34 +169,15 @@ public static class VendorEvents { private VendorEvents() { } - public static DateRangeForMenuSet dateRangeForMenuSetInstance() { - return dateRangeForMenuSetInstance(TestValues.VENDOR_ID, TestValues.MENU_ID, - TestValues.USER_ID, TestValues.MENU_DATE_RANGE2); - } - - private static DateRangeForMenuSet dateRangeForMenuSetInstance(VendorId vendorId, - MenuId menuId, - UserId userId, - MenuDateRange menuDateRange) { - final Timestamp currentTime = getCurrentTime(); - final DateRangeForMenuSet result = - DateRangeForMenuSet.newBuilder() - .setVendorId(vendorId) - .setMenuId(menuId) - .setWhoSet(userId) - .setWhenSet(currentTime) - .setMenuDateRange(menuDateRange) - .build(); - return result; - } - public static MenuImported menuImportedInstance() { return menuImportedInstance(TestValues.VENDOR_ID, TestValues.MENU_ID, - TestValues.USER_ID, TestValues.BIG_MENU); + TestValues.USER_ID, TestValues.BIG_MENU, + TestValues.MENU_DATE_RANGE2); } private static MenuImported menuImportedInstance(VendorId vendorId, MenuId menuId, - UserId whoImported, List dishes) { + UserId whoImported, List dishes, + MenuDateRange menuDateRange) { final Timestamp currentTime = getCurrentTime(); final MenuImported result = MenuImported.newBuilder() @@ -203,6 +186,7 @@ private static MenuImported menuImportedInstance(VendorId vendorId, MenuId menuI .setWhoImported(whoImported) .setWhenImported(currentTime) .addAllDish(dishes) + .setMenuDateRange(menuDateRange) .build(); return result; } @@ -262,6 +246,7 @@ public static DishAddedToOrder dishAddedToOrderInstance() { public static DishAddedToOrder dishAddedToOrderInstance2() { return dishAddedToOrderInstance(TestValues.ORDER_ID2, TestValues.DISH2); } + private static DishAddedToOrder dishAddedToOrderInstance(OrderId orderId, Dish dish) { final Timestamp currentTime = getCurrentTime(); final DishAddedToOrder result = diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestVendorCommandFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestVendorCommandFactory.java index 3f54889a..7e8cab9d 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestVendorCommandFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestVendorCommandFactory.java @@ -32,10 +32,20 @@ import javaclasses.mealorder.VendorName; import javaclasses.mealorder.c.command.AddVendor; import javaclasses.mealorder.c.command.ImportMenu; -import javaclasses.mealorder.c.command.SetDateRangeForMenu; import javaclasses.mealorder.c.command.UpdateVendor; -import static javaclasses.mealorder.testdata.TestValues.*; +import static javaclasses.mealorder.testdata.TestValues.DISH1; +import static javaclasses.mealorder.testdata.TestValues.DISH2; +import static javaclasses.mealorder.testdata.TestValues.EMAIL; +import static javaclasses.mealorder.testdata.TestValues.MENU_DATE_RANGE; +import static javaclasses.mealorder.testdata.TestValues.MENU_ID; +import static javaclasses.mealorder.testdata.TestValues.PHONE_NUMBER1; +import static javaclasses.mealorder.testdata.TestValues.PHONE_NUMBER2; +import static javaclasses.mealorder.testdata.TestValues.PO_DAILY_DEADLINE; +import static javaclasses.mealorder.testdata.TestValues.USER_ID; +import static javaclasses.mealorder.testdata.TestValues.VENDOR_CHANGE; +import static javaclasses.mealorder.testdata.TestValues.VENDOR_ID; +import static javaclasses.mealorder.testdata.TestValues.VENDOR_NAME; /** * A factory of the vendor commands for the test needs. @@ -119,7 +129,8 @@ public static UpdateVendor updateVendorInstance(VendorId vendorId, UserId userId * @return the {@code ImportMenu} instance */ public static ImportMenu importMenuInstance() { - final ImportMenu result = importMenuInstance(VENDOR_ID, USER_ID, MENU_ID, DISH1, DISH2); + final ImportMenu result = importMenuInstance(VENDOR_ID, USER_ID, MENU_ID, MENU_DATE_RANGE, + DISH1, DISH2); return result; } @@ -133,6 +144,7 @@ public static ImportMenu importMenuInstance() { * @return the {@code CreateBasicTask} instance */ public static ImportMenu importMenuInstance(VendorId vendorId, UserId userId, MenuId menuId, + MenuDateRange menuDateRange, Dish... dishes) { final ImportMenu result = ImportMenu.newBuilder() @@ -141,40 +153,8 @@ public static ImportMenu importMenuInstance(VendorId vendorId, UserId userId, Me .setMenuId(menuId) .addDish(dishes[0]) .addDish(dishes[1]) + .setMenuDateRange(menuDateRange) .build(); return result; } - - /** - * Provides a pre-configured {@link SetDateRangeForMenu} instance. - * - * @return the {@code ImportMenu} instance - */ - public static SetDateRangeForMenu setDateRangeForMenuInstance() { - final SetDateRangeForMenu result = setDateRangeForMenuInstance(VENDOR_ID, MENU_ID, USER_ID, - MENU_DATE_RANGE); - return result; - } - - /** - * Provides a pre-configured {@link SetDateRangeForMenu} instance. - * - * @param vendorId the identifier of a created vendor - * @param userId the identifier of the user who updates vendor profile - * @param menuId the identifier of the imported menu - * @param menuDateRange a menu date range that should be set. - * @return the {@code CreateBasicTask} instance - */ - public static SetDateRangeForMenu setDateRangeForMenuInstance(VendorId vendorId, MenuId menuId, - UserId userId, - MenuDateRange menuDateRange) { - - final SetDateRangeForMenu result = SetDateRangeForMenu.newBuilder() - .setVendorId(vendorId) - .setUserId(userId) - .setMenuId(menuId) - .setMenuDateRange(menuDateRange) - .build(); - return result; - } } From 87cabf899256cd2b1c8a3dd9007788173ee827ba Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Thu, 26 Apr 2018 18:14:31 +0300 Subject: [PATCH 56/66] Reformat code --- .../javaclasses/mealorder/q/MenuCalendarViewProjection.java | 1 - .../java/javaclasses/mealorder/q/MenuListViewProjection.java | 3 --- .../java/javaclasses/mealorder/q/OrderListViewProjection.java | 2 -- 3 files changed, 6 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java index 6505dace..260fe5fb 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java @@ -70,5 +70,4 @@ void on(MenuImported event) { .build()); }); } - } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java index 09a90f08..2fdaa8bd 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java @@ -74,7 +74,6 @@ void on(MenuImported event) { .build(); getBuilder().addMenu(menuItem); }); - } @Subscribe @@ -93,7 +92,5 @@ void on(PurchaseOrderCreated event) { getBuilder().setMenu(index, newMenuItem); } }); - } - } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java index ef4a35c5..3a7cda1f 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java @@ -52,7 +52,6 @@ public OrderListViewProjection(OrderListId id) { @Subscribe void on(DishAddedToOrder event) { - final OrderId orderId = event.getOrderId(); final DishItem dish = DishItem.newBuilder() .setName(event.getDish() @@ -134,5 +133,4 @@ private int getDishIndexFromOrder(DishId dishId, OrderItem order) { }); return index[0]; } - } From 98f8fc1c4a6abecb714f44de7a57ec892002dc2b Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Fri, 27 Apr 2018 13:17:04 +0300 Subject: [PATCH 57/66] Add repositories and routing for projections --- .../mealorder/q/MenuListViewProjection.java | 14 ++- .../javaclasses/mealorder/q/Projections.java | 2 +- .../q/PurchaseOrderItemViewProjection.java | 5 +- .../q/repository/FullMenuViewRepository.java | 53 +++++++++ .../MenuCalendarViewRepository.java | 47 ++++++++ .../q/repository/MenuListViewRepository.java | 53 +++++++++ .../MonthlySpendingsReportViewRepository.java | 72 ++++++++++++ .../q/repository/OrderListViewRepository.java | 104 ++++++++++++++++++ ...chaseOrderDetailsByDishViewRepository.java | 104 ++++++++++++++++++ ...chaseOrderDetailsByUserViewRepository.java | 104 ++++++++++++++++++ .../PurchaseOrderItemViewRepository.java | 89 +++++++++++++++ .../repository/VendorListViewRepository.java | 54 +++++++++ .../MenuListViewProjectionTest.java | 6 +- .../OrderListViewProjectionTest.java | 1 + .../PurchaseOrderItemViewProjectionTest.java | 12 +- .../javaclasses/mealorder/identifiers.proto | 8 -- .../javaclasses/mealorder/q/projections.proto | 2 + 17 files changed, 708 insertions(+), 22 deletions(-) create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/repository/FullMenuViewRepository.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/repository/MenuCalendarViewRepository.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/repository/MenuListViewRepository.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/repository/MonthlySpendingsReportViewRepository.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/repository/OrderListViewRepository.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/repository/PurchaseOrderDetailsByDishViewRepository.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/repository/PurchaseOrderDetailsByUserViewRepository.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/repository/PurchaseOrderItemViewRepository.java create mode 100644 api-java/src/main/java/javaclasses/mealorder/q/repository/VendorListViewRepository.java diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java index 2fdaa8bd..0a6d1820 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java @@ -37,7 +37,19 @@ import static javaclasses.mealorder.q.Projections.getDatesBetween; public class MenuListViewProjection extends Projection { - + /** + * {@link MenuListViewProjection} is a singleton. + * + *

The {@code ID} value should be the same for all JVMs + * to support work with the same projection from execution to execution. + */ + public static final MenuListId ID = MenuListId.newBuilder() + .setDate(LocalDate.newBuilder() + .setDay(2) + .setMonthValue(3) + .setYear(2018) + .build()) + .build(); /** * Creates a new instance. * diff --git a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java index 637c3738..a5aaff3e 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java @@ -39,7 +39,7 @@ public final class Projections { private Projections() { } - static List getDatesBetween( + public static List getDatesBetween( LocalDate startDate, LocalDate endDate) { java.time.LocalDate start = java.time.LocalDate.of(startDate.getYear(), startDate.getMonthValue(), diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderItemViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderItemViewProjection.java index 5c09c4f3..499fae5c 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderItemViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderItemViewProjection.java @@ -24,7 +24,6 @@ import io.spine.server.entity.storage.Column; import io.spine.server.projection.Projection; import javaclasses.mealorder.PurchaseOrderId; -import javaclasses.mealorder.PurchaseOrderListId; import javaclasses.mealorder.PurchaseOrderStatus; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; @@ -34,7 +33,7 @@ import javax.annotation.Nullable; -public class PurchaseOrderItemViewProjection extends Projection { +public class PurchaseOrderItemViewProjection extends Projection { /** * Creates a new instance. @@ -42,7 +41,7 @@ public class PurchaseOrderItemViewProjection extends Projection { + + public FullMenuViewRepository() { + super(); + setUpEventRoute(); + } + + /** + * Adds the {@link io.spine.server.route.EventRoute EventRoute}s to the repository. + * + *

Override this method in successor classes, otherwise all successors will use + * {@code MyListViewProjection.ID}. + */ + protected void setUpEventRoute() { + final EventRouting routing = getEventRouting(); + routing.route(MenuImported.class, + (message, context) -> { + final MenuImported menuImported = (MenuImported) message; + return singleton(menuImported.getMenuId()); + }); + } +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/repository/MenuCalendarViewRepository.java b/api-java/src/main/java/javaclasses/mealorder/q/repository/MenuCalendarViewRepository.java new file mode 100644 index 00000000..8e7abba3 --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/repository/MenuCalendarViewRepository.java @@ -0,0 +1,47 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.repository; + +import io.spine.server.projection.ProjectionRepository; +import javaclasses.mealorder.MenuCalendarId; +import javaclasses.mealorder.q.MenuCalendarViewProjection; +import javaclasses.mealorder.q.projection.MenuCalendarView; + +import static java.util.Collections.singleton; + +public class MenuCalendarViewRepository extends ProjectionRepository { + + public MenuCalendarViewRepository() { + super(); + setUpEventRoute(); + } + + /** + * Adds the {@link io.spine.server.route.EventRoute EventRoute}s to the repository. + * + *

Override this method in successor classes, otherwise all successors will use + * {@code MyListViewProjection.ID}. + */ + protected void setUpEventRoute() { + getEventRouting().replaceDefault( + ((message, context) -> singleton(MenuCalendarViewProjection.ID))); + } +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/repository/MenuListViewRepository.java b/api-java/src/main/java/javaclasses/mealorder/q/repository/MenuListViewRepository.java new file mode 100644 index 00000000..8307d902 --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/repository/MenuListViewRepository.java @@ -0,0 +1,53 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.repository; + +import io.spine.server.projection.ProjectionRepository; +import io.spine.server.route.EventRouting; +import javaclasses.mealorder.MenuListId; +import javaclasses.mealorder.c.event.MenuImported; +import javaclasses.mealorder.c.event.PurchaseOrderCreated; +import javaclasses.mealorder.q.MenuListViewProjection; +import javaclasses.mealorder.q.projection.MenuListView; + +import static java.util.Collections.singleton; + +public class MenuListViewRepository extends ProjectionRepository { + + public MenuListViewRepository() { + super(); + setUpEventRoute(); + } + + /** + * Adds the {@link io.spine.server.route.EventRoute EventRoute}s to the repository. + * + *

Override this method in successor classes, otherwise all successors will use + * {@code MyListViewProjection.ID}. + */ + protected void setUpEventRoute() { + final EventRouting routing = getEventRouting(); + routing.route(MenuImported.class, + (message, context) -> singleton(MenuListViewProjection.ID)); + routing.route(PurchaseOrderCreated.class, + (message, context) -> singleton(MenuListViewProjection.ID)); + } +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/repository/MonthlySpendingsReportViewRepository.java b/api-java/src/main/java/javaclasses/mealorder/q/repository/MonthlySpendingsReportViewRepository.java new file mode 100644 index 00000000..d574e791 --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/repository/MonthlySpendingsReportViewRepository.java @@ -0,0 +1,72 @@ +package javaclasses.mealorder.q.repository; + +import io.spine.server.projection.ProjectionRepository; +import io.spine.server.route.EventRouting; +import io.spine.time.MonthOfYear; +import javaclasses.mealorder.LocalMonth; +import javaclasses.mealorder.MonthlySpendingsReportId; +import javaclasses.mealorder.c.event.PurchaseOrderDelivered; +import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.q.MonthlySpendingsReportViewProjection; +import javaclasses.mealorder.q.projection.MonthlySpendingsReportView; + +import static java.util.Collections.singleton; + +public class MonthlySpendingsReportViewRepository extends ProjectionRepository { + + public MonthlySpendingsReportViewRepository() { + super(); + setUpEventRoute(); + } + + /** + * Adds the {@link io.spine.server.route.EventRoute EventRoute}s to the repository. + * + *

Override this method in successor classes, otherwise all successors will use + * {@code MyListViewProjection.ID}. + */ + protected void setUpEventRoute() { + + final EventRouting routing = getEventRouting(); + routing.route(PurchaseOrderSent.class, + (message, context) -> { + final PurchaseOrderSent purchaseOrderSent = (PurchaseOrderSent) message; + final int year = purchaseOrderSent.getPurchaseOrder() + .getId() + .getPoDate() + .getYear(); + final MonthOfYear month = purchaseOrderSent.getPurchaseOrder() + .getId() + .getPoDate() + .getMonth(); + final LocalMonth localMonth = LocalMonth.newBuilder() + .setYear(year) + .setMonth(month) + .build(); + final MonthlySpendingsReportId monthlySpendingsReportId = MonthlySpendingsReportId.newBuilder() + .setMonth( + localMonth) + .build(); + return singleton(monthlySpendingsReportId); + }); + routing.route(PurchaseOrderDelivered.class, + (message, context) -> { + final PurchaseOrderDelivered purchaseOrderDelivered = (PurchaseOrderDelivered) message; + final int year = purchaseOrderDelivered.getId() + .getPoDate() + .getYear(); + final MonthOfYear month = purchaseOrderDelivered.getId() + .getPoDate() + .getMonth(); + final LocalMonth localMonth = LocalMonth.newBuilder() + .setYear(year) + .setMonth(month) + .build(); + final MonthlySpendingsReportId monthlySpendingsReportId = MonthlySpendingsReportId.newBuilder() + .setMonth( + localMonth) + .build(); + return singleton(monthlySpendingsReportId); + }); + } +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/repository/OrderListViewRepository.java b/api-java/src/main/java/javaclasses/mealorder/q/repository/OrderListViewRepository.java new file mode 100644 index 00000000..dfac8f4c --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/repository/OrderListViewRepository.java @@ -0,0 +1,104 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.repository; + +import io.spine.server.projection.ProjectionRepository; +import io.spine.server.route.EventRouting; +import io.spine.time.LocalDate; +import javaclasses.mealorder.OrderListId; +import javaclasses.mealorder.UserId; +import javaclasses.mealorder.c.event.DishAddedToOrder; +import javaclasses.mealorder.c.event.DishRemovedFromOrder; +import javaclasses.mealorder.c.event.OrderCanceled; +import javaclasses.mealorder.c.event.OrderProcessed; +import javaclasses.mealorder.q.OrderListViewProjection; +import javaclasses.mealorder.q.projection.OrderListView; + +import static java.util.Collections.singleton; + +public class OrderListViewRepository extends ProjectionRepository { + + public OrderListViewRepository() { + super(); + setUpEventRoute(); + } + + /** + * Adds the {@link io.spine.server.route.EventRoute EventRoute}s to the repository. + * + *

Override this method in successor classes, otherwise all successors will use + * {@code MyListViewProjection.ID}. + */ + protected void setUpEventRoute() { + + final EventRouting routing = getEventRouting(); + routing.route(DishAddedToOrder.class, + (message, context) -> { + final LocalDate date = message.getOrderId() + .getOrderDate(); + final UserId userId = message.getOrderId() + .getUserId(); + final OrderListId orderListId = OrderListId.newBuilder() + .setOrderDate(date) + .setUserId(userId) + .build(); + return singleton(orderListId); + }); + routing.route(DishRemovedFromOrder.class, + (message, context) -> { + final LocalDate date = message.getOrderId() + .getOrderDate(); + final UserId userId = message.getOrderId() + .getUserId(); + final OrderListId orderListId = OrderListId.newBuilder() + .setOrderDate(date) + .setUserId(userId) + .build(); + return singleton(orderListId); + }); + routing.route(OrderCanceled.class, + (message, context) -> { + final LocalDate date = message.getOrderId() + .getOrderDate(); + final UserId userId = message.getOrderId() + .getUserId(); + final OrderListId orderListId = OrderListId.newBuilder() + .setOrderDate(date) + .setUserId(userId) + .build(); + return singleton(orderListId); + }); + routing.route(OrderProcessed.class, + (message, context) -> { + final LocalDate date = message.getOrder() + .getId() + .getOrderDate(); + final UserId userId = message.getOrder() + .getId() + .getUserId(); + final OrderListId orderListId = OrderListId.newBuilder() + .setOrderDate(date) + .setUserId(userId) + .build(); + return singleton(orderListId); + }); + } +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/repository/PurchaseOrderDetailsByDishViewRepository.java b/api-java/src/main/java/javaclasses/mealorder/q/repository/PurchaseOrderDetailsByDishViewRepository.java new file mode 100644 index 00000000..66411924 --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/repository/PurchaseOrderDetailsByDishViewRepository.java @@ -0,0 +1,104 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.repository; + +import io.spine.server.projection.ProjectionRepository; +import io.spine.server.route.EventRouting; +import javaclasses.mealorder.PurchaseOrderId; +import javaclasses.mealorder.c.event.PurchaseOrderCreated; +import javaclasses.mealorder.c.event.PurchaseOrderDelivered; +import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.c.event.PurchaseOrderValidationFailed; +import javaclasses.mealorder.q.PurchaseOrderDetailsByDishViewProjection; +import javaclasses.mealorder.q.projection.PurchaseOrderDetailsByDishView; + +import static java.util.Collections.singleton; + +@SuppressWarnings("Duplicates") /* Has the same logic for routing as + PurchaseOrderDetailsByUserViewRepository*/ +public class PurchaseOrderDetailsByDishViewRepository extends ProjectionRepository { + + public PurchaseOrderDetailsByDishViewRepository() { + super(); + setUpEventRoute(); + } + + /** + * Adds the {@link io.spine.server.route.EventRoute EventRoute}s to the repository. + * + *

Override this method in successor classes, otherwise all successors will use + * {@code MyListViewProjection.ID}. + */ + protected void setUpEventRoute() { + + final EventRouting routing = getEventRouting(); + routing.route(PurchaseOrderCreated.class, + (message, context) -> { + final PurchaseOrderId purchaseOrderId = PurchaseOrderId.newBuilder() + .setVendorId( + message.getId() + .getVendorId()) + .setPoDate( + message.getId() + .getPoDate()) + .build(); + return singleton(purchaseOrderId); + }); + routing.route(PurchaseOrderDelivered.class, + (message, context) -> { + final PurchaseOrderId purchaseOrderId = PurchaseOrderId.newBuilder() + .setVendorId( + message.getId() + .getVendorId()) + .setPoDate( + message.getId() + .getPoDate()) + .build(); + return singleton(purchaseOrderId); + }); + routing.route(PurchaseOrderSent.class, + (message, context) -> { + final PurchaseOrderId purchaseOrderId = PurchaseOrderId.newBuilder() + .setVendorId( + message.getPurchaseOrder() + .getId() + .getVendorId()) + .setPoDate( + message.getPurchaseOrder() + .getId() + .getPoDate()) + .build(); + return singleton(purchaseOrderId); + }); + routing.route(PurchaseOrderValidationFailed.class, + (message, context) -> { + final PurchaseOrderId purchaseOrderId = PurchaseOrderId.newBuilder() + .setVendorId( + message.getId() + .getVendorId()) + .setPoDate( + message.getId() + .getPoDate()) + .build(); + return singleton(purchaseOrderId); + }); + } +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/repository/PurchaseOrderDetailsByUserViewRepository.java b/api-java/src/main/java/javaclasses/mealorder/q/repository/PurchaseOrderDetailsByUserViewRepository.java new file mode 100644 index 00000000..0f558a9e --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/repository/PurchaseOrderDetailsByUserViewRepository.java @@ -0,0 +1,104 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.repository; + +import io.spine.server.projection.ProjectionRepository; +import io.spine.server.route.EventRouting; +import javaclasses.mealorder.PurchaseOrderId; +import javaclasses.mealorder.c.event.PurchaseOrderCreated; +import javaclasses.mealorder.c.event.PurchaseOrderDelivered; +import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.c.event.PurchaseOrderValidationFailed; +import javaclasses.mealorder.q.PurchaseOrderDetailsByUserViewProjection; +import javaclasses.mealorder.q.projection.PurchaseOrderDetailsByUserView; + +import static java.util.Collections.singleton; + +@SuppressWarnings("Duplicates") /* Has the same logic for routing as + PurchaseOrderDetailsByDishViewRepository*/ +public class PurchaseOrderDetailsByUserViewRepository extends ProjectionRepository { + + public PurchaseOrderDetailsByUserViewRepository() { + super(); + setUpEventRoute(); + } + + /** + * Adds the {@link io.spine.server.route.EventRoute EventRoute}s to the repository. + * + *

Override this method in successor classes, otherwise all successors will use + * {@code MyListViewProjection.ID}. + */ + protected void setUpEventRoute() { + + final EventRouting routing = getEventRouting(); + routing.route(PurchaseOrderCreated.class, + (message, context) -> { + final PurchaseOrderId purchaseOrderId = PurchaseOrderId.newBuilder() + .setVendorId( + message.getId() + .getVendorId()) + .setPoDate( + message.getId() + .getPoDate()) + .build(); + return singleton(purchaseOrderId); + }); + routing.route(PurchaseOrderDelivered.class, + (message, context) -> { + final PurchaseOrderId purchaseOrderId = PurchaseOrderId.newBuilder() + .setVendorId( + message.getId() + .getVendorId()) + .setPoDate( + message.getId() + .getPoDate()) + .build(); + return singleton(purchaseOrderId); + }); + routing.route(PurchaseOrderSent.class, + (message, context) -> { + final PurchaseOrderId purchaseOrderId = PurchaseOrderId.newBuilder() + .setVendorId( + message.getPurchaseOrder() + .getId() + .getVendorId()) + .setPoDate( + message.getPurchaseOrder() + .getId() + .getPoDate()) + .build(); + return singleton(purchaseOrderId); + }); + routing.route(PurchaseOrderValidationFailed.class, + (message, context) -> { + final PurchaseOrderId purchaseOrderId = PurchaseOrderId.newBuilder() + .setVendorId( + message.getId() + .getVendorId()) + .setPoDate( + message.getId() + .getPoDate()) + .build(); + return singleton(purchaseOrderId); + }); + } +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/repository/PurchaseOrderItemViewRepository.java b/api-java/src/main/java/javaclasses/mealorder/q/repository/PurchaseOrderItemViewRepository.java new file mode 100644 index 00000000..67b7386b --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/repository/PurchaseOrderItemViewRepository.java @@ -0,0 +1,89 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.repository; + +import io.spine.server.projection.ProjectionRepository; +import io.spine.server.route.EventRouting; +import javaclasses.mealorder.PurchaseOrderId; +import javaclasses.mealorder.c.event.PurchaseOrderDelivered; +import javaclasses.mealorder.c.event.PurchaseOrderSent; +import javaclasses.mealorder.c.event.PurchaseOrderValidationFailed; +import javaclasses.mealorder.q.PurchaseOrderItemViewProjection; +import javaclasses.mealorder.q.projection.PurchaseOrderItemView; + +import static java.util.Collections.singleton; + +public class PurchaseOrderItemViewRepository extends ProjectionRepository { + + public PurchaseOrderItemViewRepository() { + super(); + setUpEventRoute(); + } + + /** + * Adds the {@link io.spine.server.route.EventRoute EventRoute}s to the repository. + * + *

Override this method in successor classes, otherwise all successors will use + * {@code MyListViewProjection.ID}. + */ + protected void setUpEventRoute() { + + final EventRouting routing = getEventRouting(); + routing.route(PurchaseOrderSent.class, + (message, context) -> { + final PurchaseOrderId purchaseOrderId = PurchaseOrderId.newBuilder() + .setVendorId( + message.getPurchaseOrder() + .getId() + .getVendorId()) + .setPoDate( + message.getPurchaseOrder() + .getId() + .getPoDate()) + .build(); + return singleton(purchaseOrderId); + }); + routing.route(PurchaseOrderDelivered.class, + (message, context) -> { + final PurchaseOrderId purchaseOrderId = PurchaseOrderId.newBuilder() + .setVendorId( + message.getId() + .getVendorId()) + .setPoDate( + message.getId() + .getPoDate()) + .build(); + return singleton(purchaseOrderId); + }); + routing.route(PurchaseOrderValidationFailed.class, + (message, context) -> { + final PurchaseOrderId purchaseOrderId = PurchaseOrderId.newBuilder() + .setVendorId( + message.getId() + .getVendorId()) + .setPoDate( + message.getId() + .getPoDate()) + .build(); + return singleton(purchaseOrderId); + }); + } +} diff --git a/api-java/src/main/java/javaclasses/mealorder/q/repository/VendorListViewRepository.java b/api-java/src/main/java/javaclasses/mealorder/q/repository/VendorListViewRepository.java new file mode 100644 index 00000000..75fd36a6 --- /dev/null +++ b/api-java/src/main/java/javaclasses/mealorder/q/repository/VendorListViewRepository.java @@ -0,0 +1,54 @@ +/* + * Copyright 2018, TeamDev Ltd. All rights reserved. + * + * Redistribution and use in source and/or binary forms, with or without + * modification, must retain the above copyright notice and the following + * disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package javaclasses.mealorder.q.repository; + +import io.spine.server.projection.ProjectionRepository; +import io.spine.server.route.EventRouting; +import javaclasses.mealorder.VendorListId; +import javaclasses.mealorder.c.event.VendorAdded; +import javaclasses.mealorder.c.event.VendorUpdated; +import javaclasses.mealorder.q.VendorListViewProjection; +import javaclasses.mealorder.q.projection.VendorListView; + +import static java.util.Collections.singleton; + +public class VendorListViewRepository extends ProjectionRepository { + + public VendorListViewRepository() { + super(); + setUpEventRoute(); + } + + /** + * Adds the {@link io.spine.server.route.EventRoute EventRoute}s to the repository. + * + *

Override this method in successor classes, otherwise all successors will use + * {@code MyListViewProjection.ID}. + */ + protected void setUpEventRoute() { + + final EventRouting routing = getEventRouting(); + routing.route(VendorAdded.class, + (message, context) -> singleton(VendorListViewProjection.ID)); + routing.route(VendorUpdated.class, + (message, context) -> singleton(VendorListViewProjection.ID)); + } +} diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java index 6b94ae82..f61dddeb 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java @@ -20,12 +20,10 @@ package javaclasses.mealorder.q.projection; -import javaclasses.mealorder.MenuListId; import javaclasses.mealorder.c.event.MenuImported; import javaclasses.mealorder.c.event.PurchaseOrderCreated; import javaclasses.mealorder.q.MenuItem; import javaclasses.mealorder.q.MenuListViewProjection; -import javaclasses.mealorder.testdata.TestValues; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -45,9 +43,7 @@ public class MenuListViewProjectionTest extends ProjectionTest { @BeforeEach void setUp() { - projection = new MenuListViewProjection(MenuListId.newBuilder() - .setDate(TestValues.DATE) - .build()); + projection = new MenuListViewProjection(MenuListViewProjection.ID); } @Nested diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java index fab40ee0..f73bfe93 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/OrderListViewProjectionTest.java @@ -47,6 +47,7 @@ public class OrderListViewProjectionTest extends ProjectionTest { void setUp() { projection = new OrderListViewProjection(OrderListId.newBuilder() .setUserId(TestValues.USER_ID) + .setOrderDate(TestValues.DATE) .build()); } diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderItemViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderItemViewProjectionTest.java index 2ba13bc5..bb694b4b 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderItemViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/PurchaseOrderItemViewProjectionTest.java @@ -20,7 +20,7 @@ package javaclasses.mealorder.q.projection; -import javaclasses.mealorder.PurchaseOrderListId; +import javaclasses.mealorder.PurchaseOrderId; import javaclasses.mealorder.PurchaseOrderStatus; import javaclasses.mealorder.c.event.PurchaseOrderDelivered; import javaclasses.mealorder.c.event.PurchaseOrderSent; @@ -35,6 +35,8 @@ import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderDeliveredInstance; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderSentInstance; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.PurchaseOrderEvents.purchaseOrderValidationFailedInstance; +import static javaclasses.mealorder.testdata.TestValues.DATE; +import static javaclasses.mealorder.testdata.TestValues.VENDOR_ID; import static org.junit.jupiter.api.Assertions.assertEquals; public class PurchaseOrderItemViewProjectionTest extends ProjectionTest { @@ -42,9 +44,11 @@ public class PurchaseOrderItemViewProjectionTest extends ProjectionTest { @BeforeEach void setUp() { - projection = new PurchaseOrderItemViewProjection(PurchaseOrderListId.newBuilder() - .setValue("dsda") - .build()); + projection = new PurchaseOrderItemViewProjection(PurchaseOrderId.newBuilder() + .setVendorId( + VENDOR_ID) + .setPoDate(DATE) + .build()); } @Nested diff --git a/model/src/main/proto/javaclasses/mealorder/identifiers.proto b/model/src/main/proto/javaclasses/mealorder/identifiers.proto index 1df8d9e3..2e69ede5 100644 --- a/model/src/main/proto/javaclasses/mealorder/identifiers.proto +++ b/model/src/main/proto/javaclasses/mealorder/identifiers.proto @@ -43,14 +43,6 @@ message VendorListId { string value = 1 [(required) = true]; } -// The ID of the purchase order list. -// -message PurchaseOrderListId { - - // The ID of the purchase order list. - string value = 1 [(required) = true]; -} - // The ID of the calendar. // message MenuCalendarId { diff --git a/model/src/main/proto/javaclasses/mealorder/q/projections.proto b/model/src/main/proto/javaclasses/mealorder/q/projections.proto index 3d9cce5d..37723d4f 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/projections.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/projections.proto @@ -52,6 +52,8 @@ import "javaclasses/mealorder/values.proto"; // this date. This time is defined in a menu vendor aggregate. See `Vendor` // for more details. // +//Singleton, because menu list is global. +// message MenuListView { // The identifier of a menu list. From 93662141c150a26f7ab9739a6395abc296de7817 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Fri, 27 Apr 2018 13:25:59 +0300 Subject: [PATCH 58/66] Register all repositories in `BoundedContexts` --- .../mealorder/c/BoundedContexts.java | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java b/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java index 74684f35..51976e25 100644 --- a/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java +++ b/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java @@ -26,6 +26,15 @@ import javaclasses.mealorder.c.order.OrderRepository; import javaclasses.mealorder.c.po.PurchaseOrderRepository; import javaclasses.mealorder.c.vendor.VendorRepository; +import javaclasses.mealorder.q.repository.FullMenuViewRepository; +import javaclasses.mealorder.q.repository.MenuCalendarViewRepository; +import javaclasses.mealorder.q.repository.MenuListViewRepository; +import javaclasses.mealorder.q.repository.MonthlySpendingsReportViewRepository; +import javaclasses.mealorder.q.repository.OrderListViewRepository; +import javaclasses.mealorder.q.repository.PurchaseOrderDetailsByDishViewRepository; +import javaclasses.mealorder.q.repository.PurchaseOrderDetailsByUserViewRepository; +import javaclasses.mealorder.q.repository.PurchaseOrderItemViewRepository; +import javaclasses.mealorder.q.repository.VendorListViewRepository; import static com.google.common.base.Preconditions.checkNotNull; @@ -72,15 +81,35 @@ public static BoundedContext create() { public static BoundedContext create(StorageFactory storageFactory) { checkNotNull(storageFactory); final VendorRepository vendorRepository = VendorRepository.getRepository(); - final OrderRepository orderRepository = new OrderRepository(); final PurchaseOrderRepository purchaseOrderRepository = new PurchaseOrderRepository(); + final FullMenuViewRepository fullMenuViewRepository = new FullMenuViewRepository(); + final MenuCalendarViewRepository menuCalendarViewRepository = new MenuCalendarViewRepository(); + final MenuListViewRepository menuListViewRepository = new MenuListViewRepository(); + final MonthlySpendingsReportViewRepository monthlySpendingsReportViewRepository = new MonthlySpendingsReportViewRepository(); + final OrderListViewRepository orderListViewRepository = new OrderListViewRepository(); + final PurchaseOrderDetailsByDishViewRepository poDetailsByDishViewRepository = new PurchaseOrderDetailsByDishViewRepository(); + final PurchaseOrderDetailsByUserViewRepository poDetailsByUserViewRepository = new PurchaseOrderDetailsByUserViewRepository(); + final PurchaseOrderItemViewRepository poItemViewRepository = new PurchaseOrderItemViewRepository(); + final VendorListViewRepository vendorListViewRepository = new VendorListViewRepository(); + final BoundedContext boundedContext = createBoundedContext(storageFactory); boundedContext.register(vendorRepository); boundedContext.register(orderRepository); boundedContext.register(purchaseOrderRepository); + + boundedContext.register(fullMenuViewRepository); + boundedContext.register(menuCalendarViewRepository); + boundedContext.register(menuListViewRepository); + boundedContext.register(monthlySpendingsReportViewRepository); + boundedContext.register(orderListViewRepository); + boundedContext.register(poDetailsByDishViewRepository); + boundedContext.register(poDetailsByUserViewRepository); + boundedContext.register(poItemViewRepository); + boundedContext.register(vendorListViewRepository); + return boundedContext; } From d8b3645750bfd5a4e1c92203f78443ae4db5ea02 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Fri, 27 Apr 2018 15:27:23 +0300 Subject: [PATCH 59/66] Add integration tests for `FullMenuView` --- .../mealorder/c/MealOrderTest.java | 54 +++++++++++++++---- .../mealorder/c/vendor/ImportMenuTest.java | 9 ++-- .../FullMenuViewProjectionTest.java | 4 +- .../mealorder/testdata/TestValues.java | 45 +++++++++++----- .../testdata/TestVendorCommandFactory.java | 28 +++++++--- 5 files changed, 105 insertions(+), 35 deletions(-) diff --git a/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java b/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java index b8c511f8..8f7b4166 100644 --- a/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java @@ -34,6 +34,8 @@ import javaclasses.mealorder.PurchaseOrderSender; import javaclasses.mealorder.ServiceFactory; import javaclasses.mealorder.c.po.PurchaseOrderAggregate; +import javaclasses.mealorder.q.FullMenuViewProjection; +import javaclasses.mealorder.q.projection.FullMenuView; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -44,10 +46,14 @@ import static javaclasses.mealorder.testdata.TestOrderCommandFactory.createOrderInstance; import static javaclasses.mealorder.testdata.TestPurchaseOrderCommandFactory.createPurchaseOrderInstance; import static javaclasses.mealorder.testdata.TestPurchaseOrderCommandFactory.markPurchaseOrderAsDeliveredInstance; +import static javaclasses.mealorder.testdata.TestValues.MENU_ID; +import static javaclasses.mealorder.testdata.TestValues.MENU_ID2; import static javaclasses.mealorder.testdata.TestValues.PURCHASE_ORDER_ID; import static javaclasses.mealorder.testdata.TestVendorCommandFactory.addVendorInstance; -import static javaclasses.mealorder.testdata.TestVendorCommandFactory.importMenuInstance; +import static javaclasses.mealorder.testdata.TestVendorCommandFactory.importMenuInstance2; +import static javaclasses.mealorder.testdata.TestVendorCommandFactory.importMenuInstance3; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.mock; @@ -59,6 +65,7 @@ class MealOrderTest { private final BoundedContext boundedContext = BoundedContexts.create(); private final CommandBus commandBus = boundedContext.getCommandBus(); + final MemoizingObserver observer = MemoizingObserver.newInstance(); private Command createCommand(GeneratedMessageV3 message) { return getRequestFactory().command() @@ -66,23 +73,20 @@ private Command createCommand(GeneratedMessageV3 message) { } @BeforeEach - public void setUp() { - final PurchaseOrderSender purchaseOrderSenderMock = mock(PurchaseOrderSender.class); - ServiceFactory.setPoSenderInstance(purchaseOrderSenderMock); - } - - @Test @DisplayName("Add vendor -> Import menu -> Set date range for menu ->" + " Create order -> Add dish to order -> Create purchase order ->" + " Mark purchase order as delivered ") - void firstFlow() { - final MemoizingObserver observer = MemoizingObserver.newInstance(); + public void setUp() { + final PurchaseOrderSender purchaseOrderSenderMock = mock(PurchaseOrderSender.class); + ServiceFactory.setPoSenderInstance(purchaseOrderSenderMock); final Command addVendor = createCommand(addVendorInstance()); commandBus.post(addVendor, observer); - final Command importMenu = createCommand(importMenuInstance()); + final Command importMenu = createCommand(importMenuInstance2()); commandBus.post(importMenu, observer); + final Command importMenu3 = createCommand(importMenuInstance3()); + commandBus.post(importMenu3, observer); final Command createOrderCommand = createCommand(createOrderInstance()); commandBus.post(createOrderCommand, observer); @@ -96,7 +100,11 @@ void firstFlow() { final Command markAsDeliveredCommand = createCommand( markPurchaseOrderAsDeliveredInstance()); commandBus.post(markAsDeliveredCommand, observer); + } + @Test + @DisplayName("Should change aggregates") + void checkAggregate() { assertNull(observer.getError()); final Optional purchaseOrderRepository = boundedContext.findRepository( @@ -112,6 +120,32 @@ void firstFlow() { .getStatus()); } + @Test + @DisplayName("Should change full menu projections") + void checkFullMenu() { + final Repository fullMenuRepository = boundedContext.findRepository(FullMenuView.class) + .get(); + final FullMenuViewProjection fullMenu1 = (FullMenuViewProjection) fullMenuRepository.find( + MENU_ID) + .get(); + final FullMenuViewProjection fullMenu2 = (FullMenuViewProjection) fullMenuRepository.find( + MENU_ID2) + .get(); + assertNotEquals(fullMenu1.getState() + .getMenuId(), fullMenu2.getState() + .getMenuId()); + assertEquals(fullMenu1.getState() + .getDishesByCategoryList(), fullMenu2.getState() + .getDishesByCategoryList()); + } + + @Test + @DisplayName("Should change calendar repository") + void checkMenuCalendar() { + final Repository fullMenuRepository = boundedContext.findRepository(FullMenuView.class) + .get(); + + } private ActorRequestFactory getRequestFactory() { return requestFactory; } diff --git a/api-java/src/test/java/javaclasses/mealorder/c/vendor/ImportMenuTest.java b/api-java/src/test/java/javaclasses/mealorder/c/vendor/ImportMenuTest.java index 61c4efc0..166faf55 100644 --- a/api-java/src/test/java/javaclasses/mealorder/c/vendor/ImportMenuTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/c/vendor/ImportMenuTest.java @@ -30,6 +30,7 @@ import javaclasses.mealorder.c.event.MenuImported; import javaclasses.mealorder.c.rejection.CannotSetDateRange; import javaclasses.mealorder.c.rejection.Rejections; +import javaclasses.mealorder.testdata.TestValues; import javaclasses.mealorder.testdata.TestVendorCommandFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -41,6 +42,7 @@ import static javaclasses.mealorder.testdata.TestValues.DISH1; import static javaclasses.mealorder.testdata.TestValues.DISH2; import static javaclasses.mealorder.testdata.TestValues.INVALID_MENU_DATE_RANGE; +import static javaclasses.mealorder.testdata.TestValues.MENU; import static javaclasses.mealorder.testdata.TestValues.MENU_DATE_RANGE; import static javaclasses.mealorder.testdata.TestValues.MENU_DATE_RANGE_FROM_PAST; import static javaclasses.mealorder.testdata.TestValues.MENU_ID; @@ -162,8 +164,8 @@ void produceRejection() { dispatchCommand(aggregate, envelopeOf(addVendor)); final ImportMenu invalidImportMenu = - importMenuInstance(VENDOR_ID, USER_ID, MENU_ID, INVALID_MENU_DATE_RANGE, DISH1, - DISH2); + importMenuInstance(VENDOR_ID, USER_ID, MENU_ID, INVALID_MENU_DATE_RANGE, + TestValues.MENU); final Throwable t = assertThrows(Throwable.class, () -> dispatchCommand(aggregate, @@ -189,8 +191,7 @@ void produceCannotSetDateRangeRejection() { final ImportMenu importMenu = importMenuInstance(); dispatchCommand(aggregate, envelopeOf(importMenu)); final ImportMenu importMenuFromPast = - importMenuInstance(VENDOR_ID, USER_ID, MENU_ID, MENU_DATE_RANGE_FROM_PAST, DISH1, - DISH2); + importMenuInstance(VENDOR_ID, USER_ID, MENU_ID, MENU_DATE_RANGE_FROM_PAST, MENU); final Throwable t = assertThrows(Throwable.class, () -> dispatchCommand(aggregate, diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/FullMenuViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/FullMenuViewProjectionTest.java index 8fb8a1f5..968b11f6 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/FullMenuViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/FullMenuViewProjectionTest.java @@ -22,7 +22,6 @@ import javaclasses.mealorder.c.event.MenuImported; import javaclasses.mealorder.q.FullMenuViewProjection; -import javaclasses.mealorder.testdata.TestValues; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -30,6 +29,7 @@ import static io.spine.server.projection.ProjectionEventDispatcher.dispatch; import static javaclasses.mealorder.testdata.TestMealOrderEventFactory.VendorEvents.menuImportedInstance; +import static javaclasses.mealorder.testdata.TestValues.MENU_ID; import static org.junit.jupiter.api.Assertions.assertEquals; public class FullMenuViewProjectionTest extends ProjectionTest { @@ -37,7 +37,7 @@ public class FullMenuViewProjectionTest extends ProjectionTest { @BeforeEach void setUp() { - projection = new FullMenuViewProjection(TestValues.MENU_ID); + projection = new FullMenuViewProjection(MENU_ID); } @Nested diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java index a2ca9070..473a15c4 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java @@ -150,18 +150,21 @@ public class TestValues { .setMonthValue(2) .setDay(13) .build(); - + public static final LocalDate START_DATE2 = LocalDate.newBuilder() + .setYear(2020) + .setMonthValue(3) + .setDay(13) + .build(); public static final LocalDate END_DATE = LocalDate.newBuilder() .setYear(2019) .setMonthValue(2) .setDay(21) .build(); - - public static final MenuDateRange MENU_DATE_RANGE = MenuDateRange.newBuilder() - .setRangeStart(START_DATE) - .setRangeEnd(END_DATE) - .build(); - + public static final LocalDate END_DATE2 = LocalDate.newBuilder() + .setYear(2020) + .setMonthValue(3) + .setDay(22) + .build(); public static final LocalDate START_DATE_FROM_PAST = LocalDate.newBuilder() .setYear(2017) .setMonthValue(2) @@ -173,11 +176,23 @@ public class TestValues { .setMonthValue(2) .setDay(19) .build(); + public static final LocalDate END_DATE_FROM_PAST2 = LocalDate.newBuilder() .setYear(2017) .setMonthValue(3) .setDay(10) .build(); + public static final MenuDateRange MENU_DATE_RANGE = MenuDateRange.newBuilder() + .setRangeStart(START_DATE) + .setRangeEnd(END_DATE) + .build(); + public static final MenuDateRange MENU_DATE_RANGE2 = MenuDateRange.newBuilder() + .setRangeStart( + START_DATE2) + .setRangeEnd( + END_DATE2) + .build(); + public static final LocalDate INVALID_START_DATE = LocalDate.newBuilder() .setYear(2020) @@ -197,12 +212,7 @@ public class TestValues { .setRangeEnd( INVALID_END_DATE) .build(); - public static final MenuDateRange MENU_DATE_RANGE2 = MenuDateRange.newBuilder() - .setRangeStart( - START_DATE_FROM_PAST) - .setRangeEnd( - END_DATE_FROM_PAST2) - .build(); + public static final MenuDateRange MENU_DATE_RANGE_FROM_PAST = MenuDateRange.newBuilder() .setRangeStart( @@ -375,6 +385,8 @@ public class TestValues { .setStatus(ORDER_ACTIVE) .build(); public static final List BIG_ORDER = createOrder(); + public static final List MENU = createSmallMenu(); + public static final List BIG_MENU = createMenu(); private static List createMenu() { @@ -389,6 +401,13 @@ private static List createMenu() { return menu; } + private static List createSmallMenu() { + final List menu = new ArrayList<>(); + menu.add(DISH1); + menu.add(DISH2); + return menu; + } + private static List getPhoneNumbers() { final List numbers = new ArrayList<>(); numbers.add(PHONE_NUMBER1); diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestVendorCommandFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestVendorCommandFactory.java index 7e8cab9d..055bd930 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestVendorCommandFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestVendorCommandFactory.java @@ -34,15 +34,20 @@ import javaclasses.mealorder.c.command.ImportMenu; import javaclasses.mealorder.c.command.UpdateVendor; -import static javaclasses.mealorder.testdata.TestValues.DISH1; -import static javaclasses.mealorder.testdata.TestValues.DISH2; +import java.util.List; + +import static javaclasses.mealorder.testdata.TestValues.BIG_MENU; import static javaclasses.mealorder.testdata.TestValues.EMAIL; +import static javaclasses.mealorder.testdata.TestValues.MENU; import static javaclasses.mealorder.testdata.TestValues.MENU_DATE_RANGE; +import static javaclasses.mealorder.testdata.TestValues.MENU_DATE_RANGE2; import static javaclasses.mealorder.testdata.TestValues.MENU_ID; +import static javaclasses.mealorder.testdata.TestValues.MENU_ID2; import static javaclasses.mealorder.testdata.TestValues.PHONE_NUMBER1; import static javaclasses.mealorder.testdata.TestValues.PHONE_NUMBER2; import static javaclasses.mealorder.testdata.TestValues.PO_DAILY_DEADLINE; import static javaclasses.mealorder.testdata.TestValues.USER_ID; +import static javaclasses.mealorder.testdata.TestValues.USER_ID2; import static javaclasses.mealorder.testdata.TestValues.VENDOR_CHANGE; import static javaclasses.mealorder.testdata.TestValues.VENDOR_ID; import static javaclasses.mealorder.testdata.TestValues.VENDOR_NAME; @@ -130,10 +135,22 @@ public static UpdateVendor updateVendorInstance(VendorId vendorId, UserId userId */ public static ImportMenu importMenuInstance() { final ImportMenu result = importMenuInstance(VENDOR_ID, USER_ID, MENU_ID, MENU_DATE_RANGE, - DISH1, DISH2); + MENU); return result; } + public static ImportMenu importMenuInstance2() { + final ImportMenu result = importMenuInstance(VENDOR_ID, USER_ID, MENU_ID, MENU_DATE_RANGE, + BIG_MENU); + return result; + } + + public static ImportMenu importMenuInstance3() { + final ImportMenu result = importMenuInstance(VENDOR_ID, USER_ID2, MENU_ID2, + MENU_DATE_RANGE2, + BIG_MENU); + return result; + } /** * Provides a pre-configured {@link ImportMenu} instance. * @@ -145,14 +162,13 @@ public static ImportMenu importMenuInstance() { */ public static ImportMenu importMenuInstance(VendorId vendorId, UserId userId, MenuId menuId, MenuDateRange menuDateRange, - Dish... dishes) { + List dishes) { final ImportMenu result = ImportMenu.newBuilder() .setVendorId(vendorId) .setUserId(userId) .setMenuId(menuId) - .addDish(dishes[0]) - .addDish(dishes[1]) + .addAllDish(dishes) .setMenuDateRange(menuDateRange) .build(); return result; From 162f6d3d460244814da2d150e2c9bb72378de22d Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Fri, 27 Apr 2018 16:36:33 +0300 Subject: [PATCH 60/66] Change test values for tests --- .../test/java/javaclasses/mealorder/c/MealOrderTest.java | 1 + .../q/projection/MenuListViewProjectionTest.java | 6 +++--- .../java/javaclasses/mealorder/testdata/TestValues.java | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java b/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java index 8f7b4166..64d146b3 100644 --- a/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java @@ -125,6 +125,7 @@ void checkAggregate() { void checkFullMenu() { final Repository fullMenuRepository = boundedContext.findRepository(FullMenuView.class) .get(); + final FullMenuViewProjection fullMenu1 = (FullMenuViewProjection) fullMenuRepository.find( MENU_ID) .get(); diff --git a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java index f61dddeb..1f6e14ef 100644 --- a/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/q/projection/MenuListViewProjectionTest.java @@ -60,10 +60,10 @@ void addView() { .getDishesByCategoryList(), menuList.get(0) .getDishesByCategoryList()); assertEquals(25, menuList.size()); - assertEquals(18, menuList.get(5) + assertEquals(27, menuList.get(5) .getMenuDate() .getDay()); - assertEquals(2017, menuList.get(5) + assertEquals(2020, menuList.get(5) .getMenuDate() .getYear()); assertEquals(2, menuList.get(5) @@ -82,7 +82,7 @@ void addView2() { dispatch(projection, createEvent(purchaseOrderCreated)); assertFalse(projection.getState() .getMenuList() - .get(18) + .get(10) .getIsAvilable()); assertTrue(projection.getState() .getMenuList() diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java index 473a15c4..1746853f 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestValues.java @@ -152,8 +152,8 @@ public class TestValues { .build(); public static final LocalDate START_DATE2 = LocalDate.newBuilder() .setYear(2020) - .setMonthValue(3) - .setDay(13) + .setMonthValue(2) + .setDay(22) .build(); public static final LocalDate END_DATE = LocalDate.newBuilder() .setYear(2019) @@ -163,7 +163,7 @@ public class TestValues { public static final LocalDate END_DATE2 = LocalDate.newBuilder() .setYear(2020) .setMonthValue(3) - .setDay(22) + .setDay(18) .build(); public static final LocalDate START_DATE_FROM_PAST = LocalDate.newBuilder() .setYear(2017) @@ -322,7 +322,7 @@ public class TestValues { public static final LocalDate DATE2 = LocalDate.newBuilder() .setYear( - 2017) + 2020) .setMonth( MARCH) .setDay(3) From 26534d616f5e29b96bb30c274c80ee051819cb87 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 2 May 2018 12:23:29 +0300 Subject: [PATCH 61/66] Add integration tests for projections --- .../mealorder/c/BoundedContexts.java | 2 +- .../mealorder/c/vendor/VendorRepository.java | 6 +- .../mealorder/c/MealOrderTest.java | 205 +++++++++++++++++- 3 files changed, 202 insertions(+), 11 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java b/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java index 51976e25..6e1663b8 100644 --- a/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java +++ b/api-java/src/main/java/javaclasses/mealorder/c/BoundedContexts.java @@ -80,7 +80,7 @@ public static BoundedContext create() { */ public static BoundedContext create(StorageFactory storageFactory) { checkNotNull(storageFactory); - final VendorRepository vendorRepository = VendorRepository.getRepository(); + final VendorRepository vendorRepository = VendorRepository.createRepository(); final OrderRepository orderRepository = new OrderRepository(); final PurchaseOrderRepository purchaseOrderRepository = new PurchaseOrderRepository(); diff --git a/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorRepository.java b/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorRepository.java index 53e1f1f6..8865bdbf 100644 --- a/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorRepository.java +++ b/api-java/src/main/java/javaclasses/mealorder/c/vendor/VendorRepository.java @@ -40,8 +40,12 @@ public static VendorRepository getRepository() { return VendorRepositorySingleton.INSTANCE.value; } + public static VendorRepository createRepository() { + VendorRepositorySingleton.INSTANCE.value = new VendorRepository(); + return VendorRepositorySingleton.INSTANCE.value; + } private enum VendorRepositorySingleton { INSTANCE; - public final VendorRepository value = new VendorRepository(); + public VendorRepository value = new VendorRepository(); } } diff --git a/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java b/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java index 64d146b3..24221645 100644 --- a/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java @@ -30,25 +30,53 @@ import io.spine.server.BoundedContext; import io.spine.server.commandbus.CommandBus; import io.spine.server.entity.Repository; +import io.spine.time.MonthOfYear; +import javaclasses.mealorder.LocalMonth; +import javaclasses.mealorder.MonthlySpendingsReportId; +import javaclasses.mealorder.OrderListId; import javaclasses.mealorder.PurchaseOrder; import javaclasses.mealorder.PurchaseOrderSender; +import javaclasses.mealorder.PurchaseOrderStatus; import javaclasses.mealorder.ServiceFactory; +import javaclasses.mealorder.VendorListId; import javaclasses.mealorder.c.po.PurchaseOrderAggregate; import javaclasses.mealorder.q.FullMenuViewProjection; +import javaclasses.mealorder.q.MenuCalendarItem; +import javaclasses.mealorder.q.MenuCalendarViewProjection; +import javaclasses.mealorder.q.MenuListViewProjection; +import javaclasses.mealorder.q.MonthlySpendingsReportViewProjection; +import javaclasses.mealorder.q.OrderListViewProjection; +import javaclasses.mealorder.q.PurchaseOrderDetailsByDishViewProjection; +import javaclasses.mealorder.q.PurchaseOrderDetailsByUserViewProjection; +import javaclasses.mealorder.q.PurchaseOrderItemViewProjection; +import javaclasses.mealorder.q.VendorListViewProjection; import javaclasses.mealorder.q.projection.FullMenuView; +import javaclasses.mealorder.q.projection.MenuCalendarView; +import javaclasses.mealorder.q.projection.MenuListView; +import javaclasses.mealorder.q.projection.MonthlySpendingsReportView; +import javaclasses.mealorder.q.projection.OrderListView; +import javaclasses.mealorder.q.projection.PurchaseOrderDetailsByDishView; +import javaclasses.mealorder.q.projection.PurchaseOrderDetailsByUserView; +import javaclasses.mealorder.q.projection.PurchaseOrderItemView; +import javaclasses.mealorder.q.projection.VendorListView; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import java.util.Iterator; +import java.util.List; + import static io.spine.protobuf.TypeConverter.toMessage; import static javaclasses.mealorder.PurchaseOrderStatus.DELIVERED; import static javaclasses.mealorder.testdata.TestOrderCommandFactory.addDishToOrderInstance; import static javaclasses.mealorder.testdata.TestOrderCommandFactory.createOrderInstance; import static javaclasses.mealorder.testdata.TestPurchaseOrderCommandFactory.createPurchaseOrderInstance; import static javaclasses.mealorder.testdata.TestPurchaseOrderCommandFactory.markPurchaseOrderAsDeliveredInstance; +import static javaclasses.mealorder.testdata.TestValues.DATE; import static javaclasses.mealorder.testdata.TestValues.MENU_ID; import static javaclasses.mealorder.testdata.TestValues.MENU_ID2; import static javaclasses.mealorder.testdata.TestValues.PURCHASE_ORDER_ID; +import static javaclasses.mealorder.testdata.TestValues.USER_ID; import static javaclasses.mealorder.testdata.TestVendorCommandFactory.addVendorInstance; import static javaclasses.mealorder.testdata.TestVendorCommandFactory.importMenuInstance2; import static javaclasses.mealorder.testdata.TestVendorCommandFactory.importMenuInstance3; @@ -60,23 +88,27 @@ @DisplayName("MealOrder Integration Test") class MealOrderTest { - private final ActorRequestFactory requestFactory = - TestActorRequestFactory.newInstance(getClass()); - - private final BoundedContext boundedContext = BoundedContexts.create(); - private final CommandBus commandBus = boundedContext.getCommandBus(); - final MemoizingObserver observer = MemoizingObserver.newInstance(); + private ActorRequestFactory requestFactory; + private CommandBus commandBus; + private BoundedContext boundedContext; + private MemoizingObserver observer; private Command createCommand(GeneratedMessageV3 message) { return getRequestFactory().command() .create(toMessage(message)); } - @BeforeEach @DisplayName("Add vendor -> Import menu -> Set date range for menu ->" + " Create order -> Add dish to order -> Create purchase order ->" + " Mark purchase order as delivered ") + @BeforeEach public void setUp() { + requestFactory = + TestActorRequestFactory.newInstance(getClass()); + observer = MemoizingObserver.newInstance(); + boundedContext = BoundedContexts.create(); + commandBus = boundedContext.getCommandBus(); + final PurchaseOrderSender purchaseOrderSenderMock = mock(PurchaseOrderSender.class); ServiceFactory.setPoSenderInstance(purchaseOrderSenderMock); @@ -143,10 +175,165 @@ void checkFullMenu() { @Test @DisplayName("Should change calendar repository") void checkMenuCalendar() { - final Repository fullMenuRepository = boundedContext.findRepository(FullMenuView.class) - .get(); + final Repository menuCalendarViewRepository = boundedContext.findRepository( + MenuCalendarView.class) + .get(); + final MenuCalendarViewProjection menuCalendarViewProjection = (MenuCalendarViewProjection) menuCalendarViewRepository.find( + MenuCalendarViewProjection.ID) + .get(); + final List calendarItemList = menuCalendarViewProjection.getState() + .getCalendarItemList(); + assertEquals(33, calendarItemList.size()); + assertEquals(13, calendarItemList.get(0) + .getDate() + .getDay()); + } + @Test + @DisplayName("Should change menu list") + void checkMenuList() { + final Repository menuListViewRepository = boundedContext.findRepository( + MenuListView.class) + .get(); + + final MenuListViewProjection menuListViewProjection = (MenuListViewProjection) menuListViewRepository.find( + MenuListViewProjection.ID) + .get(); + assertEquals(33, menuListViewProjection.getState() + .getMenuList() + .size()); + } + + @Test + @DisplayName("Should change monthly spendings") + void checkMonthlySpendings() { + final Repository monthlySpendingsRepository = boundedContext.findRepository( + MonthlySpendingsReportView.class) + .get(); + + final LocalMonth localMonth = LocalMonth.newBuilder() + .setYear(2019) + .setMonth(MonthOfYear.FEBRUARY) + .build(); + final MonthlySpendingsReportViewProjection spendingsProjection = (MonthlySpendingsReportViewProjection) monthlySpendingsRepository.find( + MonthlySpendingsReportId.newBuilder() + .setMonth(localMonth) + .build()) + .get(); + spendingsProjection.getId(); + assertEquals("user@example.com", spendingsProjection.getState() + .getUserSpending(0) + .getId() + .getEmail() + .getValue()); + assertEquals(56, spendingsProjection.getState() + .getUserSpending(0) + .getAmount() + .getAmount()); } + + @Test + @DisplayName("Should change order view") + void checkOrderView() { + final Repository orderListViewRepository = boundedContext.findRepository( + OrderListView.class) + .get(); + + final OrderListViewProjection orderListViewProjection = (OrderListViewProjection) orderListViewRepository.find( + OrderListId.newBuilder() + .setUserId(USER_ID) + .setOrderDate(DATE) + .build()) + .get(); + assertEquals("dishName1", orderListViewProjection.getState() + .getOrder(0) + .getDish(0) + .getName()); + } + + @Test + @DisplayName("Should change po by dish view") + void checkPoByDish() { + final Repository poDetailsByDishViewRepository = boundedContext.findRepository( + PurchaseOrderDetailsByDishView.class) + .get(); + final Iterator iterator = poDetailsByDishViewRepository.iterator(input -> true); + for (Iterator it = iterator; it.hasNext(); ) { + final Object o = it.next(); + } + final PurchaseOrderDetailsByDishViewProjection poDetailsByDishViewProjection = (PurchaseOrderDetailsByDishViewProjection) poDetailsByDishViewRepository.find( + PURCHASE_ORDER_ID) + .get(); + assertEquals(PurchaseOrderStatus.DELIVERED, poDetailsByDishViewProjection.getState() + .getPurchaseOrderStatus()); + assertEquals("dishName1", poDetailsByDishViewProjection.getState() + .getDishList() + .get(0) + .getName()); + } + + @Test + @DisplayName("Should change po by user view") + void checkPoByUser() { + final Repository poDetailsByUserViewRepository = boundedContext.findRepository( + PurchaseOrderDetailsByUserView.class) + .get(); + final PurchaseOrderDetailsByUserViewProjection poDetailsByUserViewProjection = (PurchaseOrderDetailsByUserViewProjection) poDetailsByUserViewRepository.find( + PURCHASE_ORDER_ID) + .get(); + assertEquals(1, poDetailsByUserViewProjection.getState() + .getOrderList() + .size()); + assertEquals("user@example.com", poDetailsByUserViewProjection.getState() + .getOrderList() + .get(0) + .getId() + .getEmail() + .getValue()); + assertEquals(1, poDetailsByUserViewProjection.getState() + .getOrderList() + .get(0) + .getDishList() + .size()); + } + + @Test + @DisplayName("Should change po item view") + void checkPoItemView() { + final Repository poItemViewRepository = boundedContext.findRepository( + PurchaseOrderItemView.class) + .get(); + final PurchaseOrderItemViewProjection poItemViewProjection = (PurchaseOrderItemViewProjection) poItemViewRepository.find( + PURCHASE_ORDER_ID) + .get(); + assertEquals(DELIVERED, poItemViewProjection.getState() + .getPurchaseOrderStatus()); + assertEquals("vendor:value: \"VendorName1\"", poItemViewProjection.getState() + .getId() + .getVendorId() + .getValue() + .trim()); + } + + @Test + @DisplayName("Should change vendor list view") + void checkVendorList() { + final Repository vendorListViewRepository = boundedContext.findRepository( + VendorListView.class) + .get(); + final VendorListId vendorListId = VendorListViewProjection.ID; + final VendorListViewProjection vendorListViewProjection = (VendorListViewProjection) vendorListViewRepository.find( + vendorListId) + .get(); + assertEquals("VendorListViewProjectionSingleton", vendorListViewProjection.getId() + .getValue()); + assertEquals(2, vendorListViewProjection.getState() + .getVendorList() + .get(0) + .getPhoneNumberList() + .size()); + } + private ActorRequestFactory getRequestFactory() { return requestFactory; } From e68870b6a3ddd3fb26b9bd36820de69298e42556 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 2 May 2018 14:09:04 +0300 Subject: [PATCH 62/66] Add tests to cover invalid order --- .../mealorder/c/MealOrderTest.java | 45 +++++++++++++++++++ .../TestPurchaseOrderCommandFactory.java | 9 ++++ 2 files changed, 54 insertions(+) diff --git a/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java b/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java index 24221645..f1c7cfde 100644 --- a/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java +++ b/api-java/src/test/java/javaclasses/mealorder/c/MealOrderTest.java @@ -68,18 +68,22 @@ import static io.spine.protobuf.TypeConverter.toMessage; import static javaclasses.mealorder.PurchaseOrderStatus.DELIVERED; +import static javaclasses.mealorder.PurchaseOrderStatus.INVALID; import static javaclasses.mealorder.testdata.TestOrderCommandFactory.addDishToOrderInstance; import static javaclasses.mealorder.testdata.TestOrderCommandFactory.createOrderInstance; import static javaclasses.mealorder.testdata.TestPurchaseOrderCommandFactory.createPurchaseOrderInstance; +import static javaclasses.mealorder.testdata.TestPurchaseOrderCommandFactory.createPurchaseOrderWithInvalidOrdersInstance; import static javaclasses.mealorder.testdata.TestPurchaseOrderCommandFactory.markPurchaseOrderAsDeliveredInstance; import static javaclasses.mealorder.testdata.TestValues.DATE; import static javaclasses.mealorder.testdata.TestValues.MENU_ID; import static javaclasses.mealorder.testdata.TestValues.MENU_ID2; +import static javaclasses.mealorder.testdata.TestValues.NEW_VENDOR_NAME; import static javaclasses.mealorder.testdata.TestValues.PURCHASE_ORDER_ID; import static javaclasses.mealorder.testdata.TestValues.USER_ID; import static javaclasses.mealorder.testdata.TestVendorCommandFactory.addVendorInstance; import static javaclasses.mealorder.testdata.TestVendorCommandFactory.importMenuInstance2; import static javaclasses.mealorder.testdata.TestVendorCommandFactory.importMenuInstance3; +import static javaclasses.mealorder.testdata.TestVendorCommandFactory.updateVendorInstance; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNull; @@ -334,6 +338,47 @@ void checkVendorList() { .size()); } + @Test + @DisplayName("Should create invalid po") + void checkInvalidPo() { + final Command createInvalidPOCommand = createCommand( + createPurchaseOrderWithInvalidOrdersInstance()); + commandBus.post(createInvalidPOCommand, observer); + final Repository poItemViewRepository = boundedContext.findRepository( + PurchaseOrderItemView.class) + .get(); + final PurchaseOrderItemViewProjection poItemViewProjection = (PurchaseOrderItemViewProjection) poItemViewRepository.find( + PURCHASE_ORDER_ID) + .get(); + assertEquals(INVALID, poItemViewProjection.getState() + .getPurchaseOrderStatus()); + final Repository poDetailsByUserViewRepository = boundedContext.findRepository( + PurchaseOrderDetailsByUserView.class) + .get(); + final PurchaseOrderDetailsByUserViewProjection poDetailsByUserViewProjection = (PurchaseOrderDetailsByUserViewProjection) poDetailsByUserViewRepository.find( + PURCHASE_ORDER_ID) + .get(); + assertEquals(INVALID, poDetailsByUserViewProjection.getState() + .getPurchaseOrderStatus()); + } + + @Test + @DisplayName("Should updates vendor") + void checkUpdateVendor() { + final Command updateVendor = createCommand(updateVendorInstance()); + commandBus.post(updateVendor, observer); + final Repository vendorListViewRepository = boundedContext.findRepository( + VendorListView.class) + .get(); + final VendorListId vendorListId = VendorListViewProjection.ID; + final VendorListViewProjection vendorListViewProjection = (VendorListViewProjection) vendorListViewRepository.find( + vendorListId) + .get(); + assertEquals(NEW_VENDOR_NAME, vendorListViewProjection.getState() + .getVendorList() + .get(0) + .getVendorName()); + } private ActorRequestFactory getRequestFactory() { return requestFactory; } diff --git a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestPurchaseOrderCommandFactory.java b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestPurchaseOrderCommandFactory.java index ceb6effe..67a9fc6c 100644 --- a/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestPurchaseOrderCommandFactory.java +++ b/testutil-api/src/main/java/javaclasses/mealorder/testdata/TestPurchaseOrderCommandFactory.java @@ -68,6 +68,15 @@ public static CreatePurchaseOrder createPurchaseOrderInstance() { return result; } + public static CreatePurchaseOrder createPurchaseOrderInstance(List order) { + final CreatePurchaseOrder result = CreatePurchaseOrder.newBuilder() + .setId(PURCHASE_ORDER_ID) + .setWhoCreates(USER_ID) + .addAllOrder(order) + .setVendorEmail(EMAIL) + .build(); + return result; + } /** * Provides a pre-configured {@link CreatePurchaseOrder} instance * with mismatch vendor identifier of purchase order and one of From dedfc26e4f61e27254d4c35dbeab46316c9f1035 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Wed, 2 May 2018 14:22:01 +0300 Subject: [PATCH 63/66] Use guava iterables to search an index --- .../mealorder/q/OrderListViewProjection.java | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java index 3a7cda1f..6b8272ed 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java @@ -20,6 +20,7 @@ package javaclasses.mealorder.q; +import com.google.common.collect.Iterables; import io.spine.core.Subscribe; import io.spine.server.projection.Projection; import javaclasses.mealorder.DishId; @@ -122,15 +123,8 @@ private Optional getOrderById(OrderId orderId) { } private int getDishIndexFromOrder(DishId dishId, OrderItem order) { - final int[] index = {-1}; - order.getDishList() - .forEach(dishItem -> { - if (dishItem.getId() - .equals(dishId)) { - index[0] = order.getDishList() - .indexOf(dishItem); - } - }); - return index[0]; + final int index = Iterables.indexOf(order.getDishList(), dish -> dish.getId() + .equals(dishId)); + return index; } } From de8b7f7e6e3c0881e21c0d8ff35f4eafd69f11c3 Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Mon, 7 May 2018 14:03:47 +0300 Subject: [PATCH 64/66] Set all subscribers public scope --- .../javaclasses/mealorder/q/FullMenuViewProjection.java | 2 +- .../mealorder/q/MenuCalendarViewProjection.java | 2 +- .../javaclasses/mealorder/q/MenuListViewProjection.java | 4 ++-- .../mealorder/q/MonthlySpendingsReportViewProjection.java | 4 ++-- .../javaclasses/mealorder/q/OrderListViewProjection.java | 8 ++++---- .../q/PurchaseOrderDetailsByDishViewProjection.java | 8 ++++---- .../q/PurchaseOrderDetailsByUserViewProjection.java | 8 ++++---- .../mealorder/q/PurchaseOrderItemViewProjection.java | 6 +++--- .../javaclasses/mealorder/q/VendorListViewProjection.java | 4 ++-- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/FullMenuViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/FullMenuViewProjection.java index d16f42a4..4bad7142 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/FullMenuViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/FullMenuViewProjection.java @@ -45,7 +45,7 @@ public FullMenuViewProjection(MenuId id) { } @Subscribe - void on(MenuImported event) { + public void on(MenuImported event) { final VendorName vendorName = VendorName.newBuilder() .setValue(event.getVendorId() .getValue()) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java index 260fe5fb..284a9725 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuCalendarViewProjection.java @@ -57,7 +57,7 @@ public MenuCalendarViewProjection(MenuCalendarId id) { } @Subscribe - void on(MenuImported event) { + public void on(MenuImported event) { final List datesBetween = getDatesBetween(event.getMenuDateRange() .getRangeStart(), event.getMenuDateRange() diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java index 0a6d1820..6dbfcac5 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MenuListViewProjection.java @@ -61,7 +61,7 @@ public MenuListViewProjection(MenuListId id) { } @Subscribe - void on(MenuImported event) { + public void on(MenuImported event) { final VendorName vendorName = VendorName.newBuilder() .setValue(event.getVendorId() .getValue()) @@ -89,7 +89,7 @@ void on(MenuImported event) { } @Subscribe - void on(PurchaseOrderCreated event) { + public void on(PurchaseOrderCreated event) { final LocalDate poDate = event.getId() .getPoDate(); getBuilder().getMenu() diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java index c9a333c4..6ffbd026 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java @@ -50,7 +50,7 @@ public MonthlySpendingsReportViewProjection(MonthlySpendingsReportId id) { } @Subscribe - void on(PurchaseOrderSent event) { + public void on(PurchaseOrderSent event) { final List userOrderDetailsList = new ArrayList<>(); final PurchaseOrder purchaseOrder = event.getPurchaseOrder(); @@ -81,7 +81,7 @@ void on(PurchaseOrderSent event) { } @Subscribe - void on(PurchaseOrderDelivered event) { + public void on(PurchaseOrderDelivered event) { final List orderDetailsList = getBuilder().getOrder(); orderDetailsList.forEach(userOrderDetails -> { if (userOrderDetails.getPurchaseOrderId() diff --git a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java index 6b8272ed..75013362 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java @@ -52,7 +52,7 @@ public OrderListViewProjection(OrderListId id) { } @Subscribe - void on(DishAddedToOrder event) { + public void on(DishAddedToOrder event) { final OrderId orderId = event.getOrderId(); final DishItem dish = DishItem.newBuilder() .setName(event.getDish() @@ -84,7 +84,7 @@ void on(DishAddedToOrder event) { } @Subscribe - void on(DishRemovedFromOrder event) { + public void on(DishRemovedFromOrder event) { final List orderItems = getBuilder().getOrder(); final int removeIndex = getDishIndexFromOrder(event.getDish() .getId(), @@ -96,14 +96,14 @@ void on(DishRemovedFromOrder event) { } @Subscribe - void on(OrderCanceled event) { + public void on(OrderCanceled event) { final OrderItem order = getOrderById(event.getOrderId()).get(); getBuilder().removeOrder(getBuilder().getOrder() .indexOf(order)); } @Subscribe - void on(OrderProcessed event) { + public void on(OrderProcessed event) { final OrderItem order = getOrderById(event.getOrder() .getId()).get(); getBuilder().setOrder(getBuilder().getOrder() diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java index 15e57e03..cbe860fb 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByDishViewProjection.java @@ -51,24 +51,24 @@ public PurchaseOrderDetailsByDishViewProjection(PurchaseOrderId id) { } @Subscribe - void on(PurchaseOrderCreated event) { + public void on(PurchaseOrderCreated event) { final List dishItems = getDishItems(event.getOrderList()); getBuilder().addAllDish(dishItems); getBuilder().setId(event.getId()); } @Subscribe - void on(PurchaseOrderDelivered event) { + public void on(PurchaseOrderDelivered event) { getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.DELIVERED); } @Subscribe - void on(PurchaseOrderSent event) { + public void on(PurchaseOrderSent event) { getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.SENT); } @Subscribe - void on(PurchaseOrderValidationFailed event) { + public void on(PurchaseOrderValidationFailed event) { getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.INVALID); } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java index 3d3222a5..381b6d92 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderDetailsByUserViewProjection.java @@ -50,24 +50,24 @@ public PurchaseOrderDetailsByUserViewProjection(PurchaseOrderId id) { } @Subscribe - void on(PurchaseOrderCreated event) { + public void on(PurchaseOrderCreated event) { final List usersOrders = getUserOrders(event); getBuilder().addAllOrder(usersOrders); getBuilder().setId(event.getId()); } @Subscribe - void on(PurchaseOrderDelivered event) { + public void on(PurchaseOrderDelivered event) { getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.DELIVERED); } @Subscribe - void on(PurchaseOrderSent event) { + public void on(PurchaseOrderSent event) { getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.SENT); } @Subscribe - void on(PurchaseOrderValidationFailed event) { + public void on(PurchaseOrderValidationFailed event) { getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.INVALID); event.getFailureOrderList() .forEach(order -> { diff --git a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderItemViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderItemViewProjection.java index 499fae5c..5ddc70d1 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderItemViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/PurchaseOrderItemViewProjection.java @@ -58,20 +58,20 @@ public PurchaseOrderStatus getPurchaseOrderStatus() { } @Subscribe - void on(PurchaseOrderSent event) { + public void on(PurchaseOrderSent event) { getBuilder().setId(event.getPurchaseOrder() .getId()); getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.SENT); } @Subscribe - void on(PurchaseOrderDelivered event) { + public void on(PurchaseOrderDelivered event) { getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.DELIVERED); } @Subscribe - void on(PurchaseOrderValidationFailed event) { + public void on(PurchaseOrderValidationFailed event) { getBuilder().setPurchaseOrderStatus(PurchaseOrderStatus.INVALID); } } diff --git a/api-java/src/main/java/javaclasses/mealorder/q/VendorListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/VendorListViewProjection.java index 63579c67..b21179b1 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/VendorListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/VendorListViewProjection.java @@ -58,7 +58,7 @@ public VendorListViewProjection(VendorListId id) { } @Subscribe - void on(VendorAdded event) { + public void on(VendorAdded event) { final VendorItem vendorItem = VendorItem.newBuilder() .setId(event.getVendorId()) .setEmail(event.getEmail()) @@ -70,7 +70,7 @@ void on(VendorAdded event) { } @Subscribe - void on(VendorUpdated event) { + public void on(VendorUpdated event) { final VendorItem vendorItem = VendorItem.newBuilder() .setId(event.getVendorId()) .setEmail(event.getVendorChange() From bce037b9a909a870734d22d1a034cfc85e4afcdd Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Mon, 7 May 2018 14:07:47 +0300 Subject: [PATCH 65/66] Set `Projections` methods public scope --- .../src/main/java/javaclasses/mealorder/q/Projections.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java index a5aaff3e..422d8a6c 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/Projections.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/Projections.java @@ -54,7 +54,7 @@ public static List getDatesBetween( return collect; } - static LocalDate toLocalDate(java.time.LocalDate date) { + public static LocalDate toLocalDate(java.time.LocalDate date) { return LocalDate.newBuilder() .setDay(date.getDayOfMonth()) .setMonthValue(date.getMonthValue()) @@ -62,7 +62,7 @@ static LocalDate toLocalDate(java.time.LocalDate date) { .build(); } - static List getAllDishesByCategories( + public static List getAllDishesByCategories( List dishList) { final List dishesByCategoryList = new ArrayList<>(); dishList.forEach(dish -> { @@ -93,7 +93,7 @@ static List getAllDishesByCategories( return dishesByCategoryList; } - static int categoryIndex(List dishByCategory, String category) { + public static int categoryIndex(List dishByCategory, String category) { final OptionalInt optionalInt = IntStream.range(0, dishByCategory.size()) .filter(i -> dishByCategory.get(i) .getCategory() From 4429a9577d34976613f0e2a14980c1023769884b Mon Sep 17 00:00:00 2001 From: "alexander.karpetc" Date: Mon, 7 May 2018 14:56:45 +0300 Subject: [PATCH 66/66] Set id -> required for all non-singleton projections --- .../MonthlySpendingsReportViewProjection.java | 19 +++++++++++++++++++ .../mealorder/q/OrderListViewProjection.java | 14 +++++++------- .../javaclasses/mealorder/q/projections.proto | 10 +++++----- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java index 6ffbd026..31ab0848 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/MonthlySpendingsReportViewProjection.java @@ -23,7 +23,9 @@ import io.spine.core.Subscribe; import io.spine.money.Money; import io.spine.server.projection.Projection; +import io.spine.time.MonthOfYear; import javaclasses.mealorder.Dish; +import javaclasses.mealorder.LocalMonth; import javaclasses.mealorder.MonthlySpendingsReportId; import javaclasses.mealorder.PurchaseOrder; import javaclasses.mealorder.UserId; @@ -78,6 +80,23 @@ public void on(PurchaseOrderSent event) { userOrderDetailsList.add(userOrderDetails); }); getBuilder().addAllOrder(userOrderDetailsList); + final int year = event.getPurchaseOrder() + .getId() + .getPoDate() + .getYear(); + final MonthOfYear month = event.getPurchaseOrder() + .getId() + .getPoDate() + .getMonth(); + final LocalMonth localMonth = LocalMonth.newBuilder() + .setYear(year) + .setMonth(month) + .build(); + final MonthlySpendingsReportId monthlySpendingsReportId = MonthlySpendingsReportId.newBuilder() + .setMonth( + localMonth) + .build(); + getBuilder().setReportId(monthlySpendingsReportId); } @Subscribe diff --git a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java index 75013362..d529a756 100644 --- a/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java +++ b/api-java/src/main/java/javaclasses/mealorder/q/OrderListViewProjection.java @@ -63,23 +63,23 @@ public void on(DishAddedToOrder event) { .getId()) .build(); if (getOrderById(orderId).isPresent()) { + getBuilder().setOrder(getBuilder().getOrder() + .indexOf(getOrderById(orderId).get()), + OrderItem.newBuilder(getOrderById(orderId).get()) + .addDish(dish) + .build()); + } else { final OrderListId listId = OrderListId.newBuilder() .setUserId(event.getOrderId() .getUserId()) .setOrderDate(event.getOrderId() .getOrderDate()) .build(); - getBuilder().setOrder(getBuilder().getOrder() - .indexOf(getOrderById(orderId).get()), - OrderItem.newBuilder(getOrderById(orderId).get()) - .addDish(dish) - .build()) - .setListId(listId); - } else { getBuilder().addOrder(OrderItem.newBuilder() .addDish(dish) .setId(event.getOrderId()) .build()); + getBuilder().setListId(listId); } } diff --git a/model/src/main/proto/javaclasses/mealorder/q/projections.proto b/model/src/main/proto/javaclasses/mealorder/q/projections.proto index 37723d4f..e602e82c 100644 --- a/model/src/main/proto/javaclasses/mealorder/q/projections.proto +++ b/model/src/main/proto/javaclasses/mealorder/q/projections.proto @@ -91,7 +91,7 @@ message MenuCalendarView { message OrderListView { // The identifier of an order list. - OrderListId list_id = 1; + OrderListId list_id = 1 [(required) = true]; // The collection of user's orders. repeated OrderItem order = 2; @@ -106,7 +106,7 @@ message OrderListView { message FullMenuView { // // The identifier of a full menu. - MenuId menu_id = 1; + MenuId menu_id = 1 [(required) = true]; // The vendor name. VendorName vendor_name = 2 [(required) = true]; @@ -151,7 +151,7 @@ message PurchaseOrderItemView { message PurchaseOrderDetailsByDishView { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The purchase order status. PurchaseOrderStatus purchase_order_status = 2; @@ -169,7 +169,7 @@ message PurchaseOrderDetailsByDishView { message PurchaseOrderDetailsByUserView { // The identifier of a purchase order. - PurchaseOrderId id = 1; + PurchaseOrderId id = 1 [(required) = true]; // The purchase order status. PurchaseOrderStatus purchase_order_status = 2; @@ -190,7 +190,7 @@ message PurchaseOrderDetailsByUserView { message MonthlySpendingsReportView { // The identifier of a monthly spendings report. - MonthlySpendingsReportId report_id = 1; + MonthlySpendingsReportId report_id = 1 [(required) = true]; // The collection of users spendings for the specified month. repeated UserSpendings user_spending = 2;