Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#23 - Overhaul OrderManager.completeOrder() #103

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
ff5cbf1
Complete Chapter PaymentMethod in SalespointReference
Oct 13, 2014
c31fa9b
Merge branch 'master' of https://github.com/st-tu-dresden/salespoint
Oct 15, 2014
8961957
Merge branch 'master' of https://github.com/st-tu-dresden/salespoint.git
Dec 11, 2014
ab971c4
#68 - test and solution
Dec 11, 2014
f9fe5fc
#61 - Rename OrderManager.find... methods and deprecated old methods for
May 14, 2015
57adfa7
#68 - test and solution
Dec 11, 2014
e2aed9c
#61 - Rename OrderManager.find... methods and deprecated old methods for
May 14, 2015
f3b163c
Merge branch 'master' of https://github.com/AndreasZaschka/SalesPoint
Aug 23, 2015
8b31c9b
Merge branch 'master' of https://github.com/AndreasZaschka/SalesPoint
Aug 23, 2015
cd8596c
#23 - Simplified, extended OrderCompletionResult, added some Tests
Aug 24, 2015
dfe81c3
#61 - Added some more tests, removed deprecated methods due to #94
Aug 26, 2015
fe06d7b
Fixed small typo.
mheider Oct 12, 2015
ebe9824
Merge pull request #101 from st-tu-dresden/typo_reference_documentation
AndreasZaschka Oct 12, 2015
8979f3a
#68 - test and solution
Dec 11, 2014
89b6a01
#61 - Rename OrderManager.find... methods and deprecated old methods for
May 14, 2015
1c6247d
#68 - test and solution
Dec 11, 2014
eaa8718
Merge branch 'master' of https://github.com/AndreasZaschka/SalesPoint
Aug 23, 2015
03fdcbd
#61 - Added some more tests, removed deprecated methods due to #94
Aug 26, 2015
0cd5086
Merge branch 'master' of https://github.com/AndreasZaschka/SalesPoint
Oct 17, 2015
4345153
Merge branch 'master' of https://github.com/AndreasZaschka/SalesPoint
Oct 17, 2015
01d8f87
Merge branch 'master' of https://github.com/AndreasZaschka/SalesPoint
Oct 17, 2015
f46897a
#23 - Simplified, extended OrderCompletionResult, added some Tests
Aug 24, 2015
b456ff8
Merge branch '#23' of https://github.com/AndreasZaschka/SalesPoint in…
Oct 17, 2015
7238d62
#78 - FIX
Oct 19, 2015
1397a0f
#67 - FIX
Oct 19, 2015
80465d9
Merge branch 'master' of https://github.com/st-tu-dresden/salespoint
Oct 19, 2015
c431204
Merge branch 'master' into #23
Oct 19, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 8 additions & 15 deletions src/main/asciidoc/salespoint-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ image::user.png[title="User"]
image::user-account.png[title="User Account"]

To manage system accounts, Salespoint {majorversion} has a notation of a user in the form of the `User` class. Users are managed by the `UserAccountManager`. Every user is uniquely identified by a `org.salespointframework.useraccount.UserAccountIdentifier`, which also serves as primary key attribute for the database.
The username of the `org.salespointframework.useraccount.UserAccount` can be retrieved by the `getUsername()` method.

[[modules.useraccount.role]]
=== Roles
Expand All @@ -186,6 +187,7 @@ To reduce code repetition, Salespoint {majorversion} contains code to automate t

[[modules.useraccount.limitation]]
=== Limitation
The `org.salespointframework.useraccount.UserAccount` is limited to the given attributes and methods.
Due to the fact, that Salespoint use the `SecurityContext` for authentication, the `UserAccount` cannot be extended. In the background the `org.salespointframework.useraccount.UserAccount` is converted to an instance of `org.springframework.security.core.userdetails.UserDetails`.

