diff --git a/spring-geode/src/test/java/example/app/pos/model/LineItem.java b/spring-geode/src/test/java/example/app/pos/model/LineItem.java new file mode 100644 index 00000000..28640a53 --- /dev/null +++ b/spring-geode/src/test/java/example/app/pos/model/LineItem.java @@ -0,0 +1,64 @@ +/* + * Copyright 2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package example.app.pos.model; + +import java.math.BigDecimal; + +import org.springframework.util.Assert; + +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + +/** + * The {@link LineItem} class models a {@link Product} purchase on a {@link PurchaseOrder}. + * + * @author John Blum + * @since 1.3.0 + */ +@Getter +@RequiredArgsConstructor(staticName = "newLineItem") +@SuppressWarnings("unused") +public class LineItem { + + @NonNull + private Product product; + + private Integer quantity = 1; + + public String getDescription() { + return getProduct().getName(); + } + + public BigDecimal getTotal() { + return getUnitPrice().multiply(BigDecimal.valueOf(getQuantity())); + } + + public BigDecimal getUnitPrice() { + return getProduct().getPrice(); + } + + public LineItem withQuantity(int quantity) { + Assert.isTrue(quantity > 0, "Quantity must be greater than equal to 1"); + this.quantity = quantity; + return this; + } + + @Override + public String toString() { + return String.format("Purchasing [%d] of Product [%s]", getQuantity(), getProduct()); + } +} diff --git a/spring-geode/src/test/java/example/app/pos/model/Product.java b/spring-geode/src/test/java/example/app/pos/model/Product.java new file mode 100644 index 00000000..03d18ce9 --- /dev/null +++ b/spring-geode/src/test/java/example/app/pos/model/Product.java @@ -0,0 +1,54 @@ +/* + * Copyright 2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package example.app.pos.model; + +import java.math.BigDecimal; + +import org.springframework.data.annotation.Id; +import org.springframework.data.gemfire.mapping.annotation.Region; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.ToString; + +/** + * The {@link Product} class models a physical product for purchase. + * + * @author John Blum + * @see org.springframework.data.annotation.Id + * @see org.springframework.data.gemfire.mapping.annotation.Region + * @since 1.3.0 + */ +@Region("Products") +@Getter +@ToString(of = "name") +@EqualsAndHashCode(of = "name") +@RequiredArgsConstructor(staticName = "newProduct") +@SuppressWarnings("unused") +public class Product { + + @Id @NonNull + private String name; + + private BigDecimal price; + + public Product havingPrice(BigDecimal price) { + this.price = price; + return this; + } +} diff --git a/spring-geode/src/test/java/example/app/pos/model/PurchaseOrder.java b/spring-geode/src/test/java/example/app/pos/model/PurchaseOrder.java new file mode 100644 index 00000000..94d87b40 --- /dev/null +++ b/spring-geode/src/test/java/example/app/pos/model/PurchaseOrder.java @@ -0,0 +1,86 @@ +/* + * Copyright 2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package example.app.pos.model; + +import java.math.BigDecimal; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Optional; +import java.util.Set; +import java.util.stream.StreamSupport; + +import org.springframework.data.annotation.Id; +import org.springframework.data.gemfire.mapping.annotation.Region; +import org.springframework.lang.NonNull; +import org.springframework.util.Assert; + +import org.jetbrains.annotations.NotNull; + +import lombok.Getter; + +/** + * The {@link PurchaseOrder} class models an actual purchase agreement for {@link Product products} + * ordered by a consumer. + * + * @author John Blum + * @see java.lang.Iterable + * @see org.springframework.data.annotation.Id + * @see org.springframework.data.gemfire.mapping.annotation.Region + * @since 1.3.0 + */ +@Region("PurchaseOrders") +@SuppressWarnings("unused") +public class PurchaseOrder implements Iterable { + + @Id @Getter + private Long id; + + private final Set lineItems = new LinkedHashSet<>(); + + public Optional findBy(String productName) { + + return StreamSupport.stream(this.spliterator(), false) + .filter(item -> item.getProduct().getName().equals(productName)) + .findFirst(); + } + + public BigDecimal getTotal() { + + return StreamSupport.stream(this.spliterator(), false) + .map(LineItem::getTotal) + .reduce(BigDecimal::add) + .orElse(BigDecimal.ZERO); + } + + public PurchaseOrder add(@NonNull LineItem lineItem) { + + Assert.notNull(lineItem, "LineItem must not be null"); + + this.lineItems.add(lineItem); + + return this; + } + + @NotNull @Override + public Iterator iterator() { + return Collections.unmodifiableSet(this.lineItems).iterator(); + } + + public int size() { + return this.lineItems.size(); + } +}