= Salespoint Framework - Technical Reference
Andreas Zaschka; Paul Henke; Oliver Gierke;
:javadoc: /SalesPoint/{dev}/api
:source-base: ../../main/java/org/salespointframework
:source-base-test: ../../test/java/org/salespointframework
:toc:
:revnumber: {version}
:revdate: {localdate}
:imagesdir: ./images

[[preface]]
= Preface

[preface]
[[preface.introduction]]
== Introduction
The Salespoint Framework is intended to minimize developing effort of point-of-sale applications. Salespoint 2010 users complainted about complexity, missing features and bugs. Thus, the decision was made to re-design and re-implement the framework from scratch. In 2013 some parts again were re-implemented with components of the http://spring.io[Spring framework]. Our development goal was an easy-to-use framework primarily targeted for educational purposes. As such Salespoint {majorversion} is not tailored to any specific application, but designed with a wide area of applications in mind.

Models and design patterns employed in Salespoint {majorversion} are inspired by _Enterprise Patterns and MDA_ <<epam>>. An overview of the functionality of the new features in Salespoint {majorversion} are detailed in this document. We would like to thank all Salespoint users who submitted their feedback and encourage future users of Salespoint {majorversion} to do the same.

[preface]
[[preface.prerequisites]]
== Prerequisites
Working with Salespoint requires some basic knowledge of the underlying technologies such as the Spring Framework as well as JPA to implement the persistence layer. http://static.olivergierke.de/spring-webapps/index.html[This script] gives you an introduction into these technologies. Also the https://github.com/st-tu-dresden/guestbook[Guestbook] sample project is a good starting point to get familiar with the technology stack.

=== The Videoshop sample project
To give you an example of what applications built on top of Salespoint can actually look like, we provide the https://github.com/st-tu-dresden/videoshop[Videoshop] sample project that covers a few key areas:

* Using and extending the business modules provided by Salespoint to abstract a concrete problem domain.
* Implementing a web layer (controllers, views) on top of Java based business services of that business domain.
* Adding the necessary bits and pieces for technical aspects such as security and transactions.

TIP: The following sections will refer to code of the sample project here and there so it might be useful to have the repository cloned and the project imported into your IDE of choice to quickly be able to navigate these.

[preface]
[[preface.whats-new-in-6.1]]
== What's new in Salespoint 6.1?
=== Upgrade to Spring Boot 1.2 and Spring 4.1
For Salespoint 6.1 we upgraded to Spring Boot 1.2, which transitively updates a few third party dependencies, most notably Spring 4.1. Read more on the new features of Spring Boot in its http://docs.spring.io/spring-boot/docs/1.2.x/reference/htmlsingle[reference documentation] and skim through the https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-1.2-Release-Notes#upgrading-from-spring-boot-11[upgrade notes] as well. The new features of Spring 4.1 are described http://docs.spring.io/spring-framework/docs/4.1.x/spring-framework-reference/htmlsingle/#new-in-4.1[here].

=== New @EnableSalespoint annotation to simplify configuration
Activating Salespoint in a web application has been quite cumbersome so far and required a dedicated set of annotations and imports of configuration classes. To simplify this, Salespoint 6.1 introduces `@EnableSalespoint` to take care of the previously manual steps. For more information on what gets acivated and imported, see the link:{javadoc}/org/salespointframework/EnableSalespoint.html[JavaDoc of the annotation].

=== Usage of the mail autoconfiguration shipping with Spring Boot 1.2
As Salespoint 6.1 upgrades to Spring Boot 1.2 we now use the email auto-configuration settings shipping with that release. This most notably means that you slightly have to alter your properties to configure the mail user, password and host. See Boot's http://docs.spring.io/spring-boot/docs/1.2.x/reference/htmlsingle/#boot-features-email[reference documentation] and the http://docs.spring.io/spring-boot/docs/1.2.0.RC2/reference/htmlsingle/#common-application-properties[list of current application properties] for details.