If these properties don’t meet all requirements, wrap the `UserAccount` in a new entity. Put all the new features in this new entity and connect this information via a `@OneToOne` relationship with the `UserAccount`. An example can be found in the Videoshop project.
Expand All @@ -210,24 +212,15 @@ public class UserAccountExtension {

[[modules.quantity]]
== Quantity
`Quantity` is used to represent amaounts of anything. `Quantity` objects are immutable and the class implements the `Comparable` interface.
`Quantity` is used to represent amounts of anything. Furthermore a `Quantity` can be used to calc with (plus, minus).
But only `Quantities` with the same `Metric` can be combined or compared, so every `Quantity` has an `Metric` attribute.

=== Attributes of Quantity
* a numerical value -> <<modules.quantity.value>>
* a (measurement) unit or metric -> <<modules.quantity.metric>>
* a type specifing the rounding of the numerical type -> <<modules.quantity.rounding>>

[[modules.quantity.value]]
=== BigDecimal - Representing numerical values
`BigDecimal` was chosen as datatype for the `amount` attribute over `float` or `double` because of its arbitraty precision. Moreover, objects of `BigDecimal` are `immutable` and the `BigDecimal` class provides operations for including, but not limited to: arithmetic, rounding, and comparison.
And of course, every `Quantity` has an amount value, represented as a `java.math.BigDecimal`.

[[modules.quantity.metric]]
=== Metric - What is represented
The composite type `Metric` contains all information pertaining to the unit or metric of the represented object. Examples for units or metrics are: m (meter), s (second), pcs (pieces). For example consider the unit of length "meter": represented by an object of the class `Metric` the symbol would be set to `m` and the name to `meter`. Furthermore, an object of type `Metric` has a description field, to explain the meaning of the metric in detail. For the example of a meter a possible description could be "The meter is the length of the path travelled by light in vacuum during a time interval of 1/299 792 458 of a second.".

[[modules.quantity.rounding]]
=== Rounding
There are many rounding strategies, for money operations and so on. For this case, Salespoint ships with a `RoundingStrategy` interface providing a `round()` method. This implementation of this `RoundingStrategy`, `BasicRoundingStrategy` offers two ways to describe a rounding operation: using the decimal places after (or before) the decimal delimiter and using a rounding step.
=== Metric
The composite type `Metric` contains all information pertaining to the unit or metric of the represented object.
Furthermore, an object of type `Metric` has a description field, to explain the meaning of the metric in detail. For the example of a meter a possible description could be "The meter is the length of the path travelled by light in vacuum during a time interval of 1/299 792 458 of a second.".

[[modules.catalog]]
== Catalog
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.OneToOne;

import org.salespointframework.catalog.Product;
import org.salespointframework.core.AbstractEntity;
import org.salespointframework.quantity.Quantity;
Expand Down Expand Up @@ -110,4 +109,4 @@ public void increaseQuantity(Quantity quantity) {

this.quantity = this.quantity.add(quantity);
}
}
}
107 changes: 72 additions & 35 deletions src/main/java/org/salespointframework/order/OrderCompletionResult.java
Original file line number Diff line number Diff line change
@@ -1,47 +1,84 @@
package org.salespointframework.order;

import java.util.Map;
import org.salespointframework.catalog.Product;
import org.salespointframework.catalog.ProductIdentifier;
import org.salespointframework.inventory.Inventory;
import org.salespointframework.quantity.Quantity;

