diff --git a/.project b/.project
index b51ee30c..272fa001 100644
--- a/.project
+++ b/.project
@@ -20,4 +20,16 @@
org.eclipse.jdt.core.javanature
org.eclipse.m2e.core.maven2Nature
+
+
+ 1613163986495
+
+
+ 30
+
+ org.eclipse.core.resources.regexFilterMatcher
+ node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
+
+
+
diff --git a/signIn.html b/signIn.html
new file mode 100644
index 00000000..34be12ac
--- /dev/null
+++ b/signIn.html
@@ -0,0 +1,41 @@
+
+
+
+ Register - Sign In
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/signIn.js b/signIn.js
new file mode 100644
index 00000000..c2dd38b7
--- /dev/null
+++ b/signIn.js
@@ -0,0 +1,39 @@
+document.addEventListener("DOMContentLoaded", function(event) {
+ const employeeIdEditElement = getEmployeeId();
+ employeeIdEditElement.focus();
+ employeeIdEditElement.select();
+});
+
+//Get elements for the Employee Id and Password
+function getEmployeeId() {
+ return document.getElementById("employeeId");
+}
+
+function getPassword() {
+ return document.getElementById("password");
+}
+
+//Validates the Id is not blank and is a number; Validates that Password is not null
+function validateForm() {
+ const employeeIdEditElement = getEmployeeId();
+ if(isNaN(Number(employeeIdEditElement.value)) || (Number(employeeIdEditElement.value) <= 0))
+ {
+ displayError("Employee Id must be a positive numerical value.");
+
+ employeeIdEditElement.focus();
+ employeeIdEditElement.select();
+ return false;
+ }
+
+ const passwordEditElement = getPassword();
+ if ((passwordEditElement.value == null) || (passwordEditElement.value.trim() === ""))
+ {
+ displayError("Password must be valid and cannot be blank.");
+
+ passwordEditElement.focus();
+ passwordEditElement.select();
+ return false;
+
+ }
+ return true;
+}
diff --git a/src/main/java/edu/uark/registerapp/commands/activeUsers/ActiveUserDeleteCommand.java b/src/main/java/edu/uark/registerapp/commands/activeUsers/ActiveUserDeleteCommand.java
new file mode 100644
index 00000000..eed29928
--- /dev/null
+++ b/src/main/java/edu/uark/registerapp/commands/activeUsers/ActiveUserDeleteCommand.java
@@ -0,0 +1,82 @@
+/*package edu.uark.registerapp.commands.activeUsers;
+
+import java.util.Optional;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.pringframework.transaction.annotation.Transactional;
+
+
+import edu.uark.registerapp.commands.VoidCommandInterface;
+import edu.uark.registerapp.nodels.entities.ActiveUserEntity;
+import edu.uark.registerapp.models.repositories.ActiveUserRepository;
+
+@Service
+public class ActiveUserDeleteCommand implements VoidCommandInterface{
+ @Override
+ @Transactional
+ public void execute(){
+ final Optional activeUserEntity=
+ this.activeUserRepository.findBySessionKey(this.sessionKey);
+
+ if(!activeUserEntity.isPresent()){
+ this.activeUserRepository.delete(activeUserEntity.get());
+ }
+ }
+
+ private String sessionKey;
+
+ public String getSessionKey(){
+ return this.sessionKey;
+ }
+
+ public ActiveUserDeleteCommand setSessionKey(final String sessionKey){
+ this.sessionKey = sessionKey;
+ return this;
+ }
+
+ @Autowired
+ private ActiveUserRepository activeUserRepository;
+}
+*/
+
+
+package edu.uark.registerapp.commands.activeUsers;
+
+import java.util.Optional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import edu.uark.registerapp.commands.VoidCommandInterface;
+import edu.uark.registerapp.models.entities.ActiveUserEntity;
+import edu.uark.registerapp.models.repositories.ActiveUserRepository;
+
+@Service
+public class ActiveUserDeleteCommand implements VoidCommandInterface {
+ @Transactional
+ @Override
+ public void execute() {
+ final Optional activeUserEntity =
+ this.activeUserRepository.findBySessionKey(this.sessionKey);
+
+ if (activeUserEntity.isPresent()) {
+ this.activeUserRepository.delete(activeUserEntity.get());
+ }
+ }
+
+ // Properties
+ private String sessionKey;
+ public String getSessionKey() {
+ return this.sessionKey;
+ }
+ public ActiveUserDeleteCommand setSessionKey(final String sessionKey) {
+ this.sessionKey = sessionKey;
+ return this;
+ }
+
+ @Autowired
+ private ActiveUserRepository activeUserRepository;
+}
diff --git a/src/main/java/edu/uark/registerapp/commands/employees/ActiveEmployeeExistsQuery.java b/src/main/java/edu/uark/registerapp/commands/employees/ActiveEmployeeExistsQuery.java
new file mode 100644
index 00000000..29c8f85a
--- /dev/null
+++ b/src/main/java/edu/uark/registerapp/commands/employees/ActiveEmployeeExistsQuery.java
@@ -0,0 +1,20 @@
+package edu.uark.registerapp.commands.employees;
+
+import org.apache.commons.lang3.StringUtils;
+import edu.uark.registerapp.models.repositories.EmployeeRepository;
+import edu.uark.registerapp.commands.exceptions.NotFoundException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ActiveEmployeeExistsQuery implements EmployeeRepository{
+ @Override
+ public void ActiveEmployeeExistsQuery(){
+ if(!this.employeeRepository.existsByIsActive(true)){
+ throw new NotFoundException("Employee");
+ }
+ }
+
+ @Autowire
+ private EmployeeRepository employeeRepository;
+}
diff --git a/src/main/java/edu/uark/registerapp/commands/employees/EmployeeCreateCommand.java b/src/main/java/edu/uark/registerapp/commands/employees/EmployeeCreateCommand.java
new file mode 100644
index 00000000..0da298fb
--- /dev/null
+++ b/src/main/java/edu/uark/registerapp/commands/employees/EmployeeCreateCommand.java
@@ -0,0 +1,89 @@
+package edu.uark.registerapp.commands.employees;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import edu.uark.registerapp.commands.ResultCommandInterface;
+import edu.uark.registerapp.commands.employees.helpers.EmployeeHelper;
+import edu.uark.registerapp.commands.exceptions.UnprocessableEntityException;
+import edu.uark.registerapp.models.api.Employee;
+import edu.uark.registerapp.models.entities.EmployeeEntity;
+import edu.uark.registerapp.models.enums.EmployeeClassification;
+import edu.uark.registerapp.models.repositories.EmployeeRepository;
+
+@Service
+public class EmployeeCreateCommand implements ResultCommandInterface {
+ @Override
+ public Employee execute() {
+ this.validateProperties();
+
+ if (this.isInitialEmployee) {
+ this.apiEmployee.setClassification(
+ EmployeeClassification.GENERAL_MANAGER.getClassification());
+ }
+
+ // Create a new ENTITY object from the API object details.
+ final EmployeeEntity employeeEntity =
+ this.employeeRepository.save(new EmployeeEntity(this.apiEmployee));
+
+ // Synchronize information generated by the database upon INSERT.
+ this.apiEmployee.setId(employeeEntity.getId());
+ // Only send the password over the network when modifying the database.
+ this.apiEmployee.setPassword(StringUtils.EMPTY);
+ this.apiEmployee.setCreatedOn(employeeEntity.getCreatedOn());
+ this.apiEmployee.setEmployeeId(
+ EmployeeHelper.padEmployeeId(
+ employeeEntity.getEmployeeId()));
+
+ return this.apiEmployee;
+ }
+
+ // Helper methods
+ private void validateProperties() {
+ if (StringUtils.isBlank(this.apiEmployee.getFirstName())) {
+ throw new UnprocessableEntityException("first name");
+ }
+ if (StringUtils.isBlank(this.apiEmployee.getLastName())) {
+ throw new UnprocessableEntityException("last name");
+ }
+ if (StringUtils.isBlank(this.apiEmployee.getPassword())) {
+ throw new UnprocessableEntityException("password");
+ }
+
+ if (!this.isInitialEmployee
+ && (EmployeeClassification.map(this.apiEmployee.getClassification()) == EmployeeClassification.NOT_DEFINED)) {
+
+ throw new UnprocessableEntityException("classification");
+ }
+ }
+
+ // Properties
+ private Employee apiEmployee;
+ public Employee getApiEmployee() {
+ return this.apiEmployee;
+ }
+ public EmployeeCreateCommand setApiEmployee(final Employee apiEmployee) {
+ this.apiEmployee = apiEmployee;
+ return this;
+ }
+
+ private boolean isInitialEmployee;
+ public boolean getIsInitialEmployee() {
+ return this.isInitialEmployee;
+ }
+ public EmployeeCreateCommand setIsInitialEmployee(
+ final boolean isInitialEmployee
+ ) {
+
+ this.isInitialEmployee = isInitialEmployee;
+ return this;
+ }
+
+ @Autowired
+ private EmployeeRepository employeeRepository;
+
+ public EmployeeCreateCommand() {
+ this.isInitialEmployee = false;
+ }
+}
diff --git a/src/main/java/edu/uark/registerapp/commands/employees/EmployeeDeleteCommand.java b/src/main/java/edu/uark/registerapp/commands/employees/EmployeeDeleteCommand.java
new file mode 100644
index 00000000..da485479
--- /dev/null
+++ b/src/main/java/edu/uark/registerapp/commands/employees/EmployeeDeleteCommand.java
@@ -0,0 +1,42 @@
+package edu.uark.registerapp.commands.employees;
+
+import java.util.Optional;
+import java.util.UUID;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import edu.uark.registerapp.commands.VoidCommandInterface;
+import edu.uark.registerapp.commands.exceptions.NotFoundException;
+import edu.uark.registerapp.models.entities.EmployeeEntity;
+import edu.uark.registerapp.models.repositories.EmployeeRepository;
+
+@Service
+public class EmployeeDeleteCommand implements VoidCommandInterface {
+ @Transactional
+ @Override
+ public void execute() {
+ final Optional employeeEntity =
+ this.employeeRepository.findById(this.employeeId);
+
+ if (!employeeEntity.isPresent()) { // No record with the associated record ID exists in the database.
+ throw new NotFoundException("Product");
+ }
+
+ this.employeeRepository.delete(employeeEntity.get());
+ }
+
+ // Properties
+ private UUID employeeId;
+ public UUID getEmployeeId() {
+ return this.employeeId;
+ }
+ public EmployeeDeleteCommand setEmployeeId(final UUID productId) {
+ this.employeeId = productId;
+ return this;
+ }
+
+ @Autowired
+ private EmployeeRepository employeeRepository;
+}
diff --git a/src/main/java/edu/uark/registerapp/commands/employees/EmployeeQuery.java b/src/main/java/edu/uark/registerapp/commands/employees/EmployeeQuery.java
new file mode 100644
index 00000000..0fcfb8e8
--- /dev/null
+++ b/src/main/java/edu/uark/registerapp/commands/employees/EmployeeQuery.java
@@ -0,0 +1,41 @@
+package edu.uark.registerapp.commands.employees;
+
+import java.util.Optional;
+import java.util.UUID;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import edu.uark.registerapp.commands.ResultCommandInterface;
+import edu.uark.registerapp.commands.exceptions.NotFoundException;
+import edu.uark.registerapp.models.api.Employee;
+import edu.uark.registerapp.models.entities.EmployeeEntity;
+import edu.uark.registerapp.models.repositories.EmployeeRepository;
+
+@Service
+public class EmployeeQuery implements ResultCommandInterface {
+ @Override
+ public Employee execute() {
+ final Optional employeeEntity =
+ this.employeeRepository.findById(this.employeeId);
+
+ if (employeeEntity.isPresent()) {
+ return new Employee(employeeEntity.get());
+ } else {
+ throw new NotFoundException("Employee");
+ }
+ }
+
+ // Properties
+ private UUID employeeId;
+ public UUID getEmployeeId() {
+ return this.employeeId;
+ }
+ public EmployeeQuery setEmployeeId(final UUID employeeId) {
+ this.employeeId = employeeId;
+ return this;
+ }
+
+ @Autowired
+ private EmployeeRepository employeeRepository;
+}
diff --git a/src/main/java/edu/uark/registerapp/commands/employees/EmployeeSignInCommand.java b/src/main/java/edu/uark/registerapp/commands/employees/EmployeeSignInCommand.java
new file mode 100644
index 00000000..ad757154
--- /dev/null
+++ b/src/main/java/edu/uark/registerapp/commands/employees/EmployeeSignInCommand.java
@@ -0,0 +1,108 @@
+package edu.uark.registerapp.commands.employees;
+
+import java.util.Arrays;
+import java.util.Optional;
+
+import javax.transaction.Transactional;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import edu.uark.registerapp.commands.ResultCommandInterface;
+import edu.uark.registerapp.commands.employees.helpers.EmployeeHelper;
+import edu.uark.registerapp.commands.exceptions.UnauthorizedException;
+import edu.uark.registerapp.commands.exceptions.UnprocessableEntityException;
+import edu.uark.registerapp.models.api.Employee;
+import edu.uark.registerapp.models.api.EmployeeSignIn;
+import edu.uark.registerapp.models.entities.ActiveUserEntity;
+import edu.uark.registerapp.models.entities.EmployeeEntity;
+import edu.uark.registerapp.models.repositories.ActiveUserRepository;
+import edu.uark.registerapp.models.repositories.EmployeeRepository;
+
+@Service
+public class EmployeeSignInCommand implements ResultCommandInterface {
+ @Override
+ public Employee execute() {
+ this.validateProperties();
+
+ return new Employee(this.SignInEmployee());
+ }
+
+ // Helper methods
+ private void validateProperties() {
+ if (StringUtils.isBlank(this.employeeSignIn.getEmployeeId())) {
+ throw new UnprocessableEntityException("employee ID");
+ }
+ try {
+ Integer.parseInt(this.employeeSignIn.getEmployeeId());
+ } catch (final NumberFormatException e) {
+ throw new UnprocessableEntityException("employee ID");
+ }
+ if (StringUtils.isBlank(this.employeeSignIn.getPassword())) {
+ throw new UnprocessableEntityException("password");
+ }
+ }
+
+ @Transactional
+ private EmployeeEntity SignInEmployee() {
+ final Optional employeeEntity =
+ this.employeeRepository.findByEmployeeId(
+ Integer.parseInt(this.employeeSignIn.getEmployeeId()));
+
+ if (!employeeEntity.isPresent()
+ || !Arrays.equals(
+ employeeEntity.get().getPassword(),
+ EmployeeHelper.hashPassword(this.employeeSignIn.getPassword()))
+ ) {
+
+ throw new UnauthorizedException();
+ }
+
+ final Optional activeUserEntity =
+ this.activeUserRepository
+ .findByEmployeeId(employeeEntity.get().getId());
+
+ if (!activeUserEntity.isPresent()) {
+ this.activeUserRepository.save(
+ (new ActiveUserEntity())
+ .setSessionKey(this.sessionId)
+ .setEmployeeId(employeeEntity.get().getId())
+ .setClassification(
+ employeeEntity.get().getClassification())
+ .setName(
+ employeeEntity.get().getFirstName()
+ .concat(" ")
+ .concat(employeeEntity.get().getLastName())));
+ } else {
+ this.activeUserRepository.save(
+ activeUserEntity.get().setSessionKey(this.sessionId));
+ }
+
+ return employeeEntity.get();
+ }
+
+ // Properties
+ private EmployeeSignIn employeeSignIn;
+ public EmployeeSignIn getEmployeeSignIn() {
+ return this.employeeSignIn;
+ }
+ public EmployeeSignInCommand setEmployeeSignIn(final EmployeeSignIn employeeSignIn) {
+ this.employeeSignIn = employeeSignIn;
+ return this;
+ }
+
+ private String sessionId;
+ public String getSessionId() {
+ return this.sessionId;
+ }
+ public EmployeeSignInCommand setSessionId(final String sessionId) {
+ this.sessionId = sessionId;
+ return this;
+ }
+
+ @Autowired
+ private EmployeeRepository employeeRepository;
+ @Autowired
+ private ActiveUserRepository activeUserRepository;
+}
diff --git a/src/main/java/edu/uark/registerapp/commands/employees/EmployeeUpdateCommand.java b/src/main/java/edu/uark/registerapp/commands/employees/EmployeeUpdateCommand.java
new file mode 100644
index 00000000..0fd64d7a
--- /dev/null
+++ b/src/main/java/edu/uark/registerapp/commands/employees/EmployeeUpdateCommand.java
@@ -0,0 +1,80 @@
+package edu.uark.registerapp.commands.employees;
+
+import java.util.Optional;
+import java.util.UUID;
+
+import javax.transaction.Transactional;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import edu.uark.registerapp.commands.ResultCommandInterface;
+import edu.uark.registerapp.commands.exceptions.NotFoundException;
+import edu.uark.registerapp.commands.exceptions.UnprocessableEntityException;
+import edu.uark.registerapp.models.api.Employee;
+import edu.uark.registerapp.models.entities.EmployeeEntity;
+import edu.uark.registerapp.models.enums.EmployeeClassification;
+import edu.uark.registerapp.models.repositories.EmployeeRepository;
+
+@Service
+public class EmployeeUpdateCommand implements ResultCommandInterface {
+ @Override
+ public Employee execute() {
+ this.validateProperties();
+
+ this.updateEmployeeEntity();
+
+ return this.apiEmployee;
+ }
+
+ // Helper methods
+ private void validateProperties() {
+ if (StringUtils.isBlank(this.apiEmployee.getFirstName())) {
+ throw new UnprocessableEntityException("first name");
+ }
+ if (StringUtils.isBlank(this.apiEmployee.getLastName())) {
+ throw new UnprocessableEntityException("last name");
+ }
+ if (EmployeeClassification.map(this.apiEmployee.getClassification()) == EmployeeClassification.NOT_DEFINED) {
+ throw new UnprocessableEntityException("classification");
+ }
+ }
+
+ @Transactional
+ private void updateEmployeeEntity() {
+ final Optional queriedEmployeeEntity =
+ this.employeeRepository.findById(this.employeeId);
+
+ if (!queriedEmployeeEntity.isPresent()) {
+ throw new NotFoundException("Employee"); // No record with the associated record ID exists in the database.
+ }
+
+ this.apiEmployee = queriedEmployeeEntity.get()
+ .synchronize(this.apiEmployee); // Synchronize any incoming changes for UPDATE to the database.
+
+ this.employeeRepository.save(queriedEmployeeEntity.get()); // Write, via an UPDATE, any changes to the database.
+ }
+
+ // Properties
+ private UUID employeeId;
+ public UUID getEmployeeId() {
+ return this.employeeId;
+ }
+ public EmployeeUpdateCommand setEmployeeId(final UUID employeeId) {
+ this.employeeId = employeeId;
+ return this;
+ }
+
+ private Employee apiEmployee;
+ public Employee getApiEmployee() {
+ return this.apiEmployee;
+ }
+ public EmployeeUpdateCommand setApiEmployee(final Employee apiEmployee) {
+ this.apiEmployee = apiEmployee;
+ return this;
+ }
+
+ @Autowired
+ private EmployeeRepository employeeRepository;
+}
diff --git a/src/main/java/edu/uark/registerapp/controllers/MainMenuRouteController.java b/src/main/java/edu/uark/registerapp/controllers/MainMenuRouteController.java
new file mode 100644
index 00000000..45ac89e6
--- /dev/null
+++ b/src/main/java/edu/uark/registerapp/controllers/MainMenuRouteController.java
@@ -0,0 +1,47 @@
+package edu.uark.registerapp.controllers;
+
+import java.util.Map;
+import java.util.Optional;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.stereotype.Controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.ModelAndView;
+
+import edu.uark.registerapp.controllers.enums.ViewModelNames;
+import edu.uark.registerapp.controllers.enums.ViewNames;
+import edu.uark.registerapp.models.entities.ActiveUserEntity;
+
+@Controller
+@RequestMapping(value = "/mainMenu")
+public class MainMenuRouteController extends BaseRouteController {
+ @RequestMapping(method = RequestMethod.GET)
+ public ModelAndView start(
+ @RequestParam final Map queryParameters,
+ final HttpServletRequest request
+ ) {
+
+ final Optional activeUserEntity =
+ this.getCurrentUser(request);
+ if (!activeUserEntity.isPresent()) {
+ return this.buildInvalidSessionResponse();
+ }
+
+ ModelAndView modelAndView =
+ this.setErrorMessageFromQueryString(
+ new ModelAndView(ViewNames.MAIN_MENU.getViewName()),
+ queryParameters);
+
+ modelAndView.addObject(
+ ViewModelNames.IS_ELEVATED_USER.getValue(),
+ true);
+
+ return modelAndView;
+ }
+
+}
+
diff --git a/src/main/java/edu/uark/registerapp/controllers/ProductListingRouteController.java b/src/main/java/edu/uark/registerapp/controllers/ProductListingRouteController.java
index 3c2a1178..e96a45fb 100644
--- a/src/main/java/edu/uark/registerapp/controllers/ProductListingRouteController.java
+++ b/src/main/java/edu/uark/registerapp/controllers/ProductListingRouteController.java
@@ -12,7 +12,7 @@
import edu.uark.registerapp.models.api.Product;
@Controller
-@RequestMapping(value = "/")
+@RequestMapping(value = "/productListing")
public class ProductListingRouteController {
@RequestMapping(method = RequestMethod.GET)
public ModelAndView showProductListing() {
diff --git a/src/main/java/edu/uark/registerapp/controllers/SignInRestController.java b/src/main/java/edu/uark/registerapp/controllers/SignInRestController.java
new file mode 100644
index 00000000..8ec7ef25
--- /dev/null
+++ b/src/main/java/edu/uark/registerapp/controllers/SignInRestController.java
@@ -0,0 +1,34 @@
+package edu.uark.registerapp.controllers;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import edu.uark.registerapp.commands.activeUsers.ActiveUserDeleteCommand;
+import edu.uark.registerapp.controllers.enums.ViewNames;
+import edu.uark.registerapp.models.api.ApiResponse;
+
+@RestController
+@RequestMapping(value = "/api")
+public class SignInRestController extends BaseRestController {
+ @RequestMapping(value="/signOut", method = RequestMethod.DELETE)
+ public @ResponseBody ApiResponse removeActiveUser(
+ final HttpServletRequest request
+ ) {
+
+ this.activeUserDeleteCommand
+ .setSessionKey(request.getSession().getId())
+ .execute();
+
+ return (new ApiResponse())
+ .setRedirectUrl(ViewNames.SIGN_IN.getRoute());
+ }
+
+ // Properties
+ @Autowired
+ private ActiveUserDeleteCommand activeUserDeleteCommand;
+}
diff --git a/src/main/java/edu/uark/registerapp/controllers/SignInRouteController.java b/src/main/java/edu/uark/registerapp/controllers/SignInRouteController.java
new file mode 100644
index 00000000..749ace20
--- /dev/null
+++ b/src/main/java/edu/uark/registerapp/controllers/SignInRouteController.java
@@ -0,0 +1,89 @@
+package edu.uark.registerapp.controllers;
+
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.ModelAndView;
+
+import edu.uark.registerapp.commands.employees.ActiveEmployeeExistsQuery;
+import edu.uark.registerapp.commands.employees.EmployeeSignInCommand;
+import edu.uark.registerapp.commands.exceptions.NotFoundException;
+import edu.uark.registerapp.controllers.enums.QueryParameterNames;
+import edu.uark.registerapp.controllers.enums.ViewModelNames;
+import edu.uark.registerapp.controllers.enums.ViewNames;
+import edu.uark.registerapp.models.api.EmployeeSignIn;
+
+@Controller
+@RequestMapping(value = "/")
+public class SignInRouteController extends BaseRouteController {
+ @RequestMapping(method = RequestMethod.GET)
+ public ModelAndView showSignIn(
+ @RequestParam final Map queryParameters
+ ) {
+
+ try {
+ this.activeEmployeeExistsQuery.execute();
+ } catch (NotFoundException e) {
+ return new ModelAndView(
+ REDIRECT_PREPEND.concat(
+ ViewNames.EMPLOYEE_DETAIL.getRoute()));
+ }
+
+ ModelAndView modelAndView =
+ this.setErrorMessageFromQueryString(
+ new ModelAndView(ViewNames.SIGN_IN.getViewName()),
+ queryParameters);
+
+ if (queryParameters.containsKey(QueryParameterNames.EMPLOYEE_ID.getValue())) {
+ modelAndView.addObject(
+ ViewModelNames.EMPLOYEE_ID.getValue(),
+ queryParameters.get(QueryParameterNames.EMPLOYEE_ID.getValue()));
+ }
+
+ return modelAndView;
+ }
+
+ @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
+ public ModelAndView performSignIn(
+ EmployeeSignIn employeeSignIn,
+ HttpServletRequest request
+ ) {
+
+ try {
+ this.employeeSignInCommand
+ .setSessionId(request.getSession().getId())
+ .setEmployeeSignIn(employeeSignIn)
+ .execute();
+ } catch (Exception e) {
+ ModelAndView modelAndView =
+ new ModelAndView(ViewNames.SIGN_IN.getViewName());
+
+ modelAndView.addObject(
+ ViewModelNames.ERROR_MESSAGE.getValue(),
+ e.getMessage());
+ modelAndView.addObject(
+ ViewModelNames.EMPLOYEE_ID.getValue(),
+ employeeSignIn.getEmployeeId());
+
+ return modelAndView;
+ }
+
+ return new ModelAndView(
+ REDIRECT_PREPEND.concat(
+ ViewNames.MAIN_MENU.getRoute()));
+ }
+
+ // Properties
+ @Autowired
+ private EmployeeSignInCommand employeeSignInCommand;
+
+ @Autowired
+ private ActiveEmployeeExistsQuery activeEmployeeExistsQuery;
+}
diff --git a/src/main/java/edu/uark/registerapp/controllers/enums/ViewModelNames.java b/src/main/java/edu/uark/registerapp/controllers/enums/ViewModelNames.java
index 7c39b102..fefde2fd 100644
--- a/src/main/java/edu/uark/registerapp/controllers/enums/ViewModelNames.java
+++ b/src/main/java/edu/uark/registerapp/controllers/enums/ViewModelNames.java
@@ -3,8 +3,12 @@
public enum ViewModelNames {
NOT_DEFINED(""),
ERROR_MESSAGE("errorMessage"),
+ IS_ELEVATED_USER("isElevatedUser"),
PRODUCTS("products"), // Product listing
- PRODUCT("product"); // Product detail
+ PRODUCT("product"), // Product detail
+ EMPLOYEE_ID("employeeId"), // Sign in
+ EMPLOYEE("employee"), // Employee detail
+ EMPLOYEE_TYPES("employeeTypes");
public String getValue() {
return value;
diff --git a/src/main/java/edu/uark/registerapp/models/api/EmployeeSignIn.java b/src/main/java/edu/uark/registerapp/models/api/EmployeeSignIn.java
new file mode 100644
index 00000000..e01e4f6c
--- /dev/null
+++ b/src/main/java/edu/uark/registerapp/models/api/EmployeeSignIn.java
@@ -0,0 +1,28 @@
+package edu.uark.registerapp.models.api;
+
+import org.apache.commons.lang3.StringUtils;
+
+public class EmployeeSignIn {
+ private String employeeId;
+ public String getEmployeeId() {
+ return this.employeeId;
+ }
+ public EmployeeSignIn setEmployeeId(final String employeeId) {
+ this.employeeId = employeeId;
+ return this;
+ }
+
+ private String password;
+ public String getPassword() {
+ return this.password;
+ }
+ public EmployeeSignIn setPassword(final String password) {
+ this.password = password;
+ return this;
+ }
+
+ public EmployeeSignIn() {
+ this.password = StringUtils.EMPTY;
+ this.employeeId = StringUtils.EMPTY;
+ }
+}
diff --git a/src/main/resources/static/images/Sign-Out.jpeg b/src/main/resources/static/images/Sign-Out.jpeg
new file mode 100644
index 00000000..82fe8695
Binary files /dev/null and b/src/main/resources/static/images/Sign-Out.jpeg differ
diff --git a/src/main/resources/static/scripts/mainMenu.js b/src/main/resources/static/scripts/mainMenu.js
new file mode 100644
index 00000000..a2e52f9e
--- /dev/null
+++ b/src/main/resources/static/scripts/mainMenu.js
@@ -0,0 +1,36 @@
+document.addEventListener("DOMContentLoaded", function(event) {
+
+ getStartTransactionActionElement().addEventListener("click", () => { displayError("Functionality has not yet been implemented."); });
+ getViewProductsActionElement().addEventListener("click", () => { window.location.assign("./productListing.html"); });
+
+ getStartTransactionActionElement().addEventListener("click", () => { displayError("Functionality has not yet been implemented. Functionality"); });
+ //getViewProductsActionElement().addEventListener("click", () => { window.location.assign("/src/main/resources/templates/productDetail.html"); });
+
+ getCreateEmployeeActionElement().addEventListener("click", () => { window.location.assign("./employeeDetail.html"); });
+ getProductSalesReportActionElement().addEventListener("click", () => { displayError("Functionality has not yet been implemented."); });
+ getCashierSalesReportActionElement().addEventListener("click", () => { displayError("Functionality has not yet been implemented."); });
+
+});
+
+// Getters and setters
+function getViewProductsActionElement() {
+ return document.getElementById("viewProductsButton");
+}
+
+function getCreateEmployeeActionElement() {
+ return document.getElementById("createEmployeeButton");
+}
+
+function getStartTransactionActionElement() {
+ return document.getElementById("startTransactionButton");
+}
+
+function getProductSalesReportActionElement() {
+ return document.getElementById("productSalesReportButton");
+}
+
+function getCashierSalesReportActionElement() {
+ return document.getElementById("cashierSalesReportButton");
+}
+
+// End getters and setters
diff --git a/src/main/resources/static/scripts/signIn.js b/src/main/resources/static/scripts/signIn.js
new file mode 100644
index 00000000..36aafe03
--- /dev/null
+++ b/src/main/resources/static/scripts/signIn.js
@@ -0,0 +1,39 @@
+document.addEventListener("DOMContentLoaded", function(event) {
+ const employeeIdEditElement = getEmployeeId();
+ employeeIdEditElement.focus();
+ employeeIdEditElement.select();
+);
+
+//Get elements for the Employee Id and Password
+function getEmployeeId() {
+ return document.getElementById("employeeId");
+}
+
+function getPassword() {
+ return document.getElementById("password");
+}
+
+//Validates the Id is not blank and is a number; Validates that Password is not null
+function validateForm() {
+ const employeeIdEditElement = getEmployeeId();
+ if(isNaN(Number(employeeIdEditElement.value)) || (Number(employeeIdEditElement.value) <= 0))
+ {
+ displayError("Employee Id must be a positive numerical value.");
+
+ employeeIdEditElement.focus();
+ employeeIdEditElement.select();
+ return false;
+ }
+
+ const passwordEditElement = getPassword();
+ if ((passwordEditElement.value == null) || (passwordEditElement.value.trim() === ""))
+ {
+ displayError("Password must be valid and cannot be blank.");
+
+ passwordEditElement.focus();
+ passwordEditElement.select();
+ return false;
+
+ }
+ return true;
+}
diff --git a/src/main/resources/templates/mainMenu.html b/src/main/resources/templates/mainMenu.html
new file mode 100644
index 00000000..67e4f2c0
--- /dev/null
+++ b/src/main/resources/templates/mainMenu.html
@@ -0,0 +1,78 @@
+
+
+
+ Register - Main Menu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/signIn.html b/src/main/resources/templates/signIn.html
new file mode 100644
index 00000000..13799e48
--- /dev/null
+++ b/src/main/resources/templates/signIn.html
@@ -0,0 +1,42 @@
+
+
+
+ Register - Sign In
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+