[[architecture]]
= Technical Architecture

Technically Salespoint is a library to build Java based Point of Sales (PoS) applications. Whiles these applications are usually implemented as web applications, large parts of Salespoint are also usable if the application architecture of choice is a rich client implemented in Java.

The technical foundation for Salespoint is the Spring Frameworkfootnote:[Spring Framework - http://en.wikipedia.org/wiki/Spring_Framework[Wikipedia]] and Spring Boot (as some kind of opinionated layer on top of Spring Framework to ease its applicance to a large degree. Salespoint is built using the Maven build systemfootnote:[Apache Maven - http://en.wikipedia.org/wiki/Apache_Maven[Wikipedia]]. The reference documentation and static website are built with Asciidoctorfootnote:[Asciidoctor - http://asciidoctor.org[Website]].

Here you can find the link:images/salespoint-classdiagram.png[salespoint class diagram] about the basic structure.

[[architecture.core-concepts]]
== Core concepts
Before we dive into the technical details of Salespoint, let's make sure we understand some core concepts that will help us understand the different modules of the framework a bit better. Each of the <<modules, modules>> consists of a bit of code and the classes can usually be grouped into 3 different buckets: entities and value objects, summarized to <<architecture.core-concepts.ddd.newables, newables>>, repositories and services, summarized to <<architecture.core-concepts.ddd.injectables, injectables>> as well as <<architecture.core-concepts.container-configuration, Spring container configuration and extension code>>. The following sections will cast some light on these kinds of types and their special traits.

////
[[architecture.core-concepts.ddd.newables]]
=== Entities and value objects

TODO
////

[[architecture.core-concepts.ddd.injectables]]
=== Repositories, services and controllers

Repositories and services are used ot interact with entities and value objects. Repositories usually abstract data access into an interface that simulates a collection of entities that instances can be added to, or looked up using a parameterized criteria like "all users with a certain lastname like…". As Salespoint is using a relational database as persistence backend it leverages the Java Persistence API (JPA) and <<stack.spring-data-jpa, Spring Data JPA>> to implement repositories.

As repositories abstract a collection of an aggregate root (e.g. an order with it's charge and line items), we usually need a higher level abstraction that exposes a more use-case oriented API: a service. It fulfils a more coarse grained set of operations that might include the interaction with multiple repositories, trigger other services in the system etc.

Repositories, services and controllers are types whose instances are managed by the Spring container. Thus they're never instantiated manually in the application code, except for unit testing purposes. Application code uses dependency injection to access

////
[[architecture.core-concepts.container-configuration]]
=== Container configuration and extensions

TODO
////

[[architecture.maven]]
== Maven
_Maven_ simplifies the management of project dependencies, furthermore it downloads and organizes all dependencies. Another focus of _Maven_ is the management of a project's build. All settings are placed in the `pom.xml` file (http://maven.apache.org/pom.html).

[[architecture.spring]]
== Spring
In contrast to earlier versions of the Salespoint Framework, Salespoint {majorversion} obeys the MVC pattern. Salespoint {majorversion} mostly provides the application services to interact with the the model of an MVC application as no parts of the view or the controller are implemented in the framework.

Salespoint {majorversion} is designed as foundation for development of web applications, using the Spring Framework to implement views, controllers and business services abstracting the domain your application-to-be-created is applied to. To ease this development, Salespoint includes a few extensions to the Spring Framework that will avoid you having to implement very tedious tasks over and over again. Read more about this in <<stack.spring>>.

As a big new approach in development with JPA, the Spring Framework with its repository interfaces can make the work very fast, clean and easy. The Crudrepository provides the basic methods for working with the database (CRUD stands for Create, Read, Update and Delete).

[[architecture.configuration]]
==	Configuration of Salespoint {version}

The configuration for an application can be modified on the application class in the root package (e.g.  videoshop.Videoshop for the videoshop project). Methods, annotated with `@Configuration`, will be scanned at the beginning of the deployment on the application server (in this case Spring Boot). This configuration files will tell the application server the settings for the application. By overriding the configuration method, you can specify the login behaviour or security functions. For a basic login strategy the videoshop is a good start. There you can see, that with authorizeRequests() an authorization will be set. Following by matchers, you can specify the pages, this authorization is made on. Further, you can easily set an login page with formLogin() and the path to the login page with loginProcessingUrl("/login"). Analogue the logout settings works like login system.

[[stack]]
= Technical Stack

[[stack.spring-boot]]
== Spring Boot

Rapid application development framework based on Spring (see below).

- http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle[Reference documentation]
- https://spring.io/guides[Getting started guides]
- http://projects.spring.io/spring-boot[Project home]

[[stack.spring]]
== Spring 4

The de-facto standard Java application framework.

- https://spring.io/guides[Getting started guides]
- http://projects.spring.io/spring-framework[Project home]

////
[[stack.spring.core-concepts]]
=== Core concepts

TODO

[[stack.spring.core-concepts.dependency-injection]]
==== Dependency injection

TODO

[[stack.spring.core-concepts.components]]
==== Components and component scanning

TODO
////

[[stack.spring-data-jpa]]
== Spring Data JPA

Spring module to easily build data acess layers using JPA 2.1 (Java Persistence API).

- https://spring.io/guides?filter=jpa[Getting started guides]
- http://projects.spring.io/spring-data-jpa[Project home]

[[stack.thymeleaf]]
== Thymeleaf

Library to build HTML web views using natural templating.

- https://spring.io/guides/gs/serving-web-content[Getting stared guide]
- http://www.thymeleaf.org/doc/usingthymeleaf.html[Tutorial]

[[stack.java-money]]
==  Java Money
With Salespoint {majorversion} `Money` class and its related components were replaced by the Java Money library. Prices and other monetary values are represented as `org.javamoney.moneta.Money` objects. Due to the fact that all representing objects are immutable, all arithmetic functions produce a new instance.

.Example for Money operations
====
[source, java]
----
Money first = Money.parse(“USD 23.07”);
Money second = Money.parse(“USD 18.07”);
Money sum = first.plus(second);
----
====

When used in domain objects, `Money` instances need to be mapped using `@Lob`.

[[modules]]
= Business modules

[[modules.useraccount]]
== User accounts

////
[User|-enabled:boolean]-0..*>[Role]
[User]->[Password]
////
image::user.png[title="User Account"]

image::user-account.png[title="User Account Management"]

While Spring Security is used as primary technology to actually implement application security, there's also a domain abstraction of a user acoount in the form of a `UserAccount` entity.
That means that `UserAccount` instances created within the system are automatically targets for authentication.
The primary purpose of a `UserAccount` besides the security integration is the ability to assign other business entities like an order or a reservation to an account.
As those other business entities often mandate a reference, `UserAccount`s cannot be removed from the system.
That would render the business entities connected to them invalid.
A `UserAccount` primarily consists of a `UserAccountIdentifier` whose `String` representation is used as the login name and a `Password` (representing an encrypted or non-encrypted password) value object.

To create `UserAccounts`, the `UserAccountManager`'s method `create(String userName, String password, Role... role)` can be used.
The `String` given as password will be encrypted using Spring Security.
Also, it makes sure that the login names are unique and a password is always set.

[[modules.useraccount.role]]
=== Roles
As the name suggests, a `Role` represents the role a `UserAccount` has. It is usually used in security expressions with either `@Secured` or in a Thymeleaf template to restrict access to functionality or change the appearance of a view depending on a user’s status.
A view for a user having an administrator role may display different content -- e.g. delete buttons -- than for a user not having that role.

`Role` is a value typefootnoteref:[value-objects, http://blog.joda.org/2014/03/valjos-value-java-objects.html[Value Objects]] and thus instances are created using a factory method: `Role.of("ROLE_ADMIN");`.

[[modules.useraccount.login]]
=== Login
To reduce code repetition, Salespoint {majorversion} contains code to automate the user log in. Using a Thymeleaf template, a special login form is generated, which is handled by an interceptor. The interceptor verifies the user password and associates the current session with the user using `<login>` and `<logoff>`. The session is required, because multiple users can be logged on at the same time.

[[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.

.Example of a UserAccount extension
====
[source, java]
----
@Entity
public class UserAccountExtension {

  private String string;
  private Integer integer;

  @OneToOne
  private UserAccount userAccount;

  …
}
----
====

[[modules.quantity]]
== Quantity
`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.

And of course, every `Quantity` has an amount value, represented as a `java.math.BigDecimal`.

[[modules.quantity.metric]]
=== 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

Salespoint {majorversion} is intended as framework for point-of-sale applications. Items for sale are called products and represented by instances of the class `Product`. To represent different kinds of products, `Product` can be sub-classed. Products are managed by a `Catalog` implementation (see below). Products are identified using a `ProductIndentifier`.

The `Catalog` interface was designed to manage `Product` instances in the system. It provides functionality to add, remove, and find products. Products can be searched by their name or category. The `PersistentCatalog` is an implementation of the `Catalog` interface.

////
[Product]<-[<<Interface>> Catalog]
[<<Interface>> SalespointRepository]^[<<Interface>> Catalog]
////
image::catalog.png[title="Catalog"]

[[modules.inventory]]
== Inventory

The inventory package contains functionality to keep track of the amount of items we have for a given `Product` (see <<modules.catalog>> for details).
`Inventory` is a simple Spring Data repository, that allows to access `InventoryItem` instances:

.The Inventory
[source, java, indent=0]
----
include::{source-base}/inventory/Inventory.java[tags=inventory]
----

=== Handling order completion events

The inventory ships with a listener for `OrderCompleted` events (see <<modules.order.lifecycle>> for details) to update the stock for each line item contained in an `Order`.
By default, an `OrderCompletionFailure` is thrown in case any of the `OrderLine` items aren't available in the required amount.
The exception contains an `OrderCompletionReport` that can be inspected for the item lacking enough stock.

By default, all `OrderLine` instances are processed.
However, you might want to exclude some of them as the `Product` they point to don't represent a product to keep track of (e.g. some service like "gift wrapping" or the like.
The `LineItemFilter` interface allows defining a strategy to decide which of the `OrderLine` instances are supposed to be processed by the inventory.

To customize the strategy, simply declare an implementation of `LineItemFilter` as Spring bean to your application configuration:

.Declaring a custom line item filter
[source, java, indent=0]
----
include::{source-base-test}/inventory/InventoryOrderEventListenerTests.java[tags=custom-line-item-filter]
----

A declaration like this will cause only `OrderLine` instances pointing to `Product` instance with a matching name to be subject for reduction in the inventory.

[[modules.accountancy]]
== Accountancy
The accountancy package contains functionality supporting book keeping. `AccountancyEntry` is a representation of an accounting entry. `Accountancy` aggregates ``AccountancyEntry``s. Every `AccountancyEntry` is uniquely identified by an ``AccountancyEntryIdentifier``. `AccountancyEntry` extends `AbstractEntity` and serves as persistence entity, while `PersistentAccountancy` implements `Accountancy` and provides transparent access to the JPA layer. `AccountancyEntryIdentifier` is used as primary key attribute, when entities are stored in the database.

////
[<<Interface>> Accountancy]^-.-[PersistentAccountancy]
[PersistentAccountancy]uses-.->[<<Interface>> AccountancyEntryRepository]
[AccountancyEntry|-id:AccountancyEntryIdentifier]
////
image::accountancy.png[Accountancy, title="Accountancy"]

By implementing and sub-classing `Accountancy`, the notion of different accounts, as known from double-entry bookkeeping, can be realised.

To create a new account, `AccountancyEntry` has to be sub-classed. Every object of such a class belongs to the same account. Accessing per-account entries is facilitated by specifiying the desired class type when calling `get()` or `find()` methods of `Accountancy`.

[[modules.accountancy.payment-entry]]
=== Handling OrderPaid events

The accountancy subsystem handles `OrderPaid` events by creating a `ProductPaymentEntry` for the order.

[[modules.payment]]
== Payments

////
[PaymentMethod]^[Cash]
[PaymentMethod]^[Cheque]
[PaymentMethod]^[PaymentCard]
[PaymentCard]^[DebitCard]
[PaymentCard]^[CreditCard]
////
image::payment-method.png[title="Payment domain types"]

For the paying transaction, Salespoint provides some payment strategies.

* `DebitCard` -- representation of e.g. EC-card or MaestroCard
* `CreditCard` -- equal to `DebitCard` but with creditLimit-Attribute
* `Cheque` -- represents a written order of payment in a digital form
* `Cash` -- represents a payment, made direct in cash

[[modules.order]]
== Order
An `Order` can be considered as a sheet of paper which basically consists of lines, each representing an ordered product. An order can be uniquely identified by an `OrderIdentifier`. Every product of an order is stored in a separate `OrderLine`. An `OrderLine` in turn is uniquely identified by an `OrderLineIdentifier`. An `OrderLine` contains all information to identify a `Product` (see Section <<modules.catalog>> ).

////
[Order]->[UserAccount]
[Order]->[PaymentMethod]
[Order|-id:OrderIdentifier;-orderStatus:OrderStatus;-dateCreated:LocalDateTime]1++-*>[OrderLine]
[Order]1++-*>[ChargeLine]
////
image::order-light.png[title="Order"]

A `ChargeLine` represents additional costs or discounts and can be applied to an `OrderLine` or an `Order`. A `ChargeLine` is uniquely identified by a `ChargeLineIdentifier`.

TIP: For example, ``ChargeLine``s can be used to handle special taxes or handling fees.

[[modules.order.lifecycle]]
=== The Order lifecycle
image::order-status-lifecycle.png[title="Order status lifecycle state machine"]

An `Order` is an aggregate rootfootnote:[ http://static.olivergierke.de/lectures/ddd-and-spring/#ddd.building-blocks.aggregates[Aggregate root]], which means that state changes to it that have important business meaning trigger events.
These events are then used by other business modules to act on them.
Currently, the following events are exposed:

* `OrderPaid` -- the event being throw if the order gets paid, usually through a call to `OrderManager.pay(…)`. The <<modules.accountancy>> module makes use of those events as described in <<modules.accountancy.payment-entry>>.
* `OrderCompleted` -- the event being thrown when the `Order` is about to be completed, usually through a call to `OrderManager.completeOrder(…)`. The <<modules.inventory>> module ships with a listener for the `OrderCompleted` event to update the inventory and reduce the stock of ordered items.

[[modules.order.handling-events]]
==== Handling events

In case you want to write custom code to react to those events you need to implement an event handler.
An event handler is a simple Spring component that has methods annotated with either `@EventListener` or `@TransactionalEventListener`.

[source, java]
----
@Component
class MyEventListener {

	@EventListener
	public void handleEvent(OrderCompleted event) {
		// Your code goes here
	}

	// alternatively

	@TransactionalEventListener
	public void handleEventAfterTransaction(OrderCompleted event) {
		// Your code goes here
	}
}
----

The difference between the two methods is when they're actually invoked by the framework.
The former method is called before the changes to the database are eventually persisted to the database.
That means, the event listener can throw an exception and the action that caused the event to be published in the first place will be canceled, too.
On the other hand an `@EventListener` will not be guaranteed that the original action will succeed as it might be rejected if it violates e.g. database constraints.
In contrast, a `@TransactionalEventListener` will be called after the original action has completed successfully.
That in turn means, that the listener has no chance to abort that action.

[[modules.business-time]]
== Business time

To be able to simulate the state of the system in a given point in time all components in the system that set a point in time on entities or lookup the current time use the `BusinessTime` interface.

By default, the implementation will just return the current system date. However, it also allows to "forward" the current business time by calling the `BusinessTime.forward(…)` method. This will augment the current business time by the duration handed into the method. E.g. forwading the business time by 2 months will return the very same time but two months ahead for each call to `BusinessTime.getTime()`.

This is particularly useful for demoing purposes if e.g. orders can be timed to a certain date, credit cards become invalid after a certain point in time etc.

////
[<<Interface>> BusinessTime]^[DefaultBusinessTime]
////
image::business-time.png[title="Business time"]

[[modules.technical-apis]]
== Technical APIs

Besides the business modules, Salespoint containes a few <<glossary.spi,SPIs>> that can be used to extend the functionality of the core framework. These SPIs usually exist to make repeated use-cases easier to implement and free you from writing too much boilerplate code.

[[modules.technical-apis.data-initializer]]
=== DataInitializer

Every application should be tested, so an easy way is, to use test data. Salespoint provides an SPI called `DataInitializer` for you to implement. If your implementation is registered as Spring bean (e.g. by annotating it with `@Component`), it will automatically be found and `initialize()` will be called at application startup. As shown in the Videoshop project, a `DataInitializer` class is registered and creates a lot of data and finally adds this data to the application.

= Appendix

[appendix]
== FAQ

[qanda]
Why do I see warning log statements about database tables not being accessible at startup?::
  This is due to a bug in Hibernate in combination with HSQLDB and constraints in databases. Hibernate tries to drop those on application startup but fails to as the (in-memory database) is empty. See https://hibernate.atlassian.net/browse/HHH-9038[this bug report] for reference.

How do I send emails from a Salespoint application?::
  Salespoint has everything prepared for you in terms of necessary dependencies. All you need to do is configure the following properties in `application.properties`:
+
[source]
----
spring.mail.host=
spring.mail.username=
spring.mail.password=
----
If these properties get real values assigned, Salespoint will automatically create a Spring component of type `JavaMailSender` for you that you can inject into your clients and use to send emails. See the Spring reference documentation on details for that.
+
WARNING: Never push your email credentials into the version control system.
+
Alternatively for testing purposes, configure the `RecordingMailSender` as a Spring bean to simply write emails to be sent to the console instead of sending them to a real SMTP server. To automatically switch between the two setups have a look at how to use Spring's http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-profiles[profile support with Boot].

[[glossary]]
[appendix, glossary]
== Glossary

[[glossary.dependency-injection]]
Dependency injection::
   Dependency injection is a software design pattern that implements inversion of control and allows a program design to follow the dependency inversion principle. The term was coined by Martin Fowler. See http://en.wikipedia.org/wiki/Dependency_injection[Wikipedia].

[[glossary.spi]]
SPI::
   Service Provider Interface -- interfaces to be implemented to extend the functionality of the core framework. See http://en.wikipedia.org/wiki/Service_provider_interface[Wikipedia] for details.

[[bibliography]]
[appendix, bibliography]
== Bibliography
- [[[ddd]]] Eric Evans. Domain-Driven Design: Tackling Complexity in the Heart of Software. Prentice Hall. 2003
- [[[epam]]] Jim Arlow, Ila Neustadt. Enterprise Patterns and MDA: Building Better Software with Archetype Patterns and UML. Addison-Wesley. 2004.
- [[[di]]] Martin Fowler. Inversion of Control Containers and the Dependency Injection pattern. 2004. http://www.martinfowler.com/articles/injection.html