/**
* An {@code OrderCompletionResult} is returned after you call {@link OrderManager#completeOrder(Order)}
*
* An {@code OrderCompletionResult} is returned after you call
* {@link OrderManager#completeOrder(Order)}.
*
* @author Paul Henke
*/
public interface OrderCompletionResult {
@SuppressWarnings("javadoc")
public enum OrderCompletionStatus {
SUCCESSFUL, FAILED, /*FAILED_ITEMS_MISSING, *//* SPLITORDER */
}

/**
* @return the OrderCompletionStatus of the {@link Order}
*/
OrderCompletionStatus getStatus();
@SuppressWarnings("javadoc")
public enum OrderCompletionStatus {

// TODO später rollback, split
SUCCESSFUL,
FAILED,
FAILED_PRODUCTS_MISSING,
FAILED_PRODUCTS_UNDERSTOCKED,
/* SPLITORDER */
}

/**
* Call if you don't want a split order
*
* @return {@literal true} if rollback was successful, otherwise {@literal false}
*/
//
/*
boolean rollBack();
*/
/**
* Creates and returns a Splitorder
*
* @return a new {@link Order}
*/
/*
Order<OrderLine> splitOrder();
*/
/**
* @return the OrderCompletionStatus of the {@link Order}
*/
OrderCompletionStatus getStatus();

/**
* Returns all {@link Product}s,
* depending on the {@link OrderCompletionStatus}.
*
* <br/><br/>
*
* <table>
* <tr>
* <th>OrderCompletionStatus</th>
* <th>Description</th>
* </tr>
* <tr>
* <td>{@link OrderCompletionStatus#FAILED}</td>
* <td>{@link Map} is empty</td>
* </tr>
* <tr>
* <td>{@link OrderCompletionStatus#FAILED_PRODUCTS_MISSING}</td>
* <td>Contains all {@link ProductIdentifier}s and {@link Quantity}, that is not found in the {@link Inventory}.</td>
* </tr>
* <tr>
* <td>{@link OrderCompletionStatus#FAILED_PRODUCTS_UNDERSTOCKED}</td>
* <td>Contains all {@link ProductIdentifier}s and {@link Quantity}, that is not sufficient in the {@link Inventory}. The total {@link Quantity}, not the diffenrence will be returned</td>
* </tr>
* <tr>
* <td>{@link OrderCompletionStatus#SUCCESSFUL}</td>
* <td>Contains all {@link ProductIdentifier}s and {@link Quantity}, that is successfully done by the {@link OrderManager#completeOrder(org.salespointframework.order.Order) }. Should be the same as the {@link Order#getOrderLines()} contains.</td>
* </tr>
* </table>
*
* @return an {@link Map} of {@link ProductIdentifier}, {@link Quantity}
*/
Map<ProductIdentifier, Quantity> getProducts();

/**
* Returns all removed {@link ProductInstance}s
*
* @return an {@link Iterable} of {@link ProductInstance}
*/
// TODO später rollback, split
/**
* Call if you don't want a split order
*
* @return {@literal true} if rollback was successful, otherwise
* {@literal false}
*/
//
/*
Iterable<ProductInstance> getRemovedInstances();
*/
boolean rollBack();
*/
/**
* Creates and returns a Splitorder
*
* @return a new {@link Order}
*/
/*
Order<OrderLine> splitOrder();
*/
}
14 changes: 12 additions & 2 deletions src/main/java/org/salespointframework/order/OrderLine.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Lob;

import org.javamoney.moneta.Money;
import org.salespointframework.catalog.Product;
import org.salespointframework.catalog.ProductIdentifier;
Expand All @@ -16,7 +15,15 @@
import org.springframework.util.Assert;

/**
* An order line
* An order line represents the total price and the {@link Quantity}
* of a {@link Product} of an {@link Order}.
*
* <pre>
* Example:
* Product 'Car' with price 15.000, Quantity of 3
* Orderline: price -> 3 * 15.000
* quantity -> 3
* </pre>
*
* @author Paul Henke
* @author Oliver Gierke
Expand All @@ -34,6 +41,9 @@ public class OrderLine extends AbstractEntity<OrderLineIdentifier>implements Pri
@AttributeOverride(name = "id", column = @Column(name = "PRODUCT_ID") ) //
private ProductIdentifier productIdentifier;

/**
* Total price for {@link Product} multiply the {@link Quantity}
*/
private @Lob Money price;
private @Lob Quantity quantity;
private String productName;
Expand Down
46 changes: 24 additions & 22 deletions src/main/java/org/salespointframework/order/OrderManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import java.time.LocalDateTime;
import java.util.Optional;

import org.salespointframework.payment.PaymentMethod;
import org.salespointframework.useraccount.UserAccount;

Expand Down Expand Up @@ -38,50 +37,53 @@ public interface OrderManager<T extends Order> {
* @return {@literal true} if the OrderManager contains the order, {@literal false} otherwise.
*/
boolean contains(OrderIdentifier orderIdentifier);

/**
* Returns all {@link Order}s having the {@link OrderStatus} {@code status}. If no orders with the specified status
* exist, an empty Iterable is returned.
*
* @param orderStatus Denoting the {@link OrderStatus} on which the {@link Order}s will be requested.
* @return an Iterable containing all {@link Order}s with the specified {@link OrderStatus}
* @param orderStatus Denoting the {@link OrderStatus} on which the {@link Order}s will be requested.
* @return an Iterable containing all {@link Order}s with the specified {@link OrderStatus}
*/
Iterable<T> find(OrderStatus orderStatus);

Iterable<T> findOrdersByOrderStatus(OrderStatus orderStatus);
/**
* Returns all {@link Order}s in between the dates {@code from} and {@code to}, including from and to. So every entry
* Returns all {@link Order}s in between the interval {@code from} and {@code to}, including from and to. So every entry
* with an time stamp <= to and >= from is returned. If no {@link Order}s within the specified time span exist, an
* empty Iterable is returned.
*
* @param from time stamp denoting the start of the requested time period, must not be {@literal null}.
* @param to time stamp denoting the end of the requested time period, must not be {@literal null}.
* @return an {@link Iterable} containing all {@link Order}s between from and to.
* @param from Time stamp denoting the start of the requested time period, must not be {@literal null}.
* @param to Time stamp denoting the end of the requested time period, must not be {@literal null}.
* @return an {@link Iterable} containing all {@link Order}s between from and to.
*/
Iterable<T> find(LocalDateTime from, LocalDateTime to);

Iterable<T> findOrdersBetween(LocalDateTime from, LocalDateTime to);
/**
* Returns all {@link Order}s of the given {@link UserAccount}. If this user has no orders, an empty {@link Iterable}
* is returned.
*
* @param userAccount Denoting the {@link UserAccount} on which the orders will be requested, must not be
* @param userAccount Denoting the {@link UserAccount} on which the orders will be requested, must not be
* {@literal null}.
* @return an {@link Iterable} containing all orders of the specified user.
* @return an {@link Iterable} containing all orders of the specified user.
*/
Iterable<T> find(UserAccount userAccount);
Iterable<T> findOrdersByUserAccount(UserAccount userAccount);


/**
* Returns all {@link Order}s from the given {@link UserAccount} in between the dates {@code from} and {@code to},
* including from and to. If this user has no {@link Order}s in this period, an empty {@link Iterable} is returned.
* including from and to. So every entry with an time stamp <= to and >= from is returned. If this user has no
* {@link Order}s in this period, an empty {@link Iterable} is returned.
*
* @param userAccount the {@link UserAccount} whose {@link Order}s shall be returned, must not be {@literal null}.
* @param from time stamp denoting the start of the requested time period,must not be {@literal null}.
* @param to time stamp denoting the end of the requested time period, must not be {@literal null}.
* @return an {@link Iterable} containing all orders from the specified user in the specified period.
* @param userAccount The {@link UserAccount} whose {@link Order}s shall be returned, must not be {@literal null}.
* @param from Time stamp denoting the start of the requested time period,must not be {@literal null}.
* @param to Time stamp denoting the end of the requested time period, must not be {@literal null}.
* @return an {@link Iterable} containing all orders from the specified user in the specified period.
*/
Iterable<T> find(UserAccount userAccount, LocalDateTime from, LocalDateTime to);
Iterable<T> findOrders(UserAccount userAccount, LocalDateTime from, LocalDateTime to);

/**
* Tries to complete this order, the {@link OrderStatus} has to be PAID.
* Tries to complete this order.
* The {@link OrderStatus} has to be PAID.
*
* @param order the order to complete, must not be {@literal null}.
* @return an {@link OrderCompletionResult}
Expand Down
Loading